@cmtlyt/lingshu-toolkit 0.3.0 → 0.5.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.
- package/dist/247.js +66 -0
- package/dist/707.js +8 -2
- package/dist/react/index.js +2 -4
- package/dist/react/use-mount/index.js +1 -1
- package/dist/react/use-ref-state/index.js +1 -3
- package/dist/shared/allx/__test__/allsettled.test.d.ts +1 -0
- package/dist/shared/allx/__test__/basic.test.d.ts +1 -0
- package/dist/shared/allx/__test__/circular-dependency.test.d.ts +1 -0
- package/dist/shared/allx/__test__/dependency.test.d.ts +1 -0
- package/dist/shared/allx/__test__/edge-cases.test.d.ts +1 -0
- package/dist/shared/allx/__test__/error-handling.test.d.ts +1 -0
- package/dist/shared/allx/__test__/execution-order.test.d.ts +1 -0
- package/dist/shared/allx/__test__/falsy-values.test.d.ts +1 -0
- package/dist/shared/allx/__test__/performance.test.d.ts +1 -0
- package/dist/shared/allx/__test__/type-checking.test.d.ts +1 -0
- package/dist/shared/allx/__test__/use-cases.test.d.ts +1 -0
- package/dist/shared/allx/index.d.ts +13 -0
- package/dist/shared/allx/index.js +44 -0
- package/dist/shared/allx/types.d.ts +13 -0
- package/dist/shared/allx/types.js +0 -0
- package/dist/shared/allx/utils.d.ts +9 -0
- package/dist/shared/allx/utils.js +94 -0
- package/dist/shared/animation/index.d.ts +2 -2
- package/dist/shared/animation/index.js +19 -13
- package/dist/shared/animation/types.d.ts +6 -4
- package/dist/shared/animation/utils.d.ts +3 -5
- package/dist/shared/animation/utils.js +2 -6
- package/dist/shared/api-controller/__test__/index.browser.test.d.ts +1 -0
- package/dist/shared/api-controller/__test__/index.node.test.d.ts +1 -0
- package/dist/shared/api-controller/create-api.d.ts +26 -0
- package/dist/shared/api-controller/create-api.js +79 -0
- package/dist/shared/api-controller/index.d.ts +3 -0
- package/dist/shared/api-controller/index.js +3 -0
- package/dist/shared/api-controller/request.d.ts +7 -0
- package/dist/shared/api-controller/request.js +66 -0
- package/dist/shared/api-controller/types.d.ts +141 -0
- package/dist/shared/api-controller/types.js +0 -0
- package/dist/shared/api-controller/utils.d.ts +22 -0
- package/dist/shared/api-controller/utils.js +96 -0
- package/dist/shared/data-handler/tools.js +1 -3
- package/dist/shared/data-mixed-manager/__test__/basic.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/build-options.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/constructor-options.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/data-management.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/edge-cases.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/events.browser.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/events.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/fixed-slots.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/__test__/insert-mode.test.d.ts +1 -0
- package/dist/shared/data-mixed-manager/constants.d.ts +8 -0
- package/dist/shared/data-mixed-manager/constants.js +9 -0
- package/dist/shared/data-mixed-manager/index.d.ts +128 -0
- package/dist/shared/data-mixed-manager/index.js +226 -0
- package/dist/shared/data-mixed-manager/types.d.ts +90 -0
- package/dist/shared/data-mixed-manager/types.js +0 -0
- package/dist/shared/index.d.ts +5 -0
- package/dist/shared/index.js +957 -2
- package/dist/shared/logger/index.d.ts +5 -0
- package/dist/shared/logger/index.js +1 -0
- package/dist/shared/throw-error/index.d.ts +1 -0
- package/dist/shared/throw-error/index.js +5 -2
- package/dist/shared/try-call/index.d.ts +22 -0
- package/dist/shared/try-call/index.js +59 -0
- package/dist/shared/try-call/index.test.d.ts +1 -0
- package/dist/shared/types/base.d.ts +5 -0
- package/dist/shared/types/pack.d.ts +1 -1
- package/dist/shared/utils/__test__/base.test.d.ts +1 -0
- package/dist/shared/utils/__test__/verify.test.d.ts +1 -0
- package/dist/shared/utils/base.d.ts +3 -0
- package/dist/shared/utils/base.js +6 -0
- package/dist/shared/utils/index.d.ts +2 -0
- package/dist/shared/utils/index.js +2 -0
- package/dist/shared/utils/verify.d.ts +53 -0
- package/dist/shared/utils/verify.js +67 -0
- package/package.json +10 -7
- package/dist/607.js +0 -311
package/dist/247.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { dataHandler, logger, $dt, throwError, $t } from "./707.js";
|
|
2
|
+
const validInfo = $dt({
|
|
3
|
+
storageKey: 'validString',
|
|
4
|
+
storageType: $t["enum"]([
|
|
5
|
+
'local',
|
|
6
|
+
'session',
|
|
7
|
+
'memory'
|
|
8
|
+
], 'local'),
|
|
9
|
+
autoSaveInterval: $t.number(0)
|
|
10
|
+
});
|
|
11
|
+
const memoryStorage = {
|
|
12
|
+
data: {},
|
|
13
|
+
getItem (key) {
|
|
14
|
+
return this.data[key];
|
|
15
|
+
},
|
|
16
|
+
setItem (key, value) {
|
|
17
|
+
this.data[key] = value;
|
|
18
|
+
},
|
|
19
|
+
removeItem (key) {
|
|
20
|
+
delete this.data[key];
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function getStorage(storageType) {
|
|
24
|
+
try {
|
|
25
|
+
if ('memory' === storageType) return memoryStorage;
|
|
26
|
+
return 'local' === storageType ? localStorage : sessionStorage;
|
|
27
|
+
} catch {
|
|
28
|
+
logger.warn('createStorage', 'Failed to access localStorage or sessionStorage, using memoryStorage instead.');
|
|
29
|
+
return memoryStorage;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const CLEAR_FLAG = Symbol('cleared');
|
|
33
|
+
function createStorageHandler(storageKey, initialData, options = {}) {
|
|
34
|
+
const { storageKey: validStorageKey, storageType, autoSaveInterval } = dataHandler({
|
|
35
|
+
storageKey,
|
|
36
|
+
...options
|
|
37
|
+
}, validInfo, {
|
|
38
|
+
unwrap: true
|
|
39
|
+
});
|
|
40
|
+
const storage = getStorage(storageType);
|
|
41
|
+
const storageData = storage.getItem(validStorageKey);
|
|
42
|
+
const context = {
|
|
43
|
+
data: storageData ? JSON.parse(storageData) : initialData || {}
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
get (key) {
|
|
47
|
+
if (context.data === CLEAR_FLAG) throwError('createStorageHandler', 'Storage has been cleared.');
|
|
48
|
+
if (null == key) return context.data;
|
|
49
|
+
return context.data[key];
|
|
50
|
+
},
|
|
51
|
+
set (value, key) {
|
|
52
|
+
if (context.data === CLEAR_FLAG) throwError('createStorageHandler', 'Storage has been cleared.');
|
|
53
|
+
if (null == key) context.data = value;
|
|
54
|
+
else context.data[key] = value;
|
|
55
|
+
if (autoSaveInterval > 0) setTimeout(()=>{
|
|
56
|
+
storage.setItem(validStorageKey, JSON.stringify(context.data));
|
|
57
|
+
}, autoSaveInterval);
|
|
58
|
+
else storage.setItem(validStorageKey, JSON.stringify(context.data));
|
|
59
|
+
},
|
|
60
|
+
clear () {
|
|
61
|
+
context.data = CLEAR_FLAG;
|
|
62
|
+
storage.removeItem(validStorageKey);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export { createStorageHandler };
|
package/dist/707.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
+
function createError(fnName, message, ErrorClass = Error) {
|
|
2
|
+
return new ErrorClass(`[@cmtlyt/lingshu-toolkit#${fnName}]: ${message}`);
|
|
3
|
+
}
|
|
1
4
|
function throwError(fnName, message, ErrorClass = Error) {
|
|
2
|
-
throw
|
|
5
|
+
throw createError(fnName, message, ErrorClass);
|
|
3
6
|
}
|
|
4
7
|
function throwType(fnName, message) {
|
|
5
8
|
throwError(fnName, message, TypeError);
|
|
6
9
|
}
|
|
7
10
|
const logger = new Proxy(console, {
|
|
8
11
|
get (target, prop, receiver) {
|
|
12
|
+
if ((globalThis.$$lingshu$$ || {}).disableLogger) return ()=>void 0;
|
|
9
13
|
const oldLog = Reflect.get(target, prop, receiver).bind(console);
|
|
10
14
|
return (fnName, ...args)=>{
|
|
11
15
|
oldLog(`[@cmtlyt/lingshu-toolkit#${fnName}]:`, ...args);
|
|
12
16
|
};
|
|
13
17
|
}
|
|
14
18
|
});
|
|
19
|
+
const noop = ()=>void 0;
|
|
20
|
+
const identity = (_v)=>_v;
|
|
15
21
|
function getType(_v) {
|
|
16
22
|
return Object.prototype.toString.call(_v).slice(8, -1).toLowerCase();
|
|
17
23
|
}
|
|
@@ -133,4 +139,4 @@ function dataHandler(data, handler, options) {
|
|
|
133
139
|
errors: ctx.errors
|
|
134
140
|
};
|
|
135
141
|
}
|
|
136
|
-
export { $dt, $t, dataHandler, defineTransform, logger, throwError, throwType };
|
|
142
|
+
export { $dt, $t, createError, dataHandler, defineTransform, getType, identity, logger, noop, throwError, throwType };
|
package/dist/react/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useEffectEvent, useMemo, useReducer, useRef, useState } from "react";
|
|
2
2
|
import { dataHandler, logger, $dt, $t, throwType } from "../707.js";
|
|
3
|
-
import { createStorageHandler } from "../
|
|
3
|
+
import { createStorageHandler } from "../247.js";
|
|
4
4
|
function useToggle(defualtValue = false, reverseValue) {
|
|
5
5
|
const [state, setState] = useState(defualtValue);
|
|
6
6
|
const toggleRef = useRef([
|
|
@@ -138,9 +138,7 @@ function useMount(callback) {
|
|
|
138
138
|
callbackRef.current();
|
|
139
139
|
}, []);
|
|
140
140
|
}
|
|
141
|
-
|
|
142
|
-
return structuredClone(_v);
|
|
143
|
-
}
|
|
141
|
+
const clone = structuredClone;
|
|
144
142
|
function useRefState(initialState) {
|
|
145
143
|
const stateRef = useRef(initialState);
|
|
146
144
|
const forceUpdate = useForceUpdate();
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { useMemo, useRef } from "react";
|
|
2
2
|
import { useForceUpdate } from "../use-force-update/index.js";
|
|
3
|
-
|
|
4
|
-
return structuredClone(_v);
|
|
5
|
-
}
|
|
3
|
+
const clone = structuredClone;
|
|
6
4
|
function useRefState(initialState) {
|
|
7
5
|
const stateRef = useRef(initialState);
|
|
8
6
|
const forceUpdate = useForceUpdate();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AllxContext, AllxOptions, AllxResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 支持自动依赖优化和完整类型推断的 Promise.all, 执行任务时自动解决依赖关系。
|
|
4
|
+
*
|
|
5
|
+
* @platform web, node, webworker
|
|
6
|
+
* @example
|
|
7
|
+
* const { a, b, c } = await allx({
|
|
8
|
+
* a() { return 1 },
|
|
9
|
+
* async b() { return 'hello' },
|
|
10
|
+
* async c() { return (await this.$.a) + 10 }
|
|
11
|
+
* })
|
|
12
|
+
*/
|
|
13
|
+
export declare function allx<M extends Record<PropertyKey, any>, O extends AllxOptions>(tasks: M & ThisType<AllxContext<M>>, options?: O): Promise<AllxResult<M, O>>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { $dt, $t, dataHandler } from "../data-handler/index.js";
|
|
2
|
+
import { isFunction, isPromiseLike } from "../utils/verify.js";
|
|
3
|
+
import { withResolvers } from "../with-resolvers/index.js";
|
|
4
|
+
import { createDepProxy, getValueFormatFunc } from "./utils.js";
|
|
5
|
+
const validInfo = $dt({
|
|
6
|
+
allSettled: $t.boolean(false)
|
|
7
|
+
});
|
|
8
|
+
async function allx(tasks, options) {
|
|
9
|
+
const validOptions = dataHandler(options || {}, validInfo, {
|
|
10
|
+
unwrap: true
|
|
11
|
+
});
|
|
12
|
+
const { allSettled } = validOptions;
|
|
13
|
+
const results = {};
|
|
14
|
+
const depCtrl = createDepProxy(tasks, results, validOptions);
|
|
15
|
+
const valueFormat = getValueFormatFunc(options);
|
|
16
|
+
const promises = [];
|
|
17
|
+
depCtrl.taskNameSet.forEach(async (taskName)=>{
|
|
18
|
+
const taskFn = tasks[taskName];
|
|
19
|
+
const context = {
|
|
20
|
+
$: depCtrl.createContextFor(taskName)
|
|
21
|
+
};
|
|
22
|
+
const taskResolvers = withResolvers();
|
|
23
|
+
taskResolvers.promise.then((value)=>{
|
|
24
|
+
results[taskName] = valueFormat(value, 'fulfilled');
|
|
25
|
+
depCtrl.resolveDepFor(taskName, value);
|
|
26
|
+
return value;
|
|
27
|
+
}, (error)=>{
|
|
28
|
+
if (allSettled) results[taskName] = valueFormat(error, 'rejected');
|
|
29
|
+
depCtrl.rejectDepFor(taskName, error);
|
|
30
|
+
});
|
|
31
|
+
promises.push(taskResolvers.promise);
|
|
32
|
+
if (isPromiseLike(taskFn)) return void await taskFn.then(taskResolvers.resolve, taskResolvers.reject);
|
|
33
|
+
if (!isFunction(taskFn)) return void taskResolvers.resolve(taskFn);
|
|
34
|
+
try {
|
|
35
|
+
const result = await taskFn.call(context);
|
|
36
|
+
taskResolvers.resolve(result);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
taskResolvers.reject(error);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
if (allSettled) return Promise.allSettled(promises).then(()=>results);
|
|
42
|
+
return Promise.all(promises).then(()=>results);
|
|
43
|
+
}
|
|
44
|
+
export { allx };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnyFunc } from '../types/base';
|
|
2
|
+
export interface AllxOptions {
|
|
3
|
+
allSettled?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export type AllxTaskValue<T> = T extends AnyFunc ? Awaited<ReturnType<T>> : Awaited<T>;
|
|
6
|
+
export interface AllxContext<M extends Record<PropertyKey, AnyFunc>> {
|
|
7
|
+
$: {
|
|
8
|
+
[P in keyof M]: Promise<AllxTaskValue<M[P]>>;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export type AllxResult<M extends Record<PropertyKey, AnyFunc>, O extends AllxOptions = AllxOptions> = {
|
|
12
|
+
[P in keyof M]: O['allSettled'] extends true ? PromiseSettledResult<Awaited<ReturnType<M[P]>>> : AllxTaskValue<M[P]>;
|
|
13
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AnyFunc } from '../types/base';
|
|
2
|
+
import type { AllxOptions } from './types';
|
|
3
|
+
export declare function createDepProxy(tasks: Record<PropertyKey, AnyFunc>, results: Record<PropertyKey, any>, options: Required<AllxOptions>): {
|
|
4
|
+
taskNameSet: Set<PropertyKey>;
|
|
5
|
+
createContextFor: (currentTask: PropertyKey) => {};
|
|
6
|
+
resolveDepFor: (depName: PropertyKey, value: any) => void;
|
|
7
|
+
rejectDepFor: (depName: PropertyKey, error: any) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare function getValueFormatFunc(options?: AllxOptions): (value: any, _type?: PromiseSettledResult<any>["status"]) => any;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { createError } from "../throw-error/index.js";
|
|
2
|
+
import { withResolvers } from "../with-resolvers/index.js";
|
|
3
|
+
function detectCycle(from, to, waitingForGraph) {
|
|
4
|
+
const visited = new Set();
|
|
5
|
+
const queue = [
|
|
6
|
+
to
|
|
7
|
+
];
|
|
8
|
+
let head = 0;
|
|
9
|
+
while(head < queue.length){
|
|
10
|
+
const node = queue[head++];
|
|
11
|
+
if (node === from) return true;
|
|
12
|
+
if (visited.has(node)) continue;
|
|
13
|
+
visited.add(node);
|
|
14
|
+
const deps = waitingForGraph.get(node);
|
|
15
|
+
if (deps) {
|
|
16
|
+
const depsIter = deps.values();
|
|
17
|
+
for(let dep = depsIter.next(); !dep.done; dep = depsIter.next())queue.push(dep.value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
function getCached(results, depName, allSettled) {
|
|
23
|
+
if (Reflect.getOwnPropertyDescriptor(results, depName)) {
|
|
24
|
+
const cached = results[depName];
|
|
25
|
+
if (allSettled) return 'rejected' === cached.status ? Promise.reject(cached.reason) : Promise.resolve(cached.value);
|
|
26
|
+
return Promise.resolve(cached);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function createDepResolver(waitingFor, resolverMap, currentTask, depName) {
|
|
30
|
+
waitingFor.set(currentTask, (waitingFor.get(currentTask) || new Set()).add(depName));
|
|
31
|
+
const depResolvers = resolverMap.get(depName) || withResolvers();
|
|
32
|
+
resolverMap.set(depName, depResolvers);
|
|
33
|
+
return depResolvers.promise.then((value)=>{
|
|
34
|
+
waitingFor.get(currentTask)?.delete(depName);
|
|
35
|
+
return value;
|
|
36
|
+
}, (error)=>{
|
|
37
|
+
waitingFor.get(currentTask)?.delete(depName);
|
|
38
|
+
throw error;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function cleanWaitingForGraph(waitingForGraph, depName) {
|
|
42
|
+
waitingForGraph.forEach((deps, task)=>{
|
|
43
|
+
deps.delete(depName);
|
|
44
|
+
if (0 === deps.size) waitingForGraph.delete(task);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function createDepProxy(tasks, results, options) {
|
|
48
|
+
const resolverMap = new Map();
|
|
49
|
+
const taskNameSet = new Set(Reflect.ownKeys(tasks));
|
|
50
|
+
const waitingForGraph = new Map();
|
|
51
|
+
const resolveDepFor = (depName, value)=>{
|
|
52
|
+
const resolver = resolverMap.get(depName);
|
|
53
|
+
if (resolver) {
|
|
54
|
+
resolver.resolve(value);
|
|
55
|
+
resolverMap.delete(depName);
|
|
56
|
+
}
|
|
57
|
+
cleanWaitingForGraph(waitingForGraph, depName);
|
|
58
|
+
};
|
|
59
|
+
const rejectDepFor = (depName, error)=>{
|
|
60
|
+
const resolver = resolverMap.get(depName);
|
|
61
|
+
if (resolver) {
|
|
62
|
+
resolver.reject(error);
|
|
63
|
+
resolverMap.delete(depName);
|
|
64
|
+
}
|
|
65
|
+
cleanWaitingForGraph(waitingForGraph, depName);
|
|
66
|
+
};
|
|
67
|
+
const createContextFor = (currentTask)=>new Proxy({}, {
|
|
68
|
+
get (_, depName) {
|
|
69
|
+
if (!taskNameSet.has(depName)) return Promise.reject(createError('allx', `Unknown task "${String(depName)}"`));
|
|
70
|
+
const cached = getCached(results, depName, options.allSettled);
|
|
71
|
+
if (cached) return cached;
|
|
72
|
+
if (detectCycle(currentTask, depName, waitingForGraph)) return Promise.reject(createError('allx', `Circular dependency detected: "${String(currentTask)}" -> "${String(depName)}"`));
|
|
73
|
+
return createDepResolver(waitingForGraph, resolverMap, currentTask, depName);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
taskNameSet,
|
|
78
|
+
createContextFor,
|
|
79
|
+
resolveDepFor,
|
|
80
|
+
rejectDepFor
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function getValueFormatFunc(options) {
|
|
84
|
+
if (!options) return (value, _type = 'fulfilled')=>value;
|
|
85
|
+
if (options.allSettled) return (value, status = 'fulfilled')=>'fulfilled' === status ? {
|
|
86
|
+
status,
|
|
87
|
+
value
|
|
88
|
+
} : {
|
|
89
|
+
status,
|
|
90
|
+
reason: value
|
|
91
|
+
};
|
|
92
|
+
return (value, _type = 'fulfilled')=>value;
|
|
93
|
+
}
|
|
94
|
+
export { createDepProxy, getValueFormatFunc };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { AnimationBaseOptions, AnimationOptions, AnimationResult } from './types';
|
|
2
|
-
export declare function stepAnimation<T>(from: T, to: T, step: number, options?: AnimationBaseOptions): Generator<
|
|
3
|
-
export declare function animation<T>(from: T, to: T, duration: number, options?: AnimationOptions): AnimationResult;
|
|
2
|
+
export declare function stepAnimation<T>(from: T, to: T, step: number, options?: AnimationBaseOptions<T>): Generator<any, void, unknown>;
|
|
3
|
+
export declare function animation<T>(from: T, to: T, duration: number, options?: AnimationOptions<T>): AnimationResult;
|
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import { $dt, $t, dataHandler } from "../data-handler/index.js";
|
|
2
2
|
import { throwError } from "../throw-error/index.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
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
|
-
}
|
|
3
|
+
import { identity, noop } from "../utils/base.js";
|
|
4
|
+
import { createNextTick, createRunningControllerSignal, getNextValueHandler, matchValid } from "./utils.js";
|
|
14
5
|
const validInfo = $dt({
|
|
15
6
|
autoStart: $t.boolean(true),
|
|
16
7
|
easing: $t["function"](()=>identity),
|
|
@@ -19,17 +10,32 @@ const validInfo = $dt({
|
|
|
19
10
|
onClear: $t["function"](()=>noop),
|
|
20
11
|
onUpdate: $t["function"](()=>noop),
|
|
21
12
|
onComplete: $t["function"](()=>noop),
|
|
13
|
+
formatterValue: $t["function"](()=>identity),
|
|
22
14
|
formatter: $t["function"](()=>identity),
|
|
23
15
|
parser: $t["function"](()=>identity)
|
|
24
16
|
});
|
|
17
|
+
function* stepAnimation(from, to, step, options = {}) {
|
|
18
|
+
if (!Number.isInteger(step) || step <= 0) throwError('stepAnimation', 'step must be a positive integer', RangeError);
|
|
19
|
+
const validOptions = dataHandler(options, validInfo, {
|
|
20
|
+
unwrap: true
|
|
21
|
+
});
|
|
22
|
+
const { parser: valueParser = identity, formatterValue = identity, formatter } = validOptions;
|
|
23
|
+
const [validFrom, validTo] = matchValid(from, to, valueParser);
|
|
24
|
+
const getNextValue = getNextValueHandler(validFrom, validTo, formatterValue);
|
|
25
|
+
for(let i = 0; i <= step; i++){
|
|
26
|
+
const value = formatter(getNextValue(i / step));
|
|
27
|
+
yield value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
25
30
|
function animation(from, to, duration, options = {}) {
|
|
26
31
|
if (duration <= 0 || !Number.isInteger(duration)) throwError('animation', 'duration must be a positive integer', RangeError);
|
|
27
32
|
const validOptions = dataHandler(options, validInfo, {
|
|
28
33
|
unwrap: true
|
|
29
34
|
});
|
|
30
35
|
const [validFrom, validTo] = matchValid(from, to, validOptions.parser);
|
|
31
|
-
const { autoStart, easing, onComplete, onUpdate, formatter
|
|
32
|
-
const
|
|
36
|
+
const { autoStart, easing, onComplete, onUpdate, formatterValue, formatter } = validOptions;
|
|
37
|
+
const _getNextValue = getNextValueHandler(validFrom, validTo, formatterValue);
|
|
38
|
+
const getNextValue = (...args)=>formatter(_getNextValue(...args));
|
|
33
39
|
let startTime = 0;
|
|
34
40
|
let hasStarted = false;
|
|
35
41
|
const rcSignal = createRunningControllerSignal(()=>{
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export
|
|
1
|
+
export type FormatterValue = (value: number) => any;
|
|
2
|
+
export type Formatter<T> = (value: T) => any;
|
|
3
|
+
export interface AnimationBaseOptions<T> {
|
|
3
4
|
parser?: (value: any) => number;
|
|
4
|
-
|
|
5
|
+
formatterValue?: FormatterValue;
|
|
6
|
+
formatter?: Formatter<T>;
|
|
5
7
|
}
|
|
6
|
-
export interface AnimationOptions extends AnimationBaseOptions {
|
|
8
|
+
export interface AnimationOptions<T> extends AnimationBaseOptions<T> {
|
|
7
9
|
autoStart?: boolean;
|
|
8
10
|
easing?: (time: number) => number;
|
|
9
11
|
onStart?: () => void;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { type Resolver } from '../with-resolvers';
|
|
2
|
-
import type { AnimationOptions,
|
|
3
|
-
export declare
|
|
4
|
-
export declare const identity: <T>(_v: T) => T;
|
|
5
|
-
export declare function getNextValueHandler(from: any, to: any, valueFormatter: Formatter): (progress: number) => any;
|
|
2
|
+
import type { AnimationOptions, FormatterValue } from './types';
|
|
3
|
+
export declare function getNextValueHandler<T>(from: T, to: T, valueFormatter: FormatterValue): (progress: number) => any;
|
|
6
4
|
export declare function matchValid(from: any, to: any, valueParser: (value: any) => number): number[] | unknown[][] | [Record<PropertyKey, any>, Record<PropertyKey, any>];
|
|
7
5
|
export declare function createNextTick(resolvers: Resolver<any>, rcSignal: RCSignal): (callback: (...args: any[]) => void) => boolean;
|
|
8
6
|
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
|
|
7
|
+
export declare function createRunningControllerSignal(startFn: () => void, options: Required<AnimationOptions<any>>): {
|
|
10
8
|
stopSignal: boolean;
|
|
11
9
|
resolvers: Resolver<boolean>;
|
|
12
10
|
stop: () => void;
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { throwType } from "../throw-error/index.js";
|
|
2
|
+
import { getType } from "../utils/base.js";
|
|
2
3
|
import { withResolvers } from "../with-resolvers/index.js";
|
|
3
|
-
const noop = ()=>void 0;
|
|
4
|
-
const identity = (_v)=>_v;
|
|
5
|
-
function getType(_v) {
|
|
6
|
-
return Object.prototype.toString.call(_v).slice(8, -1).toLowerCase();
|
|
7
|
-
}
|
|
8
4
|
function getNextValueHandler(from, to, valueFormatter) {
|
|
9
5
|
const type = getType(from);
|
|
10
6
|
const context = {
|
|
@@ -135,4 +131,4 @@ function createRunningControllerSignal(startFn, options) {
|
|
|
135
131
|
};
|
|
136
132
|
return ctrl;
|
|
137
133
|
}
|
|
138
|
-
export { createNextTick, createRunningControllerSignal, getNextValueHandler,
|
|
134
|
+
export { createNextTick, createRunningControllerSignal, getNextValueHandler, matchValid, tryRun };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { APIConfig, APIMap, APIMapTransformMethods, APITransformMethod, DefaultAPIConfig, DefineAPIConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 通过 API config map 创建请求对象
|
|
4
|
+
*
|
|
5
|
+
* @param apiMap API config map
|
|
6
|
+
* @param defaultConfig 默认配置
|
|
7
|
+
*/
|
|
8
|
+
export declare function createApiWithMap<M extends APIMap, D extends DefaultAPIConfig = DefaultAPIConfig>(apiMap: M, defaultConfig?: D): APIMapTransformMethods<M, D>;
|
|
9
|
+
/**
|
|
10
|
+
* 通过 API config 创建一个请求方法
|
|
11
|
+
*
|
|
12
|
+
* @param api API config
|
|
13
|
+
* @param defaultConfig 默认配置
|
|
14
|
+
* @param custom 是否为自定义请求
|
|
15
|
+
*/
|
|
16
|
+
export declare function createApi<A extends APIConfig, D extends DefaultAPIConfig = DefaultAPIConfig, C extends boolean = false>(api: A, defaultConfig?: D, custom?: C): APITransformMethod<A, D, C>;
|
|
17
|
+
/**
|
|
18
|
+
* 定义 API, ts 支持, 获取更好的类型声明
|
|
19
|
+
* @warn 不应该被复用, 如果希望复用的话请使用 apiInstance.$
|
|
20
|
+
*/
|
|
21
|
+
export declare function defineApi<U extends string, A extends DefineAPIConfig<U>>(_api: A): A;
|
|
22
|
+
/**
|
|
23
|
+
* 定义 API map, ts 支持, 获取更好的类型声明
|
|
24
|
+
* @warn 不应该被复用, 如果希望复用的话请使用 apiInstance.$
|
|
25
|
+
*/
|
|
26
|
+
export declare function defineApiMap<U extends string, A extends APIMap<U>>(_apiMap: A): A;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { logger } from "../logger/index.js";
|
|
2
|
+
import { throwType } from "../throw-error/index.js";
|
|
3
|
+
import { isString, isTrue } from "../utils/verify.js";
|
|
4
|
+
import { request } from "./request.js";
|
|
5
|
+
import { apiNamesCheck, createInstance, getInstanceMemberOrApi, instanceMemberGetter, isAbsUrl } from "./utils.js";
|
|
6
|
+
const FROM_DEFINE = Symbol('fromDefine');
|
|
7
|
+
function createApiWithMap(apiMap, defaultConfig) {
|
|
8
|
+
const fromDefine = apiMap[FROM_DEFINE];
|
|
9
|
+
delete apiMap[FROM_DEFINE];
|
|
10
|
+
const proxyCache = Object.create(null);
|
|
11
|
+
const realDefaultConfig = defaultConfig || {};
|
|
12
|
+
if (!isTrue(fromDefine)) apiNamesCheck(apiMap);
|
|
13
|
+
const instanceObj = createInstance(apiMap, realDefaultConfig, defaultConfig);
|
|
14
|
+
const proxy = new Proxy(apiMap, {
|
|
15
|
+
get (target, prop, receiver) {
|
|
16
|
+
if (Reflect.getOwnPropertyDescriptor(proxyCache, prop)) return proxyCache[prop];
|
|
17
|
+
const { instanceMember, api, isCustom = false } = getInstanceMemberOrApi(target, prop, receiver, instanceObj) || {};
|
|
18
|
+
if (instanceMember) return instanceMember;
|
|
19
|
+
if (!api) return;
|
|
20
|
+
let result = null;
|
|
21
|
+
result = isString(api.url) ? createApi({
|
|
22
|
+
...api,
|
|
23
|
+
[FROM_DEFINE]: fromDefine
|
|
24
|
+
}, realDefaultConfig, isCustom) : createApiWithMap({
|
|
25
|
+
...api,
|
|
26
|
+
[FROM_DEFINE]: fromDefine
|
|
27
|
+
}, realDefaultConfig);
|
|
28
|
+
proxyCache[prop] = result;
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return proxy;
|
|
33
|
+
}
|
|
34
|
+
function createApi(api, defaultConfig, custom) {
|
|
35
|
+
const fromDefine = api[FROM_DEFINE];
|
|
36
|
+
delete api[FROM_DEFINE];
|
|
37
|
+
const realDefaultConfig = defaultConfig || {};
|
|
38
|
+
if (!isString(api.url)) throwType('apiController.createApi', '入参应为 APIConfig 对象');
|
|
39
|
+
if (api.url.includes('/:')) {
|
|
40
|
+
if (!isTrue(fromDefine)) logger.warn('apiController.createApi', 'url 中存在 params 参数, 使用 defineApi 或 defineApiMap 定义 API 或 API map 来获取更好的类型提示');
|
|
41
|
+
if (!isTrue(custom)) throwType('apiController.createApi', 'url 中存在 params 参数, 不支持普通请求, 转为自定义请求');
|
|
42
|
+
}
|
|
43
|
+
let handler = null;
|
|
44
|
+
handler = isTrue(custom) ? (data, config)=>request({
|
|
45
|
+
...realDefaultConfig,
|
|
46
|
+
...api,
|
|
47
|
+
...config,
|
|
48
|
+
url: api.url,
|
|
49
|
+
data,
|
|
50
|
+
oriUrl: api.url
|
|
51
|
+
}) : (data)=>request({
|
|
52
|
+
...realDefaultConfig,
|
|
53
|
+
...api,
|
|
54
|
+
data,
|
|
55
|
+
oriUrl: api.url
|
|
56
|
+
});
|
|
57
|
+
const instanceObj = createInstance(api, realDefaultConfig, defaultConfig);
|
|
58
|
+
if (!isAbsUrl(api.url)) instanceObj.$updateBaseUrl(realDefaultConfig.baseUrl);
|
|
59
|
+
return new Proxy(handler, {
|
|
60
|
+
get (target, prop, receiver) {
|
|
61
|
+
if (Reflect.getOwnPropertyDescriptor(instanceObj, prop)) return instanceMemberGetter(prop, instanceObj);
|
|
62
|
+
return Reflect.get(target, prop, receiver);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function defineApi(_api) {
|
|
67
|
+
return {
|
|
68
|
+
..._api,
|
|
69
|
+
[FROM_DEFINE]: true
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function defineApiMap(_apiMap) {
|
|
73
|
+
apiNamesCheck(_apiMap);
|
|
74
|
+
return {
|
|
75
|
+
..._apiMap,
|
|
76
|
+
[FROM_DEFINE]: true
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export { createApi, createApiWithMap, defineApi, defineApiMap };
|