@composy/store-core 0.0.1 → 0.0.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/CHANGELOG.md +64 -3
- package/README.md +196 -172
- package/dist/index.js +1331 -1115
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +578 -417
- package/dist/index.min.js.map +1 -1
- package/es/.dts-output-manifest.json +1 -0
- package/es/.dts.tsbuildinfo +1 -0
- package/es/core/async-action.d.ts +1 -71
- package/es/core/async-action.js +83 -35
- package/es/core/async-action.js.map +1 -1
- package/es/core/base-store.d.ts +27 -62
- package/es/core/base-store.js +174 -74
- package/es/core/base-store.js.map +1 -1
- package/es/core/batch-manager.d.ts +0 -1
- package/es/core/batch-manager.js +15 -2
- package/es/core/batch-manager.js.map +1 -1
- package/es/core/create-store.d.ts +3 -3
- package/es/core/create-store.js +3 -3
- package/es/core/create-store.js.map +1 -1
- package/es/core/event-bus.d.ts +0 -1
- package/es/core/event-bus.js +1 -1
- package/es/core/event-bus.js.map +1 -1
- package/es/core/index.d.ts +1 -2
- package/es/core/index.js +2 -2
- package/es/core/pub-sub.d.ts +0 -1
- package/es/core/pub-sub.js +1 -1
- package/es/core/pub-sub.js.map +1 -1
- package/es/engine/index.d.ts +0 -1
- package/es/engine/index.js +1 -1
- package/es/engine/plugin.d.ts +0 -1
- package/es/engine/plugin.js +11 -2
- package/es/engine/plugin.js.map +1 -1
- package/es/engine/types.d.ts +0 -1
- package/es/engine/types.js +1 -1
- package/es/errors/index.d.ts +0 -1
- package/es/errors/index.js +17 -1
- package/es/errors/index.js.map +1 -1
- package/es/index.d.ts +3 -4
- package/es/index.js +8 -8
- package/es/index.js.map +1 -1
- package/es/middleware/index.d.ts +3 -4
- package/es/middleware/index.js +2 -2
- package/es/middleware/logger.d.ts +0 -1
- package/es/middleware/logger.js +2 -2
- package/es/middleware/logger.js.map +1 -1
- package/es/middleware/middleware-manager.d.ts +0 -1
- package/es/middleware/middleware-manager.js +5 -2
- package/es/middleware/middleware-manager.js.map +1 -1
- package/es/middleware/persist.d.ts +0 -1
- package/es/middleware/persist.js +3 -3
- package/es/middleware/persist.js.map +1 -1
- package/es/middleware/time-travel.d.ts +0 -1
- package/es/middleware/time-travel.js +1 -1
- package/es/middleware/time-travel.js.map +1 -1
- package/es/middleware/validation.d.ts +0 -1
- package/es/middleware/validation.js +2 -2
- package/es/middleware/validation.js.map +1 -1
- package/es/plugins/define-plugin.d.ts +1 -2
- package/es/plugins/define-plugin.js +2 -2
- package/es/plugins/define-plugin.js.map +1 -1
- package/es/plugins/index.d.ts +0 -1
- package/es/plugins/index.js +2 -2
- package/es/plugins/plugin-manager.d.ts +1 -31
- package/es/plugins/plugin-manager.js +58 -27
- package/es/plugins/plugin-manager.js.map +1 -1
- package/es/types/action.d.ts +2 -0
- package/es/types/action.js +10 -0
- package/es/types/batch.d.ts +2 -0
- package/es/types/batch.js +10 -0
- package/es/types/event.d.ts +2 -0
- package/es/types/event.js +10 -0
- package/es/types/index.d.ts +2 -3
- package/es/types/index.js +1 -1
- package/es/types/middleware.d.ts +10 -2
- package/es/types/middleware.js +1 -1
- package/es/types/mutation.d.ts +2 -0
- package/es/types/mutation.js +10 -0
- package/es/types/plugin.d.ts +4 -1
- package/es/types/plugin.js +1 -1
- package/es/types/state.d.ts +2 -0
- package/es/types/state.js +10 -0
- package/es/types/store.d.ts +19 -1
- package/es/types/store.js +1 -1
- package/es/types/subscription.d.ts +7 -2
- package/es/types/subscription.js +1 -1
- package/es/types/time-travel.d.ts +2 -0
- package/es/types/time-travel.js +10 -0
- package/es/types/utility.d.ts +3 -4
- package/es/types/utility.js +1 -1
- package/es/utils/debounce-throttle.d.ts +0 -1
- package/es/utils/debounce-throttle.js +1 -1
- package/es/utils/debounce-throttle.js.map +1 -1
- package/es/utils/deep-clone.d.ts +0 -1
- package/es/utils/deep-clone.js +1 -1
- package/es/utils/deep-clone.js.map +1 -1
- package/es/utils/index.d.ts +4 -5
- package/es/utils/index.js +1 -1
- package/es/utils/selector.d.ts +0 -1
- package/es/utils/selector.js +1 -1
- package/es/utils/selector.js.map +1 -1
- package/esm/core/async-action.js +83 -35
- package/esm/core/async-action.js.map +1 -1
- package/esm/core/base-store.js +174 -74
- package/esm/core/base-store.js.map +1 -1
- package/esm/core/batch-manager.js +15 -2
- package/esm/core/batch-manager.js.map +1 -1
- package/esm/core/create-store.js +3 -3
- package/esm/core/create-store.js.map +1 -1
- package/esm/core/event-bus.js +1 -1
- package/esm/core/event-bus.js.map +1 -1
- package/esm/core/index.js +2 -2
- package/esm/core/pub-sub.js +1 -1
- package/esm/core/pub-sub.js.map +1 -1
- package/esm/engine/index.js +1 -1
- package/esm/engine/plugin.js +11 -2
- package/esm/engine/plugin.js.map +1 -1
- package/esm/errors/index.js +17 -1
- package/esm/errors/index.js.map +1 -1
- package/esm/index.js +8 -8
- package/esm/index.js.map +1 -1
- package/esm/middleware/logger.js +2 -2
- package/esm/middleware/logger.js.map +1 -1
- package/esm/middleware/middleware-manager.js +5 -2
- package/esm/middleware/middleware-manager.js.map +1 -1
- package/esm/middleware/persist.js +3 -3
- package/esm/middleware/persist.js.map +1 -1
- package/esm/middleware/time-travel.js +1 -1
- package/esm/middleware/time-travel.js.map +1 -1
- package/esm/middleware/validation.js +2 -2
- package/esm/middleware/validation.js.map +1 -1
- package/esm/plugins/define-plugin.js +2 -2
- package/esm/plugins/define-plugin.js.map +1 -1
- package/esm/plugins/plugin-manager.js +58 -27
- package/esm/plugins/plugin-manager.js.map +1 -1
- package/esm/utils/debounce-throttle.js +1 -1
- package/esm/utils/debounce-throttle.js.map +1 -1
- package/esm/utils/deep-clone.js +1 -1
- package/esm/utils/deep-clone.js.map +1 -1
- package/esm/utils/selector.js +1 -1
- package/esm/utils/selector.js.map +1 -1
- package/lib/core/async-action.cjs +83 -35
- package/lib/core/async-action.cjs.map +1 -1
- package/lib/core/async-action.d.cts +25 -0
- package/lib/core/base-store.cjs +174 -74
- package/lib/core/base-store.cjs.map +1 -1
- package/lib/core/base-store.d.cts +50 -0
- package/lib/core/batch-manager.cjs +15 -2
- package/lib/core/batch-manager.cjs.map +1 -1
- package/{esm/core/batch-manager.d.ts → lib/core/batch-manager.d.cts} +0 -1
- package/lib/core/create-store.cjs +3 -3
- package/lib/core/create-store.cjs.map +1 -1
- package/lib/core/{create-store.d.ts → create-store.d.cts} +3 -3
- package/lib/core/event-bus.cjs +1 -1
- package/lib/core/event-bus.cjs.map +1 -1
- package/lib/core/{event-bus.d.ts → event-bus.d.cts} +0 -1
- package/lib/core/index.cjs +2 -2
- package/{esm/core/index.d.ts → lib/core/index.d.cts} +1 -2
- package/lib/core/pub-sub.cjs +1 -1
- package/lib/core/pub-sub.cjs.map +1 -1
- package/lib/core/{pub-sub.d.ts → pub-sub.d.cts} +0 -1
- package/lib/engine/index.cjs +1 -1
- package/{esm/engine/index.d.ts → lib/engine/index.d.cts} +0 -1
- package/lib/engine/plugin.cjs +11 -2
- package/lib/engine/plugin.cjs.map +1 -1
- package/{esm/engine/plugin.d.ts → lib/engine/plugin.d.cts} +0 -1
- package/lib/engine/types.cjs +1 -1
- package/lib/engine/{types.d.ts → types.d.cts} +0 -1
- package/lib/errors/index.cjs +17 -1
- package/lib/errors/index.cjs.map +1 -1
- package/lib/errors/{index.d.ts → index.d.cts} +0 -1
- package/lib/index.cjs +8 -8
- package/lib/index.cjs.map +1 -1
- package/lib/{index.d.ts → index.d.cts} +3 -4
- package/lib/middleware/index.cjs +2 -2
- package/lib/middleware/{index.d.ts → index.d.cts} +3 -4
- package/lib/middleware/logger.cjs +2 -2
- package/lib/middleware/logger.cjs.map +1 -1
- package/lib/middleware/{logger.d.ts → logger.d.cts} +0 -1
- package/lib/middleware/middleware-manager.cjs +5 -2
- package/lib/middleware/middleware-manager.cjs.map +1 -1
- package/lib/middleware/{middleware-manager.d.ts → middleware-manager.d.cts} +0 -1
- package/lib/middleware/persist.cjs +3 -3
- package/lib/middleware/persist.cjs.map +1 -1
- package/{esm/middleware/persist.d.ts → lib/middleware/persist.d.cts} +0 -1
- package/lib/middleware/time-travel.cjs +1 -1
- package/lib/middleware/time-travel.cjs.map +1 -1
- package/{esm/middleware/time-travel.d.ts → lib/middleware/time-travel.d.cts} +0 -1
- package/lib/middleware/validation.cjs +2 -2
- package/lib/middleware/validation.cjs.map +1 -1
- package/{esm/middleware/validation.d.ts → lib/middleware/validation.d.cts} +0 -1
- package/lib/plugins/define-plugin.cjs +2 -2
- package/lib/plugins/define-plugin.cjs.map +1 -1
- package/{esm/plugins/define-plugin.d.ts → lib/plugins/define-plugin.d.cts} +1 -2
- package/lib/plugins/index.cjs +2 -2
- package/{esm/plugins/index.d.ts → lib/plugins/index.d.cts} +0 -1
- package/lib/plugins/plugin-manager.cjs +58 -27
- package/lib/plugins/plugin-manager.cjs.map +1 -1
- package/lib/plugins/plugin-manager.d.cts +5 -0
- package/lib/types/action.cjs +12 -0
- package/lib/types/action.d.cts +2 -0
- package/lib/types/batch.cjs +12 -0
- package/lib/types/batch.d.cts +2 -0
- package/lib/types/event.cjs +12 -0
- package/lib/types/event.d.cts +2 -0
- package/lib/types/index.cjs +1 -1
- package/{esm/types/index.d.ts → lib/types/index.d.cts} +2 -3
- package/lib/types/middleware.cjs +1 -1
- package/lib/types/{middleware.d.ts → middleware.d.cts} +10 -2
- package/lib/types/mutation.cjs +12 -0
- package/lib/types/mutation.d.cts +2 -0
- package/lib/types/plugin.cjs +1 -1
- package/lib/types/{plugin.d.ts → plugin.d.cts} +4 -1
- package/lib/types/state.cjs +12 -0
- package/lib/types/state.d.cts +2 -0
- package/lib/types/store.cjs +1 -1
- package/lib/types/{store.d.ts → store.d.cts} +19 -1
- package/lib/types/subscription.cjs +1 -1
- package/lib/types/{subscription.d.ts → subscription.d.cts} +7 -2
- package/lib/types/time-travel.cjs +12 -0
- package/lib/types/time-travel.d.cts +2 -0
- package/lib/types/utility.cjs +1 -1
- package/lib/types/{utility.d.ts → utility.d.cts} +3 -4
- package/lib/utils/debounce-throttle.cjs +1 -1
- package/lib/utils/debounce-throttle.cjs.map +1 -1
- package/{esm/utils/debounce-throttle.d.ts → lib/utils/debounce-throttle.d.cts} +0 -1
- package/lib/utils/deep-clone.cjs +1 -1
- package/lib/utils/deep-clone.cjs.map +1 -1
- package/lib/utils/{deep-clone.d.ts → deep-clone.d.cts} +0 -1
- package/lib/utils/index.cjs +1 -1
- package/lib/utils/{index.d.ts → index.d.cts} +4 -5
- package/lib/utils/selector.cjs +1 -1
- package/lib/utils/selector.cjs.map +1 -1
- package/lib/utils/{selector.d.ts → selector.d.cts} +0 -1
- package/package.json +14 -11
- package/es/core/async-action.d.ts.map +0 -1
- package/es/core/base-store.d.ts.map +0 -1
- package/es/core/batch-manager.d.ts.map +0 -1
- package/es/core/create-store.d.ts.map +0 -1
- package/es/core/event-bus.d.ts.map +0 -1
- package/es/core/index.d.ts.map +0 -1
- package/es/core/pub-sub.d.ts.map +0 -1
- package/es/engine/index.d.ts.map +0 -1
- package/es/engine/plugin.d.ts.map +0 -1
- package/es/engine/types.d.ts.map +0 -1
- package/es/errors/index.d.ts.map +0 -1
- package/es/index.d.ts.map +0 -1
- package/es/middleware/index.d.ts.map +0 -1
- package/es/middleware/logger.d.ts.map +0 -1
- package/es/middleware/middleware-manager.d.ts.map +0 -1
- package/es/middleware/persist.d.ts.map +0 -1
- package/es/middleware/time-travel.d.ts.map +0 -1
- package/es/middleware/validation.d.ts.map +0 -1
- package/es/plugins/define-plugin.d.ts.map +0 -1
- package/es/plugins/index.d.ts.map +0 -1
- package/es/plugins/plugin-manager.d.ts.map +0 -1
- package/es/types/index.d.ts.map +0 -1
- package/es/types/middleware.d.ts.map +0 -1
- package/es/types/plugin.d.ts.map +0 -1
- package/es/types/store.d.ts.map +0 -1
- package/es/types/subscription.d.ts.map +0 -1
- package/es/types/utility.d.ts.map +0 -1
- package/es/utils/debounce-throttle.d.ts.map +0 -1
- package/es/utils/deep-clone.d.ts.map +0 -1
- package/es/utils/index.d.ts.map +0 -1
- package/es/utils/selector.d.ts.map +0 -1
- package/esm/core/async-action.d.ts +0 -95
- package/esm/core/base-store.d.ts +0 -85
- package/esm/core/create-store.d.ts +0 -66
- package/esm/core/event-bus.d.ts +0 -34
- package/esm/core/pub-sub.d.ts +0 -41
- package/esm/engine/types.d.ts +0 -81
- package/esm/errors/index.d.ts +0 -208
- package/esm/index.d.ts +0 -27
- package/esm/middleware/index.d.ts +0 -13
- package/esm/middleware/logger.d.ts +0 -67
- package/esm/middleware/middleware-manager.d.ts +0 -40
- package/esm/plugins/plugin-manager.d.ts +0 -35
- package/esm/types/middleware.d.ts +0 -172
- package/esm/types/plugin.d.ts +0 -136
- package/esm/types/store.d.ts +0 -198
- package/esm/types/subscription.d.ts +0 -158
- package/esm/types/utility.d.ts +0 -312
- package/esm/utils/deep-clone.d.ts +0 -143
- package/esm/utils/index.d.ts +0 -13
- package/esm/utils/selector.d.ts +0 -213
- package/lib/core/async-action.d.ts +0 -95
- package/lib/core/base-store.d.ts +0 -85
- package/lib/core/batch-manager.d.ts +0 -46
- package/lib/core/index.d.ts +0 -14
- package/lib/engine/index.d.ts +0 -10
- package/lib/engine/plugin.d.ts +0 -20
- package/lib/middleware/persist.d.ts +0 -34
- package/lib/middleware/time-travel.d.ts +0 -30
- package/lib/middleware/validation.d.ts +0 -100
- package/lib/plugins/define-plugin.d.ts +0 -74
- package/lib/plugins/index.d.ts +0 -8
- package/lib/plugins/plugin-manager.d.ts +0 -35
- package/lib/types/index.d.ts +0 -12
- package/lib/utils/debounce-throttle.d.ts +0 -86
|
@@ -18,7 +18,14 @@ export interface MiddlewareContext<S extends StateTree = StateTree> {
|
|
|
18
18
|
/** 操作数据 */
|
|
19
19
|
payload?: unknown;
|
|
20
20
|
/** 元数据 */
|
|
21
|
-
meta?: Record<string, unknown
|
|
21
|
+
meta?: Record<string, unknown> & {
|
|
22
|
+
/** 由 Store Runtime 注入的提交回调,供 pre-commit 中间件调用 */
|
|
23
|
+
commit?: () => void;
|
|
24
|
+
/** 待提交的候选状态 */
|
|
25
|
+
candidateState?: S;
|
|
26
|
+
/** 提交前的深拷贝状态 */
|
|
27
|
+
previousState?: S;
|
|
28
|
+
};
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
31
|
* 中间件操作类型
|
|
@@ -41,6 +48,8 @@ export interface Middleware<S extends StateTree = StateTree> {
|
|
|
41
48
|
/** 中间件处理函数 */
|
|
42
49
|
handler: MiddlewareFunction<S>;
|
|
43
50
|
}
|
|
51
|
+
/** Public compatibility alias for a Store middleware. */
|
|
52
|
+
export type StoreMiddleware<S extends StateTree = StateTree> = Middleware<S>;
|
|
44
53
|
/**
|
|
45
54
|
* 中间件管理器接口
|
|
46
55
|
*/
|
|
@@ -169,4 +178,3 @@ export interface StateSnapshot {
|
|
|
169
178
|
/** Store ID */
|
|
170
179
|
storeId: StoreId;
|
|
171
180
|
}
|
|
172
|
-
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-10-12 17:23:58 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
12
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
package/lib/types/plugin.cjs
CHANGED
|
@@ -132,5 +132,8 @@ export interface PluginManager {
|
|
|
132
132
|
* 清空所有插件
|
|
133
133
|
*/
|
|
134
134
|
clear: () => void;
|
|
135
|
+
/** Runtime 鐢ㄤ簬灏嗘彃浠剁敓鍛藉懆鏈熻繛鎺ュ埌 Store */
|
|
136
|
+
notifyStoreCreated?: (store: unknown) => void;
|
|
137
|
+
notifyStoreDisposed?: (store: unknown) => void;
|
|
138
|
+
notifyStateChange?: <S extends StateTree>(storeId: StoreId, state: S, oldState: S) => void;
|
|
135
139
|
}
|
|
136
|
-
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-10-12 17:23:58 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
12
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
package/lib/types/store.cjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { MiddlewareManager } from './middleware';
|
|
2
|
+
import type { PluginManager } from './plugin';
|
|
3
|
+
import type { BatchManager } from './subscription';
|
|
1
4
|
/**
|
|
2
5
|
* Store 核心类型定义
|
|
3
6
|
*
|
|
@@ -76,6 +79,10 @@ export interface StoreInstance<Id extends StoreId = StoreId, S extends StateTree
|
|
|
76
79
|
* @param partialState - 部分状态或更新函数
|
|
77
80
|
*/
|
|
78
81
|
$patch: (partialState: Partial<S> | ((state: S) => void)) => void;
|
|
82
|
+
/**
|
|
83
|
+
* 鏁版嫙涓棿浠跺拰楠岃瘉瀹屾垚鍚庡啀鎻愪氦鐘舵€佺殑寮傛琛ュ厖 API
|
|
84
|
+
*/
|
|
85
|
+
$patchAsync: (partialState: Partial<S> | ((state: S) => void)) => Promise<void>;
|
|
79
86
|
/**
|
|
80
87
|
* 订阅状态变化
|
|
81
88
|
* @param callback - 回调函数
|
|
@@ -157,7 +164,19 @@ export interface StoreOptions {
|
|
|
157
164
|
persist?: boolean;
|
|
158
165
|
/** 持久化配置 */
|
|
159
166
|
persistOptions?: PersistOptions;
|
|
167
|
+
/** 鐘舵€佸彉鏇翠腑闂翠欢绠$悊鍣紝鏈彁渚涙椂浣跨敤鍏ㄥ眬绠$悊鍣?*/
|
|
168
|
+
middleware?: MiddlewareManager;
|
|
169
|
+
/** Store 鎻掍欢绠$悊鍣紝鏈彁渚涙椂浣跨敤鍏ㄥ眬绠$悊鍣?*/
|
|
170
|
+
plugins?: PluginManager;
|
|
171
|
+
/** 鎵归噺閫氱煡绠$悊鍣紝鏈彁渚涙椂浣跨敤鍏ㄥ眬绠$悊鍣?*/
|
|
172
|
+
batch?: BatchManager;
|
|
160
173
|
}
|
|
174
|
+
/** Public compatibility alias for mutation metadata. */
|
|
175
|
+
export type StoreMutation<S extends StateTree = StateTree> = StateMutation<S>;
|
|
176
|
+
/** Public compatibility alias for a Store instance. */
|
|
177
|
+
export type Store<Id extends StoreId = StoreId, S extends StateTree = StateTree, G extends StoreGetters<S> = StoreGetters<S>, A extends StoreActions = StoreActions> = StoreInstance<Id, S, G, A>;
|
|
178
|
+
/** Public compatibility alias for a Store state tree. */
|
|
179
|
+
export type StoreState = StateTree;
|
|
161
180
|
/**
|
|
162
181
|
* 持久化选项
|
|
163
182
|
*/
|
|
@@ -195,4 +214,3 @@ export interface StorageAdapter {
|
|
|
195
214
|
/** 删除数据 */
|
|
196
215
|
removeItem: (key: string) => void | Promise<void>;
|
|
197
216
|
}
|
|
198
|
-
//# sourceMappingURL=store.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module types/subscription
|
|
5
5
|
*/
|
|
6
|
-
import type { StateTree, StoreId } from './store';
|
|
6
|
+
import type { StateSubscriber, StateTree, StoreId } from './store';
|
|
7
7
|
/**
|
|
8
8
|
* 订阅回调类型
|
|
9
9
|
* @template T - 数据类型
|
|
@@ -13,6 +13,8 @@ export type Subscriber<T = unknown> = (value: T, oldValue?: T) => void;
|
|
|
13
13
|
* 取消订阅函数类型
|
|
14
14
|
*/
|
|
15
15
|
export type Unsubscribe = () => void;
|
|
16
|
+
/** Public compatibility alias for a Store subscription callback. */
|
|
17
|
+
export type StoreSubscription<S extends StateTree = StateTree> = StateSubscriber<S>;
|
|
16
18
|
/**
|
|
17
19
|
* 订阅选项
|
|
18
20
|
*/
|
|
@@ -154,5 +156,8 @@ export interface BatchManager {
|
|
|
154
156
|
* 是否正在批量更新
|
|
155
157
|
*/
|
|
156
158
|
isBatching: () => boolean;
|
|
159
|
+
/**
|
|
160
|
+
* 瑙傚療鎵归噺缁撴潫锛屽湪瀹炴椂涓嶄細褰卞搷鏃х殑 batch/start/end 鍏煎 API
|
|
161
|
+
*/
|
|
162
|
+
onFlush?: (listener: (storeIds: Set<StoreId>) => void) => Unsubscribe;
|
|
157
163
|
}
|
|
158
|
-
//# sourceMappingURL=subscription.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-10-12 17:23:58 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
12
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
package/lib/types/utility.cjs
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* // { name?: string; address?: { city?: string; zip?: string } }
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export type DeepPartial<T> = T extends object ? T extends Array<infer U> ? Array<DeepPartial<U>> : T extends Map<infer K, infer V> ? Map<DeepPartial<K>, DeepPartial<V>> : T extends Set<infer U> ? Set<DeepPartial<U>> : T extends
|
|
25
|
+
export type DeepPartial<T> = T extends object ? T extends Array<infer U> ? Array<DeepPartial<U>> : T extends Map<infer K, infer V> ? Map<DeepPartial<K>, DeepPartial<V>> : T extends Set<infer U> ? Set<DeepPartial<U>> : T extends (...args: never[]) => unknown ? T : {
|
|
26
26
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
27
27
|
} : T;
|
|
28
28
|
/**
|
|
@@ -42,7 +42,7 @@ export type DeepPartial<T> = T extends object ? T extends Array<infer U> ? Array
|
|
|
42
42
|
* // { readonly api: { readonly url: string; readonly timeout: number } }
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
|
-
export type DeepReadonly<T> = T extends object ? T extends Array<infer U> ? ReadonlyArray<DeepReadonly<U>> : T extends Map<infer K, infer V> ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>> : T extends Set<infer U> ? ReadonlySet<DeepReadonly<U>> : T extends
|
|
45
|
+
export type DeepReadonly<T> = T extends object ? T extends Array<infer U> ? ReadonlyArray<DeepReadonly<U>> : T extends Map<infer K, infer V> ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>> : T extends Set<infer U> ? ReadonlySet<DeepReadonly<U>> : T extends (...args: never[]) => unknown ? T : {
|
|
46
46
|
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
|
47
47
|
} : T;
|
|
48
48
|
/**
|
|
@@ -234,7 +234,7 @@ export type IsArray<T> = T extends unknown[] ? true : false;
|
|
|
234
234
|
*
|
|
235
235
|
* @template T - 待检查类型
|
|
236
236
|
*/
|
|
237
|
-
export type IsPlainObject<T> = T extends object ? T extends
|
|
237
|
+
export type IsPlainObject<T> = T extends object ? T extends (...args: never[]) => unknown ? false : T extends unknown[] ? false : true : false;
|
|
238
238
|
/**
|
|
239
239
|
* 值类型为指定类型的键
|
|
240
240
|
*
|
|
@@ -309,4 +309,3 @@ export type Capitalize<S extends string> = S extends `${infer F}${infer R}` ? `$
|
|
|
309
309
|
*/
|
|
310
310
|
export type Uncapitalize<S extends string> = S extends `${infer F}${infer R}` ? `${Lowercase<F>}${R}` : S;
|
|
311
311
|
export {};
|
|
312
|
-
//# sourceMappingURL=utility.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debounce-throttle.cjs","names":[],"sources":["../../src/utils/debounce-throttle.ts"],"sourcesContent":["/**\n * 防抖和节流工具函数\n *\n * 提供性能优化的防抖、节流功能\n * @module utils/debounce-throttle\n */\n\n/**\n * 防抖函数返回类型\n */\nexport interface DebouncedFunction<T extends (...args: never[]) => void> {\n (...args: Parameters<T>): void\n /** 取消待执行的调用 */\n cancel: () => void\n /** 立即执行待处理的调用 */\n flush: () => void\n /** 是否有待处理的调用 */\n pending: () => boolean\n}\n\n/**\n * 节流函数返回类型\n */\nexport interface ThrottledFunction<T extends (...args: never[]) => void> {\n (...args: Parameters<T>): void\n /** 取消待执行的调用 */\n cancel: () => void\n}\n\n/**\n * 创建防抖函数\n *\n * 在连续调用停止后,延迟指定时间执行函数\n *\n * @template T - 函数类型\n * @param fn - 需要防抖的函数\n * @param delay - 延迟时间(毫秒)\n * @param immediate - 是否在首次调用时立即执行\n * @returns 防抖后的函数\n *\n * @example\n * ```typescript\n * const debouncedSearch = debounce((query: string) => {\n * fetchResults(query)\n * }, 300)\n *\n * // 连续调用只会在最后一次调用后 300ms 执行\n * debouncedSearch('a')\n * debouncedSearch('ab')\n * debouncedSearch('abc') // 只有这次会触发\n *\n * // 取消待执行的调用\n * debouncedSearch.cancel()\n * ```\n */\nexport function debounce<T extends (...args: never[]) => void>(\n fn: T,\n delay: number,\n immediate = false
|
|
1
|
+
{"version":3,"file":"debounce-throttle.cjs","names":[],"sources":["../../src/utils/debounce-throttle.ts"],"sourcesContent":["/**\r\n * 防抖和节流工具函数\r\n *\r\n * 提供性能优化的防抖、节流功能\r\n * @module utils/debounce-throttle\r\n */\r\n\r\n/**\r\n * 防抖函数返回类型\r\n */\r\nexport interface DebouncedFunction<T extends (...args: never[]) => void> {\r\n (...args: Parameters<T>): void\r\n /** 取消待执行的调用 */\r\n cancel: () => void\r\n /** 立即执行待处理的调用 */\r\n flush: () => void\r\n /** 是否有待处理的调用 */\r\n pending: () => boolean\r\n}\r\n\r\n/**\r\n * 节流函数返回类型\r\n */\r\nexport interface ThrottledFunction<T extends (...args: never[]) => void> {\r\n (...args: Parameters<T>): void\r\n /** 取消待执行的调用 */\r\n cancel: () => void\r\n}\r\n\r\n/**\r\n * 创建防抖函数\r\n *\r\n * 在连续调用停止后,延迟指定时间执行函数\r\n *\r\n * @template T - 函数类型\r\n * @param fn - 需要防抖的函数\r\n * @param delay - 延迟时间(毫秒)\r\n * @param immediate - 是否在首次调用时立即执行\r\n * @returns 防抖后的函数\r\n *\r\n * @example\r\n * ```typescript\r\n * const debouncedSearch = debounce((query: string) => {\r\n * fetchResults(query)\r\n * }, 300)\r\n *\r\n * // 连续调用只会在最后一次调用后 300ms 执行\r\n * debouncedSearch('a')\r\n * debouncedSearch('ab')\r\n * debouncedSearch('abc') // 只有这次会触发\r\n *\r\n * // 取消待执行的调用\r\n * debouncedSearch.cancel()\r\n * ```\r\n */\r\nexport function debounce<T extends (...args: never[]) => void>(\r\n fn: T,\r\n delay: number,\r\n immediate = false\r\n): DebouncedFunction<T> {\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n let lastArgs: Parameters<T> | null = null\r\n\r\n const debounced = ((...args: Parameters<T>) => {\r\n lastArgs = args\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n if (immediate && !timer) {\r\n fn(...args)\r\n timer = setTimeout(() => {\r\n timer = null\r\n lastArgs = null\r\n }, delay)\r\n } else {\r\n timer = setTimeout(() => {\r\n fn(...args)\r\n timer = null\r\n lastArgs = null\r\n }, delay)\r\n }\r\n }) as DebouncedFunction<T>\r\n\r\n debounced.cancel = () => {\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n lastArgs = null\r\n }\r\n }\r\n\r\n debounced.flush = () => {\r\n if (timer && lastArgs) {\r\n clearTimeout(timer)\r\n fn(...lastArgs)\r\n timer = null\r\n lastArgs = null\r\n }\r\n }\r\n\r\n debounced.pending = () => timer !== null\r\n\r\n return debounced\r\n}\r\n\r\n/**\r\n * 创建节流函数\r\n *\r\n * 在指定时间间隔内最多执行一次函数\r\n *\r\n * @template T - 函数类型\r\n * @param fn - 需要节流的函数\r\n * @param interval - 间隔时间(毫秒)\r\n * @param options - 节流选项\r\n * @param options.leading - 是否在时间窗开始时立即执行\r\n * @param options.trailing - 是否在时间窗结束时补执行最后一次调用\r\n * @returns 节流后的函数\r\n *\r\n * @example\r\n * ```typescript\r\n * const throttledUpdate = throttle((x: number, y: number) => {\r\n * updatePosition(x, y)\r\n * }, 100)\r\n *\r\n * // 在 100ms 内多次调用,只会执行一次\r\n * window.addEventListener('mousemove', (e) => {\r\n * throttledUpdate(e.clientX, e.clientY)\r\n * })\r\n *\r\n * // 取消\r\n * throttledUpdate.cancel()\r\n * ```\r\n */\r\nexport function throttle<T extends (...args: never[]) => void>(\r\n fn: T,\r\n interval: number,\r\n options: { leading?: boolean; trailing?: boolean } = {}\r\n): ThrottledFunction<T> {\r\n const { leading = true, trailing = true } = options\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n let lastTime = 0\r\n let lastArgs: Parameters<T> | null = null\r\n\r\n const throttled = ((...args: Parameters<T>) => {\r\n const now = Date.now()\r\n const remaining = interval - (now - lastTime)\r\n\r\n lastArgs = args\r\n\r\n if (remaining <= 0 || remaining > interval) {\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n lastTime = now\r\n if (leading || lastTime !== 0) {\r\n fn(...args)\r\n }\r\n lastArgs = null\r\n } else if (!timer && trailing) {\r\n timer = setTimeout(() => {\r\n lastTime = trailing ? Date.now() : 0\r\n timer = null\r\n if (lastArgs) {\r\n fn(...lastArgs)\r\n lastArgs = null\r\n }\r\n }, remaining)\r\n }\r\n }) as ThrottledFunction<T>\r\n\r\n throttled.cancel = () => {\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n lastTime = 0\r\n lastArgs = null\r\n }\r\n\r\n return throttled\r\n}\r\n"],"mappings":";;;;;;;;;;;;AAuDO,SAAS,SACd,IACA,OACA,YAAY,OACU;CACtB,IAAI,QAA8C;CAClD,IAAI,WAAiC;CAErC,MAAM,cAAa,GAAI,SAAwB;EAC7C,WAAW;EAEX,IAAI,OACF,aAAa,KAAK;EAGpB,IAAI,aAAa,CAAC,OAAO;GACvB,GAAG,GAAG,IAAI;GACV,QAAQ,iBAAiB;IACvB,QAAQ;IACR,WAAW;GACb,GAAG,KAAK;EACV,OACE,QAAQ,iBAAiB;GACvB,GAAG,GAAG,IAAI;GACV,QAAQ;GACR,WAAW;EACb,GAAG,KAAK;CAEZ;CAEA,UAAU,eAAe;EACvB,IAAI,OAAO;GACT,aAAa,KAAK;GAClB,QAAQ;GACR,WAAW;EACb;CACF;CAEA,UAAU,cAAc;EACtB,IAAI,SAAS,UAAU;GACrB,aAAa,KAAK;GAClB,GAAG,GAAG,QAAQ;GACd,QAAQ;GACR,WAAW;EACb;CACF;CAEA,UAAU,gBAAgB,UAAU;CAEpC,OAAO;AACT;AA8BO,SAAS,SACd,IACA,UACA,UAAqD,CAAC,GAChC;CACtB,MAAM,EAAE,UAAU,MAAM,WAAW,SAAS;CAC5C,IAAI,QAA8C;CAClD,IAAI,WAAW;CACf,IAAI,WAAiC;CAErC,MAAM,cAAa,GAAI,SAAwB;EAC7C,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,YAAY,YAAY,MAAM;EAEpC,WAAW;EAEX,IAAI,aAAa,KAAK,YAAY,UAAU;GAC1C,IAAI,OAAO;IACT,aAAa,KAAK;IAClB,QAAQ;GACV;GACA,WAAW;GACX,IAAI,WAAW,aAAa,GAC1B,GAAG,GAAG,IAAI;GAEZ,WAAW;EACb,OAAA,IAAW,CAAC,SAAS,UACnB,QAAQ,iBAAiB;GACvB,WAAW,WAAW,KAAK,IAAI,IAAI;GACnC,QAAQ;GACR,IAAI,UAAU;IACZ,GAAG,GAAG,QAAQ;IACd,WAAW;GACb;EACF,GAAG,SAAS;CAEhB;CAEA,UAAU,eAAe;EACvB,IAAI,OAAO;GACT,aAAa,KAAK;GAClB,QAAQ;EACV;EACA,WAAW;EACX,WAAW;CACb;CAEA,OAAO;AACT"}
|
package/lib/utils/deep-clone.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-clone.cjs","names":["result"],"sources":["../../src/utils/deep-clone.ts"],"sourcesContent":["/**\n * 深拷贝工具\n *\n * 提供高性能的深拷贝、浅拷贝和深度合并功能\n * @module utils/deep-clone\n */\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\nfunction hasOwnKey(value: object, key: PropertyKey): boolean {\n return hasOwnProperty.call(value, key)\n}\n\n/**\n * 判断是否为对象\n *\n * @param value - 待检查的值\n * @returns 是否为对象\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object'\n}\n\n/**\n * 判断是否为普通对象(非数组、非内置对象)\n *\n * @param value - 待检查的值\n * @returns 是否为普通对象\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (!isObject(value)) return false\n const proto = Object.getPrototypeOf(value)\n return proto === null || proto === Object.prototype\n}\n\n/**\n * 判断值是否可以被 structuredClone 处理\n *\n * @param value - 待检查的值\n * @returns 是否可以使用 structuredClone\n */\nfunction isStructuredCloneable(value: unknown): boolean {\n // 基础类型\n if (value === null || value === undefined) return true\n if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string') return true\n if (typeof value === 'bigint') return true\n\n // 函数和 Symbol 不可克隆\n if (typeof value === 'function' || typeof value === 'symbol') return false\n\n // 内置可克隆对象\n if (value instanceof Date || value instanceof RegExp) return true\n if (value instanceof ArrayBuffer || value instanceof DataView) return true\n if (value instanceof Map || value instanceof Set) return true\n if (ArrayBuffer.isView(value)) return true\n\n // 普通对象和数组递归检查\n if (Array.isArray(value)) {\n return value.every(item => isStructuredCloneable(item))\n }\n\n if (isPlainObject(value)) {\n return Object.values(value).every(v => isStructuredCloneable(v))\n }\n\n return false\n}\n\n/**\n * 深拷贝配置选项\n */\nexport interface DeepCloneOptions {\n /** 是否优先使用 structuredClone(默认 true) */\n useStructuredClone?: boolean\n /** 是否克隆函数(默认 false,函数保持引用) */\n cloneFunctions?: boolean\n /** 是否克隆 Symbol 属性(默认 false) */\n cloneSymbols?: boolean\n /** 最大深度(默认无限制) */\n maxDepth?: number\n /** 自定义克隆器 */\n customCloner?: <T>(value: T, clone: <U>(v: U) => U) => T | undefined\n}\n\n/**\n * 深拷贝\n *\n * 高性能深拷贝实现,优先使用原生 structuredClone(如果可用)\n *\n * @template T - 值类型\n * @param value - 要拷贝的值\n * @param options - 配置选项\n * @returns 拷贝后的值\n *\n * @example\n * ```typescript\n * const obj = { a: 1, b: { c: 2 } }\n * const cloned = deepClone(obj)\n * cloned.b.c = 3\n * console.log(obj.b.c) // 2\n * ```\n *\n * @example\n * ```typescript\n * // 带配置的深拷贝\n * const cloned = deepClone(obj, {\n * maxDepth: 5,\n * cloneSymbols: true\n * })\n * ```\n */\nexport function deepClone<T>(value: T, options: DeepCloneOptions = {}): T {\n const {\n useStructuredClone: preferStructuredClone = true,\n cloneFunctions = false,\n cloneSymbols = false,\n maxDepth = Infinity,\n customCloner,\n } = options\n\n // 尝试使用 structuredClone(性能更好)\n if (preferStructuredClone && typeof structuredClone === 'function' && isStructuredCloneable(value)) {\n try {\n return structuredClone(value)\n }\n catch {\n // structuredClone 失败,回退到手动实现\n }\n }\n\n const cache = new WeakMap<object, unknown>()\n\n function cloneInternal<U>(val: U, depth: number): U {\n // 基础类型直接返回\n if (val === null || val === undefined) return val\n if (typeof val === 'boolean' || typeof val === 'number' || typeof val === 'string') return val\n if (typeof val === 'bigint') return val\n\n // Symbol 处理\n if (typeof val === 'symbol') {\n return cloneSymbols ? Symbol(val.description) as U : val\n }\n\n // 函数处理\n if (typeof val === 'function') {\n return cloneFunctions ? (val.bind({}) as U) : val\n }\n\n // 深度检查\n if (depth > maxDepth) {\n return val\n }\n\n // 自定义克隆器\n if (customCloner) {\n const customResult = customCloner(val, v => cloneInternal(v, depth + 1))\n if (customResult !== undefined) {\n return customResult\n }\n }\n\n // 检查循环引用\n if (typeof val === 'object' && val !== null) {\n if (cache.has(val)) {\n return cache.get(val) as U\n }\n }\n\n // 处理日期\n if (val instanceof Date) {\n return new Date(val.getTime()) as U\n }\n\n // 处理正则\n if (val instanceof RegExp) {\n const result = new RegExp(val.source, val.flags)\n ;(result as RegExp).lastIndex = val.lastIndex\n return result as U\n }\n\n // 处理 Error\n if (val instanceof Error) {\n const result = new (val.constructor as ErrorConstructor)(val.message)\n result.stack = val.stack\n result.name = val.name\n return result as U\n }\n\n // 处理 Map\n if (val instanceof Map) {\n const result = new Map()\n cache.set(val, result)\n val.forEach((v, k) => {\n result.set(cloneInternal(k, depth + 1), cloneInternal(v, depth + 1))\n })\n return result as U\n }\n\n // 处理 Set\n if (val instanceof Set) {\n const result = new Set()\n cache.set(val, result)\n val.forEach((v) => {\n result.add(cloneInternal(v, depth + 1))\n })\n return result as U\n }\n\n // 处理 ArrayBuffer\n if (val instanceof ArrayBuffer) {\n return val.slice(0) as U\n }\n\n // 处理 TypedArray\n if (ArrayBuffer.isView(val) && !(val instanceof DataView)) {\n const TypedArrayConstructor = val.constructor as new (buffer: ArrayBuffer) => typeof val\n return new TypedArrayConstructor((val as unknown as { buffer: ArrayBuffer }).buffer.slice(0)) as U\n }\n\n // 处理数组\n if (Array.isArray(val)) {\n const result: unknown[] = []\n cache.set(val, result)\n for (let i = 0; i < val.length; i++) {\n result[i] = cloneInternal(val[i], depth + 1)\n }\n return result as U\n }\n\n // 处理普通对象\n if (isPlainObject(val)) {\n const result: Record<string | symbol, unknown> = {}\n cache.set(val, result)\n\n // 克隆字符串键\n const keys = Object.keys(val)\n for (const key of keys) {\n result[key] = cloneInternal((val as Record<string, unknown>)[key], depth + 1)\n }\n\n // 克隆 Symbol 键\n if (cloneSymbols) {\n const symbolKeys = Object.getOwnPropertySymbols(val)\n for (const sym of symbolKeys) {\n result[sym] = cloneInternal((val as Record<symbol, unknown>)[sym], depth + 1)\n }\n }\n\n return result as U\n }\n\n // 其他对象类型(如自定义类实例)直接返回\n return val\n }\n\n return cloneInternal(value, 0)\n}\n\n/**\n * 浅拷贝\n *\n * @template T - 值类型\n * @param value - 要拷贝的值\n * @returns 拷贝后的值\n *\n * @example\n * ```typescript\n * const arr = [1, 2, { a: 3 }]\n * const cloned = shallowClone(arr)\n * cloned[2].a = 4\n * console.log(arr[2].a) // 4 (浅拷贝,嵌套对象共享引用)\n * ```\n */\nexport function shallowClone<T>(value: T): T {\n if (value === null || value === undefined) return value\n if (typeof value !== 'object') return value\n\n if (Array.isArray(value)) {\n return [...value] as T\n }\n\n if (value instanceof Map) {\n return new Map(value) as T\n }\n\n if (value instanceof Set) {\n return new Set(value) as T\n }\n\n if (value instanceof Date) {\n return new Date(value.getTime()) as T\n }\n\n return { ...value }\n}\n\n/**\n * 深度合并配置选项\n */\nexport interface DeepMergeOptions {\n /** 数组合并策略:'replace' 替换 | 'concat' 连接 | 'merge' 按索引合并 */\n arrayStrategy?: 'replace' | 'concat' | 'merge'\n /** 是否克隆源对象(默认 true) */\n clone?: boolean\n /** 最大深度 */\n maxDepth?: number\n}\n\n/**\n * 深度合并对象\n *\n * 将多个源对象深度合并到目标对象\n *\n * @template T - 目标对象类型\n * @param target - 目标对象\n * @param sources - 源对象列表\n * @returns 合并后的对象\n *\n * @example\n * ```typescript\n * const target = { a: 1, b: { c: 2 } }\n * const source = { b: { d: 3 }, e: 4 }\n * const result = deepMerge(target, source)\n * // { a: 1, b: { c: 2, d: 3 }, e: 4 }\n * ```\n */\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n ...sources: Array<Partial<T>>\n): T {\n return deepMergeWithOptions(target, {}, ...sources)\n}\n\n/**\n * 带配置的深度合并\n *\n * @template T - 目标对象类型\n * @param target - 目标对象\n * @param options - 合并配置\n * @param sources - 源对象列表\n * @returns 合并后的对象\n */\nexport function deepMergeWithOptions<T extends Record<string, unknown>>(\n target: T,\n options: DeepMergeOptions,\n ...sources: Array<Partial<T>>\n): T {\n const {\n arrayStrategy = 'replace',\n clone = true,\n maxDepth = Infinity,\n } = options\n\n function mergeInternal(\n targetObj: Record<string, unknown>,\n sourceObj: Record<string, unknown>,\n depth: number,\n ): Record<string, unknown> {\n if (depth > maxDepth) {\n return targetObj\n }\n\n for (const key of Object.keys(sourceObj)) {\n const sourceValue = sourceObj[key]\n const targetValue = targetObj[key]\n\n // 处理数组\n if (Array.isArray(sourceValue)) {\n if (arrayStrategy === 'concat' && Array.isArray(targetValue)) {\n targetObj[key] = [...targetValue, ...sourceValue]\n }\n else if (arrayStrategy === 'merge' && Array.isArray(targetValue)) {\n const result = [...targetValue]\n sourceValue.forEach((item, index) => {\n if (isPlainObject(item) && isPlainObject(result[index])) {\n result[index] = mergeInternal(result[index] as Record<string, unknown>, item, depth + 1)\n }\n else {\n result[index] = clone ? deepClone(item) : item\n }\n })\n targetObj[key] = result\n }\n else {\n targetObj[key] = clone ? deepClone(sourceValue) : sourceValue\n }\n }\n // 处理普通对象\n else if (isPlainObject(sourceValue)) {\n if (isPlainObject(targetValue)) {\n targetObj[key] = mergeInternal(\n targetValue as Record<string, unknown>,\n sourceValue,\n depth + 1,\n )\n }\n else {\n targetObj[key] = clone ? deepClone(sourceValue) : sourceValue\n }\n }\n // 其他类型直接赋值\n else {\n targetObj[key] = clone && isObject(sourceValue) ? deepClone(sourceValue) : sourceValue\n }\n }\n\n return targetObj\n }\n\n let result = target\n\n for (const source of sources) {\n if (source !== null && source !== undefined) {\n result = mergeInternal(result, source, 0) as T\n }\n }\n\n return result\n}\n\n/**\n * 比较两个值是否深度相等\n *\n * @param a - 第一个值\n * @param b - 第二个值\n * @returns 是否相等\n *\n * @example\n * ```typescript\n * deepEqual({ a: 1 }, { a: 1 }) // true\n * deepEqual([1, 2], [1, 2]) // true\n * deepEqual({ a: { b: 1 } }, { a: { b: 2 } }) // false\n * ```\n */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n // 严格相等\n if (a === b) return true\n\n // null/undefined 检查\n if (a === null || b === null || a === undefined || b === undefined) {\n return a === b\n }\n\n // 类型不同\n if (typeof a !== typeof b) return false\n\n // 基础类型\n if (typeof a !== 'object') return a === b\n\n // 日期比较\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n // 正则比较\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.source === b.source && a.flags === b.flags\n }\n\n // Map 比较\n if (a instanceof Map && b instanceof Map) {\n if (a.size !== b.size) return false\n for (const [key, value] of a) {\n if (!b.has(key) || !deepEqual(value, b.get(key))) {\n return false\n }\n }\n return true\n }\n\n // Set 比较\n if (a instanceof Set && b instanceof Set) {\n if (a.size !== b.size) return false\n for (const value of a) {\n if (!b.has(value)) return false\n }\n return true\n }\n\n // 数组比较\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i])) return false\n }\n return true\n }\n\n // 对象比较\n if (isPlainObject(a) && isPlainObject(b)) {\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n if (keysA.length !== keysB.length) return false\n for (const key of keysA) {\n if (!hasOwnKey(b, key)) return false\n if (!deepEqual(a[key], b[key])) return false\n }\n return true\n }\n\n return false\n}\n\n/**\n * 冻结对象(深度)\n *\n * @template T - 对象类型\n * @param obj - 要冻结的对象\n * @returns 冻结后的对象\n */\nexport function deepFreeze<T extends object>(obj: T): Readonly<T> {\n const propNames = Object.getOwnPropertyNames(obj)\n\n for (const name of propNames) {\n const value = (obj as Record<string, unknown>)[name]\n if (value && typeof value === 'object') {\n deepFreeze(value)\n }\n }\n\n return Object.freeze(obj)\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deep-clone.cjs","names":["result"],"sources":["../../src/utils/deep-clone.ts"],"sourcesContent":["/**\r\n * 深拷贝工具\r\n *\r\n * 提供高性能的深拷贝、浅拷贝和深度合并功能\r\n * @module utils/deep-clone\r\n */\r\n\r\nconst hasOwnProperty = Object.prototype.hasOwnProperty\r\n\r\nfunction hasOwnKey(value: object, key: PropertyKey): boolean {\r\n return hasOwnProperty.call(value, key)\r\n}\r\n\r\n/**\r\n * 判断是否为对象\r\n *\r\n * @param value - 待检查的值\r\n * @returns 是否为对象\r\n */\r\nexport function isObject(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === 'object'\r\n}\r\n\r\n/**\r\n * 判断是否为普通对象(非数组、非内置对象)\r\n *\r\n * @param value - 待检查的值\r\n * @returns 是否为普通对象\r\n */\r\nexport function isPlainObject(\r\n value: unknown\r\n): value is Record<string, unknown> {\r\n if (!isObject(value)) return false\r\n const proto = Object.getPrototypeOf(value)\r\n return proto === null || proto === Object.prototype\r\n}\r\n\r\n/**\r\n * 判断值是否可以被 structuredClone 处理\r\n *\r\n * @param value - 待检查的值\r\n * @returns 是否可以使用 structuredClone\r\n */\r\nfunction isStructuredCloneable(value: unknown): boolean {\r\n // 基础类型\r\n if (value === null || value === undefined) return true\r\n if (\r\n typeof value === 'boolean' ||\r\n typeof value === 'number' ||\r\n typeof value === 'string'\r\n )\r\n return true\r\n if (typeof value === 'bigint') return true\r\n\r\n // 函数和 Symbol 不可克隆\r\n if (typeof value === 'function' || typeof value === 'symbol') return false\r\n\r\n // 内置可克隆对象\r\n if (value instanceof Date || value instanceof RegExp) return true\r\n if (value instanceof ArrayBuffer || value instanceof DataView) return true\r\n if (value instanceof Map || value instanceof Set) return true\r\n if (ArrayBuffer.isView(value)) return true\r\n\r\n // 普通对象和数组递归检查\r\n if (Array.isArray(value)) {\r\n return value.every(item => isStructuredCloneable(item))\r\n }\r\n\r\n if (isPlainObject(value)) {\r\n return Object.values(value).every(v => isStructuredCloneable(v))\r\n }\r\n\r\n return false\r\n}\r\n\r\n/**\r\n * 深拷贝配置选项\r\n */\r\nexport interface DeepCloneOptions {\r\n /** 是否优先使用 structuredClone(默认 true) */\r\n useStructuredClone?: boolean\r\n /** 是否克隆函数(默认 false,函数保持引用) */\r\n cloneFunctions?: boolean\r\n /** 是否克隆 Symbol 属性(默认 false) */\r\n cloneSymbols?: boolean\r\n /** 最大深度(默认无限制) */\r\n maxDepth?: number\r\n /** 自定义克隆器 */\r\n customCloner?: <T>(value: T, clone: <U>(v: U) => U) => T | undefined\r\n}\r\n\r\n/**\r\n * 深拷贝\r\n *\r\n * 高性能深拷贝实现,优先使用原生 structuredClone(如果可用)\r\n *\r\n * @template T - 值类型\r\n * @param value - 要拷贝的值\r\n * @param options - 配置选项\r\n * @returns 拷贝后的值\r\n *\r\n * @example\r\n * ```typescript\r\n * const obj = { a: 1, b: { c: 2 } }\r\n * const cloned = deepClone(obj)\r\n * cloned.b.c = 3\r\n * console.log(obj.b.c) // 2\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // 带配置的深拷贝\r\n * const cloned = deepClone(obj, {\r\n * maxDepth: 5,\r\n * cloneSymbols: true\r\n * })\r\n * ```\r\n */\r\nexport function deepClone<T>(value: T, options: DeepCloneOptions = {}): T {\r\n const {\r\n useStructuredClone: preferStructuredClone = true,\r\n cloneFunctions = false,\r\n cloneSymbols = false,\r\n maxDepth = Infinity,\r\n customCloner,\r\n } = options\r\n\r\n // 尝试使用 structuredClone(性能更好)\r\n if (\r\n preferStructuredClone &&\r\n typeof structuredClone === 'function' &&\r\n isStructuredCloneable(value)\r\n ) {\r\n try {\r\n return structuredClone(value)\r\n } catch {\r\n // structuredClone 失败,回退到手动实现\r\n }\r\n }\r\n\r\n const cache = new WeakMap<object, unknown>()\r\n\r\n function cloneInternal<U>(val: U, depth: number): U {\r\n // 基础类型直接返回\r\n if (val === null || val === undefined) return val\r\n if (\r\n typeof val === 'boolean' ||\r\n typeof val === 'number' ||\r\n typeof val === 'string'\r\n )\r\n return val\r\n if (typeof val === 'bigint') return val\r\n\r\n // Symbol 处理\r\n if (typeof val === 'symbol') {\r\n return cloneSymbols ? (Symbol(val.description) as U) : val\r\n }\r\n\r\n // 函数处理\r\n if (typeof val === 'function') {\r\n return cloneFunctions ? (val.bind({}) as U) : val\r\n }\r\n\r\n // 深度检查\r\n if (depth > maxDepth) {\r\n return val\r\n }\r\n\r\n // 自定义克隆器\r\n if (customCloner) {\r\n const customResult = customCloner(val, v => cloneInternal(v, depth + 1))\r\n if (customResult !== undefined) {\r\n return customResult\r\n }\r\n }\r\n\r\n // 检查循环引用\r\n if (typeof val === 'object' && val !== null) {\r\n if (cache.has(val)) {\r\n return cache.get(val) as U\r\n }\r\n }\r\n\r\n // 处理日期\r\n if (val instanceof Date) {\r\n return new Date(val.getTime()) as U\r\n }\r\n\r\n // 处理正则\r\n if (val instanceof RegExp) {\r\n const result = new RegExp(val.source, val.flags)\r\n ;(result as RegExp).lastIndex = val.lastIndex\r\n return result as U\r\n }\r\n\r\n // 处理 Error\r\n if (val instanceof Error) {\r\n const result = new (val.constructor as ErrorConstructor)(val.message)\r\n result.stack = val.stack\r\n result.name = val.name\r\n return result as U\r\n }\r\n\r\n // 处理 Map\r\n if (val instanceof Map) {\r\n const result = new Map()\r\n cache.set(val, result)\r\n val.forEach((v, k) => {\r\n result.set(cloneInternal(k, depth + 1), cloneInternal(v, depth + 1))\r\n })\r\n return result as U\r\n }\r\n\r\n // 处理 Set\r\n if (val instanceof Set) {\r\n const result = new Set()\r\n cache.set(val, result)\r\n val.forEach(v => {\r\n result.add(cloneInternal(v, depth + 1))\r\n })\r\n return result as U\r\n }\r\n\r\n // 处理 ArrayBuffer\r\n if (val instanceof ArrayBuffer) {\r\n return val.slice(0) as U\r\n }\r\n\r\n // 处理 TypedArray\r\n if (ArrayBuffer.isView(val) && !(val instanceof DataView)) {\r\n const TypedArrayConstructor = val.constructor as new (\r\n buffer: ArrayBuffer\r\n ) => typeof val\r\n return new TypedArrayConstructor(\r\n (val as unknown as { buffer: ArrayBuffer }).buffer.slice(0)\r\n ) as U\r\n }\r\n\r\n // 处理数组\r\n if (Array.isArray(val)) {\r\n const result: unknown[] = []\r\n cache.set(val, result)\r\n for (let i = 0; i < val.length; i++) {\r\n result[i] = cloneInternal(val[i], depth + 1)\r\n }\r\n return result as U\r\n }\r\n\r\n // 处理普通对象\r\n if (isPlainObject(val)) {\r\n const result: Record<string | symbol, unknown> = {}\r\n cache.set(val, result)\r\n\r\n // 克隆字符串键\r\n const keys = Object.keys(val)\r\n for (const key of keys) {\r\n result[key] = cloneInternal(\r\n (val as Record<string, unknown>)[key],\r\n depth + 1\r\n )\r\n }\r\n\r\n // 克隆 Symbol 键\r\n if (cloneSymbols) {\r\n const symbolKeys = Object.getOwnPropertySymbols(val)\r\n for (const sym of symbolKeys) {\r\n result[sym] = cloneInternal(\r\n (val as Record<symbol, unknown>)[sym],\r\n depth + 1\r\n )\r\n }\r\n }\r\n\r\n return result as U\r\n }\r\n\r\n // 其他对象类型(如自定义类实例)直接返回\r\n return val\r\n }\r\n\r\n return cloneInternal(value, 0)\r\n}\r\n\r\n/**\r\n * 浅拷贝\r\n *\r\n * @template T - 值类型\r\n * @param value - 要拷贝的值\r\n * @returns 拷贝后的值\r\n *\r\n * @example\r\n * ```typescript\r\n * const arr = [1, 2, { a: 3 }]\r\n * const cloned = shallowClone(arr)\r\n * cloned[2].a = 4\r\n * console.log(arr[2].a) // 4 (浅拷贝,嵌套对象共享引用)\r\n * ```\r\n */\r\nexport function shallowClone<T>(value: T): T {\r\n if (value === null || value === undefined) return value\r\n if (typeof value !== 'object') return value\r\n\r\n if (Array.isArray(value)) {\r\n return [...value] as T\r\n }\r\n\r\n if (value instanceof Map) {\r\n return new Map(value) as T\r\n }\r\n\r\n if (value instanceof Set) {\r\n return new Set(value) as T\r\n }\r\n\r\n if (value instanceof Date) {\r\n return new Date(value.getTime()) as T\r\n }\r\n\r\n return { ...value }\r\n}\r\n\r\n/**\r\n * 深度合并配置选项\r\n */\r\nexport interface DeepMergeOptions {\r\n /** 数组合并策略:'replace' 替换 | 'concat' 连接 | 'merge' 按索引合并 */\r\n arrayStrategy?: 'replace' | 'concat' | 'merge'\r\n /** 是否克隆源对象(默认 true) */\r\n clone?: boolean\r\n /** 最大深度 */\r\n maxDepth?: number\r\n}\r\n\r\n/**\r\n * 深度合并对象\r\n *\r\n * 将多个源对象深度合并到目标对象\r\n *\r\n * @template T - 目标对象类型\r\n * @param target - 目标对象\r\n * @param sources - 源对象列表\r\n * @returns 合并后的对象\r\n *\r\n * @example\r\n * ```typescript\r\n * const target = { a: 1, b: { c: 2 } }\r\n * const source = { b: { d: 3 }, e: 4 }\r\n * const result = deepMerge(target, source)\r\n * // { a: 1, b: { c: 2, d: 3 }, e: 4 }\r\n * ```\r\n */\r\nexport function deepMerge<T extends Record<string, unknown>>(\r\n target: T,\r\n ...sources: Array<Partial<T>>\r\n): T {\r\n return deepMergeWithOptions(target, {}, ...sources)\r\n}\r\n\r\n/**\r\n * 带配置的深度合并\r\n *\r\n * @template T - 目标对象类型\r\n * @param target - 目标对象\r\n * @param options - 合并配置\r\n * @param sources - 源对象列表\r\n * @returns 合并后的对象\r\n */\r\nexport function deepMergeWithOptions<T extends Record<string, unknown>>(\r\n target: T,\r\n options: DeepMergeOptions,\r\n ...sources: Array<Partial<T>>\r\n): T {\r\n const {\r\n arrayStrategy = 'replace',\r\n clone = true,\r\n maxDepth = Infinity,\r\n } = options\r\n\r\n function mergeInternal(\r\n targetObj: Record<string, unknown>,\r\n sourceObj: Record<string, unknown>,\r\n depth: number\r\n ): Record<string, unknown> {\r\n if (depth > maxDepth) {\r\n return targetObj\r\n }\r\n\r\n for (const key of Object.keys(sourceObj)) {\r\n const sourceValue = sourceObj[key]\r\n const targetValue = targetObj[key]\r\n\r\n // 处理数组\r\n if (Array.isArray(sourceValue)) {\r\n if (arrayStrategy === 'concat' && Array.isArray(targetValue)) {\r\n targetObj[key] = [...targetValue, ...sourceValue]\r\n } else if (arrayStrategy === 'merge' && Array.isArray(targetValue)) {\r\n const result = [...targetValue]\r\n sourceValue.forEach((item, index) => {\r\n if (isPlainObject(item) && isPlainObject(result[index])) {\r\n result[index] = mergeInternal(\r\n result[index] as Record<string, unknown>,\r\n item,\r\n depth + 1\r\n )\r\n } else {\r\n result[index] = clone ? deepClone(item) : item\r\n }\r\n })\r\n targetObj[key] = result\r\n } else {\r\n targetObj[key] = clone ? deepClone(sourceValue) : sourceValue\r\n }\r\n }\r\n // 处理普通对象\r\n else if (isPlainObject(sourceValue)) {\r\n if (isPlainObject(targetValue)) {\r\n targetObj[key] = mergeInternal(\r\n targetValue as Record<string, unknown>,\r\n sourceValue,\r\n depth + 1\r\n )\r\n } else {\r\n targetObj[key] = clone ? deepClone(sourceValue) : sourceValue\r\n }\r\n }\r\n // 其他类型直接赋值\r\n else {\r\n targetObj[key] =\r\n clone && isObject(sourceValue) ? deepClone(sourceValue) : sourceValue\r\n }\r\n }\r\n\r\n return targetObj\r\n }\r\n\r\n let result = target\r\n\r\n for (const source of sources) {\r\n if (source !== null && source !== undefined) {\r\n result = mergeInternal(result, source, 0) as T\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * 比较两个值是否深度相等\r\n *\r\n * @param a - 第一个值\r\n * @param b - 第二个值\r\n * @returns 是否相等\r\n *\r\n * @example\r\n * ```typescript\r\n * deepEqual({ a: 1 }, { a: 1 }) // true\r\n * deepEqual([1, 2], [1, 2]) // true\r\n * deepEqual({ a: { b: 1 } }, { a: { b: 2 } }) // false\r\n * ```\r\n */\r\nexport function deepEqual(a: unknown, b: unknown): boolean {\r\n // 严格相等\r\n if (a === b) return true\r\n\r\n // null/undefined 检查\r\n if (a === null || b === null || a === undefined || b === undefined) {\r\n return a === b\r\n }\r\n\r\n // 类型不同\r\n if (typeof a !== typeof b) return false\r\n\r\n // 基础类型\r\n if (typeof a !== 'object') return a === b\r\n\r\n // 日期比较\r\n if (a instanceof Date && b instanceof Date) {\r\n return a.getTime() === b.getTime()\r\n }\r\n\r\n // 正则比较\r\n if (a instanceof RegExp && b instanceof RegExp) {\r\n return a.source === b.source && a.flags === b.flags\r\n }\r\n\r\n // Map 比较\r\n if (a instanceof Map && b instanceof Map) {\r\n if (a.size !== b.size) return false\r\n for (const [key, value] of a) {\r\n if (!b.has(key) || !deepEqual(value, b.get(key))) {\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n\r\n // Set 比较\r\n if (a instanceof Set && b instanceof Set) {\r\n if (a.size !== b.size) return false\r\n for (const value of a) {\r\n if (!b.has(value)) return false\r\n }\r\n return true\r\n }\r\n\r\n // 数组比较\r\n if (Array.isArray(a) && Array.isArray(b)) {\r\n if (a.length !== b.length) return false\r\n for (let i = 0; i < a.length; i++) {\r\n if (!deepEqual(a[i], b[i])) return false\r\n }\r\n return true\r\n }\r\n\r\n // 对象比较\r\n if (isPlainObject(a) && isPlainObject(b)) {\r\n const keysA = Object.keys(a)\r\n const keysB = Object.keys(b)\r\n if (keysA.length !== keysB.length) return false\r\n for (const key of keysA) {\r\n if (!hasOwnKey(b, key)) return false\r\n if (!deepEqual(a[key], b[key])) return false\r\n }\r\n return true\r\n }\r\n\r\n return false\r\n}\r\n\r\n/**\r\n * 冻结对象(深度)\r\n *\r\n * @template T - 对象类型\r\n * @param obj - 要冻结的对象\r\n * @returns 冻结后的对象\r\n */\r\nexport function deepFreeze<T extends object>(obj: T): Readonly<T> {\r\n const propNames = Object.getOwnPropertyNames(obj)\r\n\r\n for (const name of propNames) {\r\n const value = (obj as Record<string, unknown>)[name]\r\n if (value && typeof value === 'object') {\r\n deepFreeze(value)\r\n }\r\n }\r\n\r\n return Object.freeze(obj)\r\n}\r\n"],"mappings":";;;;;;;;;;;;AAOA,MAAM,iBAAiB,OAAO,UAAU;AAExC,SAAS,UAAU,OAAe,KAA2B;CAC3D,OAAO,eAAe,KAAK,OAAO,GAAG;AACvC;AAQO,SAAS,SAAS,OAAkD;CACzE,OAAO,UAAU,QAAQ,OAAO,UAAU;AAC5C;AAQO,SAAS,cACd,OACkC;CAClC,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAC7B,MAAM,QAAQ,OAAO,eAAe,KAAK;CACzC,OAAO,UAAU,QAAQ,UAAU,OAAO;AAC5C;AAQA,SAAS,sBAAsB,OAAyB;CAEtD,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IACE,OAAO,UAAU,aACjB,OAAO,UAAU,YACjB,OAAO,UAAU,UAEjB,OAAO;CACT,IAAI,OAAO,UAAU,UAAU,OAAO;CAGtC,IAAI,OAAO,UAAU,cAAc,OAAO,UAAU,UAAU,OAAO;CAGrE,IAAI,iBAAiB,QAAQ,iBAAiB,QAAQ,OAAO;CAC7D,IAAI,iBAAiB,eAAe,iBAAiB,UAAU,OAAO;CACtE,IAAI,iBAAiB,OAAO,iBAAiB,KAAK,OAAO;CACzD,IAAI,YAAY,OAAO,KAAK,GAAG,OAAO;CAGtC,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,OAAM,SAAQ,sBAAsB,IAAI,CAAC;CAGxD,IAAI,cAAc,KAAK,GACrB,OAAO,OAAO,OAAO,KAAK,CAAA,CAAE,OAAM,MAAK,sBAAsB,CAAC,CAAC;CAGjE,OAAO;AACT;AA6CO,SAAS,UAAa,OAAU,UAA4B,CAAC,GAAM;CACxE,MAAM,EACJ,oBAAoB,wBAAwB,MAC5C,iBAAiB,OACjB,eAAe,OACf,WAAW,UACX,iBACE;CAGJ,IACE,yBACA,OAAO,oBAAoB,cAC3B,sBAAsB,KAAK,GAE3B,IAAI;EACF,OAAO,gBAAgB,KAAK;CAC9B,QAAQ,CAER;CAGF,MAAM,wBAAQ,IAAI,QAAyB;CAE3C,SAAS,cAAiB,KAAQ,OAAkB;EAElD,IAAI,QAAQ,QAAQ,QAAQ,KAAA,GAAW,OAAO;EAC9C,IACE,OAAO,QAAQ,aACf,OAAO,QAAQ,YACf,OAAO,QAAQ,UAEf,OAAO;EACT,IAAI,OAAO,QAAQ,UAAU,OAAO;EAGpC,IAAI,OAAO,QAAQ,UACjB,OAAO,eAAgB,OAAO,IAAI,WAAW,IAAU;EAIzD,IAAI,OAAO,QAAQ,YACjB,OAAO,iBAAkB,IAAI,KAAK,CAAC,CAAC,IAAU;EAIhD,IAAI,QAAQ,UACV,OAAO;EAIT,IAAI,cAAc;GAChB,MAAM,eAAe,aAAa,MAAK,MAAK,cAAc,GAAG,QAAQ,CAAC,CAAC;GACvE,IAAI,iBAAiB,KAAA,GACnB,OAAO;EAEX;EAGA,IAAI,OAAO,QAAQ,YAAY,QAAQ;OACjC,MAAM,IAAI,GAAG,GACf,OAAO,MAAM,IAAI,GAAG;EAAA;EAKxB,IAAI,eAAe,MACjB,OAAO,IAAI,KAAK,IAAI,QAAQ,CAAC;EAI/B,IAAI,eAAe,QAAQ;GACzB,MAAM,SAAS,IAAI,OAAO,IAAI,QAAQ,IAAI,KAAK;GAC7C,OAAkB,YAAY,IAAI;GACpC,OAAO;EACT;EAGA,IAAI,eAAe,OAAO;GACxB,MAAM,SAAS,IAAK,IAAI,YAAiC,IAAI,OAAO;GACpE,OAAO,QAAQ,IAAI;GACnB,OAAO,OAAO,IAAI;GAClB,OAAO;EACT;EAGA,IAAI,eAAe,KAAK;GACtB,MAAM,yBAAS,IAAI,IAAI;GACvB,MAAM,IAAI,KAAK,MAAM;GACrB,IAAI,SAAS,GAAG,MAAM;IACpB,OAAO,IAAI,cAAc,GAAG,QAAQ,CAAC,GAAG,cAAc,GAAG,QAAQ,CAAC,CAAC;GACrE,CAAC;GACD,OAAO;EACT;EAGA,IAAI,eAAe,KAAK;GACtB,MAAM,yBAAS,IAAI,IAAI;GACvB,MAAM,IAAI,KAAK,MAAM;GACrB,IAAI,SAAQ,MAAK;IACf,OAAO,IAAI,cAAc,GAAG,QAAQ,CAAC,CAAC;GACxC,CAAC;GACD,OAAO;EACT;EAGA,IAAI,eAAe,aACjB,OAAO,IAAI,MAAM,CAAC;EAIpB,IAAI,YAAY,OAAO,GAAG,KAAK,EAAE,eAAe,WAAW;GACzD,MAAM,wBAAwB,IAAI;GAGlC,OAAO,IAAI,sBACR,IAA2C,OAAO,MAAM,CAAC,CAC5D;EACF;EAGA,IAAI,MAAM,QAAQ,GAAG,GAAG;GACtB,MAAM,SAAoB,CAAC;GAC3B,MAAM,IAAI,KAAK,MAAM;GACrB,KAAA,IAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAC9B,OAAO,KAAK,cAAc,IAAI,IAAI,QAAQ,CAAC;GAE7C,OAAO;EACT;EAGA,IAAI,cAAc,GAAG,GAAG;GACtB,MAAM,SAA2C,CAAC;GAClD,MAAM,IAAI,KAAK,MAAM;GAGrB,MAAM,OAAO,OAAO,KAAK,GAAG;GAC5B,KAAA,MAAW,OAAO,MAChB,OAAO,OAAO,cACX,IAAgC,MACjC,QAAQ,CACV;GAIF,IAAI,cAAc;IAChB,MAAM,aAAa,OAAO,sBAAsB,GAAG;IACnD,KAAA,MAAW,OAAO,YAChB,OAAO,OAAO,cACX,IAAgC,MACjC,QAAQ,CACV;GAEJ;GAEA,OAAO;EACT;EAGA,OAAO;CACT;CAEA,OAAO,cAAc,OAAO,CAAC;AAC/B;AAiBO,SAAS,aAAgB,OAAa;CAC3C,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO;CAEtC,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,CAAC,GAAG,KAAK;CAGlB,IAAI,iBAAiB,KACnB,OAAO,IAAI,IAAI,KAAK;CAGtB,IAAI,iBAAiB,KACnB,OAAO,IAAI,IAAI,KAAK;CAGtB,IAAI,iBAAiB,MACnB,OAAO,IAAI,KAAK,MAAM,QAAQ,CAAC;CAGjC,OAAO,EAAE,GAAG,MAAM;AACpB;AAgCO,SAAS,UACd,QAAA,GACG,SACA;CACH,OAAO,qBAAqB,QAAQ,CAAC,GAAG,GAAG,OAAO;AACpD;AAWO,SAAS,qBACd,QACA,SAAA,GACG,SACA;CACH,MAAM,EACJ,gBAAgB,WAChB,QAAQ,MACR,WAAW,aACT;CAEJ,SAAS,cACP,WACA,WACA,OACyB;EACzB,IAAI,QAAQ,UACV,OAAO;EAGT,KAAA,MAAW,OAAO,OAAO,KAAK,SAAS,GAAG;GACxC,MAAM,cAAc,UAAU;GAC9B,MAAM,cAAc,UAAU;GAG9B,IAAI,MAAM,QAAQ,WAAW,GAC3B,IAAI,kBAAkB,YAAY,MAAM,QAAQ,WAAW,GACzD,UAAU,OAAO,CAAC,GAAG,aAAa,GAAG,WAAW;QAClD,IAAW,kBAAkB,WAAW,MAAM,QAAQ,WAAW,GAAG;IAClE,MAAMA,UAAS,CAAC,GAAG,WAAW;IAC9B,YAAY,SAAS,MAAM,UAAU;KACnC,IAAI,cAAc,IAAI,KAAK,cAAcA,QAAO,MAAM,GACpDA,QAAO,SAAS,cACdA,QAAO,QACP,MACA,QAAQ,CACV;UAEAA,QAAO,SAAS,QAAQ,UAAU,IAAI,IAAI;IAE9C,CAAC;IACD,UAAU,OAAOA;GACnB,OACE,UAAU,OAAO,QAAQ,UAAU,WAAW,IAAI;QAEtD,IAES,cAAc,WAAW,GAChC,IAAI,cAAc,WAAW,GAC3B,UAAU,OAAO,cACf,aACA,aACA,QAAQ,CACV;QAEA,UAAU,OAAO,QAAQ,UAAU,WAAW,IAAI;QAKpD,UAAU,OACR,SAAS,SAAS,WAAW,IAAI,UAAU,WAAW,IAAI;EAEhE;EAEA,OAAO;CACT;CAEA,IAAI,SAAS;CAEb,KAAA,MAAW,UAAU,SACnB,IAAI,WAAW,QAAQ,WAAW,KAAA,GAChC,SAAS,cAAc,QAAQ,QAAQ,CAAC;CAI5C,OAAO;AACT;AAgBO,SAAS,UAAU,GAAY,GAAqB;CAEzD,IAAI,MAAM,GAAG,OAAO;CAGpB,IAAI,MAAM,QAAQ,MAAM,QAAQ,MAAM,KAAA,KAAa,MAAM,KAAA,GACvD,OAAO,MAAM;CAIf,IAAI,OAAO,MAAM,OAAO,GAAG,OAAO;CAGlC,IAAI,OAAO,MAAM,UAAU,OAAO,MAAM;CAGxC,IAAI,aAAa,QAAQ,aAAa,MACpC,OAAO,EAAE,QAAQ,MAAM,EAAE,QAAQ;CAInC,IAAI,aAAa,UAAU,aAAa,QACtC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE;CAIhD,IAAI,aAAa,OAAO,aAAa,KAAK;EACxC,IAAI,EAAE,SAAS,EAAE,MAAM,OAAO;EAC9B,KAAA,MAAW,CAAC,KAAK,UAAU,GACzB,IAAI,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,UAAU,OAAO,EAAE,IAAI,GAAG,CAAC,GAC7C,OAAO;EAGX,OAAO;CACT;CAGA,IAAI,aAAa,OAAO,aAAa,KAAK;EACxC,IAAI,EAAE,SAAS,EAAE,MAAM,OAAO;EAC9B,KAAA,MAAW,SAAS,GAClB,IAAI,CAAC,EAAE,IAAI,KAAK,GAAG,OAAO;EAE5B,OAAO;CACT;CAGA,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;EACxC,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;EAClC,KAAA,IAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAC5B,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO;EAErC,OAAO;CACT;CAGA,IAAI,cAAc,CAAC,KAAK,cAAc,CAAC,GAAG;EACxC,MAAM,QAAQ,OAAO,KAAK,CAAC;EAC3B,MAAM,QAAQ,OAAO,KAAK,CAAC;EAC3B,IAAI,MAAM,WAAW,MAAM,QAAQ,OAAO;EAC1C,KAAA,MAAW,OAAO,OAAO;GACvB,IAAI,CAAC,UAAU,GAAG,GAAG,GAAG,OAAO;GAC/B,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO;EACzC;EACA,OAAO;CACT;CAEA,OAAO;AACT;AASO,SAAS,WAA6B,KAAqB;CAChE,MAAM,YAAY,OAAO,oBAAoB,GAAG;CAEhD,KAAA,MAAW,QAAQ,WAAW;EAC5B,MAAM,QAAS,IAAgC;EAC/C,IAAI,SAAS,OAAO,UAAU,UAC5B,WAAW,KAAK;CAEpB;CAEA,OAAO,OAAO,OAAO,GAAG;AAC1B"}
|
package/lib/utils/index.cjs
CHANGED
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
* 提供深拷贝、选择器、路径操作等工具函数
|
|
5
5
|
* @module utils
|
|
6
6
|
*/
|
|
7
|
-
export { debounce, throttle
|
|
8
|
-
export type { DebouncedFunction, ThrottledFunction
|
|
7
|
+
export { debounce, throttle } from './debounce-throttle';
|
|
8
|
+
export type { DebouncedFunction, ThrottledFunction } from './debounce-throttle';
|
|
9
9
|
export { deepClone, deepEqual, deepFreeze, deepMerge, deepMergeWithOptions, isObject, isPlainObject, shallowClone, } from './deep-clone';
|
|
10
|
-
export type { DeepCloneOptions, DeepMergeOptions
|
|
10
|
+
export type { DeepCloneOptions, DeepMergeOptions } from './deep-clone';
|
|
11
11
|
export { combineSelectors, createCachedSelector, createMemoizedSelector, createSelector, createSelectorWithDeps, deleteByPath, getByPath, hasPath, setByPath, } from './selector';
|
|
12
|
-
export type { MemoizedSelectorOptions, SelectorEqualityFn
|
|
13
|
-
//# sourceMappingURL=index.d.ts.map
|
|
12
|
+
export type { MemoizedSelectorOptions, SelectorEqualityFn } from './selector';
|
package/lib/utils/selector.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selector.cjs","names":[],"sources":["../../src/utils/selector.ts"],"sourcesContent":["/**\n * 状态选择器工具\n *\n * 提供高性能的状态选择器和路径操作工具\n * @module utils/selector\n */\n\nimport type { Selector, StateTree } from '../types'\n\nconst ARRAY_INDEX_RE = /^\\d+$/\n\n/**\n * 选择器相等性比较函数类型\n */\nexport type SelectorEqualityFn<R> = (a: R, b: R) => boolean\n\n/**\n * 记忆化选择器配置选项\n */\nexport interface MemoizedSelectorOptions<R> {\n /** 相等性比较函数 */\n equalityFn?: SelectorEqualityFn<R>\n /** 最大缓存大小(默认 1) */\n maxSize?: number\n /** 是否在开发模式下记录缓存命中率 */\n trackHitRate?: boolean\n}\n\n/**\n * 创建记忆化选择器\n *\n * 基本的记忆化选择器,只缓存最后一次结果\n *\n * @template S - 状态类型\n * @template R - 返回值类型\n * @param selector - 选择器函数\n * @param equalityFn - 相等性比较函数(默认使用 Object.is)\n * @returns 记忆化的选择器\n *\n * @example\n * ```typescript\n * const selectTodos = createSelector(\n * (state: AppState) => state.todos,\n * )\n *\n * const selectCompletedTodos = createSelector(\n * (state: AppState) => state.todos.filter(t => t.completed),\n * (a, b) => a.length === b.length && a.every((v, i) => v === b[i])\n * )\n * ```\n */\nexport function createSelector<S extends StateTree, R>(\n selector: Selector<S, R>,\n equalityFn: SelectorEqualityFn<R> = Object.is\n): Selector<S, R> {\n let lastState: S | undefined\n let lastResult: R | undefined\n let initialized = false\n\n return (state: S): R => {\n // 如果状态引用未变,直接返回缓存结果\n if (initialized && lastState === state) {\n return lastResult as R\n }\n\n const result = selector(state)\n\n // 检查结果是否改变\n if (!initialized || !equalityFn(result, lastResult as R)) {\n lastResult = result\n }\n\n lastState = state\n initialized = true\n\n return lastResult as R\n }\n}\n\n/**\n * 创建带依赖的选择器\n *\n * 类似 reselect 的实现,支持多个输入选择器\n *\n * @template S - 状态类型\n * @template Deps - 依赖结果类型\n * @template R - 返回值类型\n * @param dependencies - 依赖选择器数组\n * @param combiner - 组合函数\n * @param options - 配置选项\n * @returns 记忆化的选择器\n *\n * @example\n * ```typescript\n * const selectVisibleTodos = createSelectorWithDeps(\n * [\n * (state) => state.todos,\n * (state) => state.visibilityFilter,\n * ],\n * (todos, filter) => {\n * switch (filter) {\n * case 'SHOW_COMPLETED': return todos.filter(t => t.completed)\n * case 'SHOW_ACTIVE': return todos.filter(t => !t.completed)\n * default: return todos\n * }\n * }\n * )\n * ```\n */\nexport function createSelectorWithDeps<\n S extends StateTree,\n Deps extends unknown[],\n R,\n>(\n dependencies: { [K in keyof Deps]: Selector<S, Deps[K]> },\n combiner: (...args: Deps) => R,\n options: MemoizedSelectorOptions<R> = {}\n): Selector<S, R> {\n const { equalityFn = Object.is, trackHitRate = false } = options\n\n let lastDeps: Deps | undefined\n let lastResult: R | undefined\n let initialized = false\n\n // 缓存统计(仅开发模式)\n let hits = 0\n let calls = 0\n\n const selector = (state: S): R => {\n if (trackHitRate) calls++\n\n // 计算所有依赖的结果\n const deps = dependencies.map(dep => dep(state)) as Deps\n\n // 检查依赖是否改变\n if (initialized && lastDeps) {\n let changed = false\n for (let i = 0; i < deps.length; i++) {\n if (!Object.is(deps[i], lastDeps[i])) {\n changed = true\n break\n }\n }\n\n if (!changed) {\n if (trackHitRate) hits++\n return lastResult as R\n }\n }\n\n // 计算新结果\n const result = combiner(...deps)\n\n // 检查结果是否改变\n if (!initialized || !equalityFn(result, lastResult as R)) {\n lastResult = result\n }\n\n lastDeps = deps\n initialized = true\n\n return lastResult as R\n }\n\n // 添加缓存统计方法\n if (trackHitRate) {\n ;(selector as Selector<S, R> & { getHitRate: () => number }).getHitRate =\n () => {\n return calls > 0 ? hits / calls : 0\n }\n }\n\n return selector\n}\n\n/**\n * 组合多个选择器\n *\n * 简单的选择器组合,不带记忆化\n *\n * @template S - 状态类型\n * @template R - 结果类型数组\n * @template C - 组合结果类型\n * @param selectors - 选择器数组\n * @param combiner - 组合函数\n * @returns 组合后的选择器\n *\n * @example\n * ```typescript\n * const selectUserAndTodos = combineSelectors(\n * [\n * (state) => state.user,\n * (state) => state.todos,\n * ],\n * (user, todos) => ({ user, todos })\n * )\n * ```\n */\nexport function combineSelectors<S extends StateTree, R extends unknown[], C>(\n selectors: { [K in keyof R]: Selector<S, R[K]> },\n combiner: (...results: R) => C\n): Selector<S, C> {\n return (state: S): C => {\n const results = selectors.map(selector => selector(state)) as R\n return combiner(...results)\n }\n}\n\n/**\n * 创建带高级缓存的选择器\n *\n * 支持多个缓存条目,使用 LRU 策略\n *\n * @template S - 状态类型\n * @template R - 返回值类型\n * @param selector - 选择器函数\n * @param options - 配置选项\n * @returns 带缓存的选择器\n *\n * @example\n * ```typescript\n * const selectFilteredItems = createCachedSelector(\n * (state, filter) => state.items.filter(item => item.type === filter),\n * { maxSize: 5 }\n * )\n * ```\n */\nexport function createCachedSelector<S extends StateTree, R>(\n selector: Selector<S, R>,\n options: MemoizedSelectorOptions<R> = {}\n): Selector<S, R> & { clearCache: () => void; getCacheSize: () => number } {\n const { maxSize = 10 } = options\n\n // 使用 Map 保持插入顺序(LRU 策略)\n const cache = new Map<S, R>()\n\n const memoizedSelector = (state: S): R => {\n // 检查缓存\n if (cache.has(state)) {\n const cached = cache.get(state) as R\n // 移到末尾(最近使用)\n cache.delete(state)\n cache.set(state, cached)\n return cached\n }\n\n // 计算结果\n const result = selector(state)\n\n // 管理缓存大小(LRU 淘汰)\n if (cache.size >= maxSize) {\n const firstKey = cache.keys().next().value\n if (firstKey !== undefined) {\n cache.delete(firstKey)\n }\n }\n\n cache.set(state, result)\n return result\n }\n\n // 添加缓存管理方法\n memoizedSelector.clearCache = () => cache.clear()\n memoizedSelector.getCacheSize = () => cache.size\n\n return memoizedSelector\n}\n\n/**\n * 创建记忆化选择器(别名,同 createSelector)\n *\n * @template S - 状态类型\n * @template R - 返回值类型\n * @param selector - 选择器函数\n * @param options - 配置选项\n * @returns 记忆化的选择器\n */\nexport function createMemoizedSelector<S extends StateTree, R>(\n selector: Selector<S, R>,\n options: MemoizedSelectorOptions<R> = {}\n): Selector<S, R> {\n return createSelector(selector, options.equalityFn)\n}\n\n/**\n * 获取嵌套对象的值\n *\n * 支持点表示法和数组索引\n *\n * @template T - 返回值类型\n * @param obj - 对象\n * @param path - 路径(支持 'a.b.c' 或 'a[0].b')\n * @param defaultValue - 默认值(当路径不存在时返回)\n * @returns 值\n *\n * @example\n * ```typescript\n * const value = getByPath({ a: { b: { c: 1 } } }, 'a.b.c')\n * // value: 1\n *\n * const arr = getByPath({ items: [{ name: 'test' }] }, 'items[0].name')\n * // arr: 'test'\n *\n * const missing = getByPath({ a: 1 }, 'b.c', 'default')\n * // missing: 'default'\n * ```\n */\nexport function getByPath<T = unknown>(\n obj: unknown,\n path: string,\n defaultValue?: T\n): T | undefined {\n if (!path || path.length === 0) {\n return obj as T\n }\n\n // 解析路径(支持 'a.b.c' 和 'a[0].b')\n const keys = path\n .replace(/\\[([^\\]]+)\\]/g, '.$1') // 将 [0] 转换为 .0\n .split('.')\n .filter(Boolean)\n\n let result: unknown = obj\n\n for (const key of keys) {\n if (result === null || result === undefined) {\n return defaultValue\n }\n\n if (typeof result !== 'object') {\n return defaultValue\n }\n\n result = (result as Record<string, unknown>)[key]\n }\n\n return result === undefined ? defaultValue : (result as T)\n}\n\n/**\n * 设置嵌套对象的值\n *\n * 支持自动创建中间路径\n *\n * @param obj - 对象\n * @param path - 路径\n * @param value - 值\n * @returns 是否成功\n *\n * @example\n * ```typescript\n * const obj = {}\n * setByPath(obj, 'a.b.c', 1)\n * // obj: { a: { b: { c: 1 } } }\n *\n * setByPath(obj, 'items[0].name', 'test')\n * // obj: { a: { b: { c: 1 } }, items: [{ name: 'test' }] }\n * ```\n */\nexport function setByPath(\n obj: Record<string, unknown>,\n path: string,\n value: unknown\n): boolean {\n if (!path || path.length === 0) {\n return false\n }\n\n // 解析路径\n const keys = path\n .replace(/\\[([^\\]]+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean)\n\n let current: Record<string, unknown> = obj\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i]\n const nextKey = keys[i + 1] ?? ''\n\n const nextValue = current[key] ?? (ARRAY_INDEX_RE.test(nextKey) ? [] : {})\n // 根据下一个键决定创建对象还是数组\n current[key] = nextValue\n current = current[key] as Record<string, unknown>\n }\n\n const lastKey = keys[keys.length - 1]\n current[lastKey] = value\n return true\n}\n\n/**\n * 删除嵌套对象的值\n *\n * @param obj - 对象\n * @param path - 路径\n * @returns 是否成功删除\n *\n * @example\n * ```typescript\n * const obj = { a: { b: { c: 1 } } }\n * deleteByPath(obj, 'a.b.c')\n * // obj: { a: { b: {} } }\n * ```\n */\nexport function deleteByPath(\n obj: Record<string, unknown>,\n path: string\n): boolean {\n if (!path || path.length === 0) {\n return false\n }\n\n const keys = path\n .replace(/\\[([^\\]]+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean)\n\n let current: Record<string, unknown> = obj\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i]\n if (current[key] === undefined || current[key] === null) {\n return false\n }\n current = current[key] as Record<string, unknown>\n }\n\n const lastKey = keys[keys.length - 1]\n if (lastKey in current) {\n if (Array.isArray(current)) {\n const index = Number.parseInt(lastKey, 10)\n if (!Number.isNaN(index)) {\n current.splice(index, 1)\n return true\n }\n }\n delete current[lastKey]\n return true\n }\n\n return false\n}\n\n/**\n * 检查嵌套对象中是否存在指定路径\n *\n * @param obj - 对象\n * @param path - 路径\n * @returns 是否存在\n *\n * @example\n * ```typescript\n * hasPath({ a: { b: 1 } }, 'a.b') // true\n * hasPath({ a: { b: 1 } }, 'a.c') // false\n * ```\n */\nexport function hasPath(obj: unknown, path: string): boolean {\n if (!path || path.length === 0) {\n return true\n }\n\n const keys = path\n .replace(/\\[([^\\]]+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean)\n\n let current: unknown = obj\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return false\n }\n\n if (typeof current !== 'object') {\n return false\n }\n\n if (!(key in (current as Record<string, unknown>))) {\n return false\n }\n\n current = (current as Record<string, unknown>)[key]\n }\n\n return true\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selector.cjs","names":[],"sources":["../../src/utils/selector.ts"],"sourcesContent":["/**\r\n * 状态选择器工具\r\n *\r\n * 提供高性能的状态选择器和路径操作工具\r\n * @module utils/selector\r\n */\r\n\r\nimport type { Selector, StateTree } from '../types'\r\n\r\nconst ARRAY_INDEX_RE = /^\\d+$/\r\n\r\n/**\r\n * 选择器相等性比较函数类型\r\n */\r\nexport type SelectorEqualityFn<R> = (a: R, b: R) => boolean\r\n\r\n/**\r\n * 记忆化选择器配置选项\r\n */\r\nexport interface MemoizedSelectorOptions<R> {\r\n /** 相等性比较函数 */\r\n equalityFn?: SelectorEqualityFn<R>\r\n /** 最大缓存大小(默认 1) */\r\n maxSize?: number\r\n /** 是否在开发模式下记录缓存命中率 */\r\n trackHitRate?: boolean\r\n}\r\n\r\n/**\r\n * 创建记忆化选择器\r\n *\r\n * 基本的记忆化选择器,只缓存最后一次结果\r\n *\r\n * @template S - 状态类型\r\n * @template R - 返回值类型\r\n * @param selector - 选择器函数\r\n * @param equalityFn - 相等性比较函数(默认使用 Object.is)\r\n * @returns 记忆化的选择器\r\n *\r\n * @example\r\n * ```typescript\r\n * const selectTodos = createSelector(\r\n * (state: AppState) => state.todos,\r\n * )\r\n *\r\n * const selectCompletedTodos = createSelector(\r\n * (state: AppState) => state.todos.filter(t => t.completed),\r\n * (a, b) => a.length === b.length && a.every((v, i) => v === b[i])\r\n * )\r\n * ```\r\n */\r\nexport function createSelector<S extends StateTree, R>(\r\n selector: Selector<S, R>,\r\n equalityFn: SelectorEqualityFn<R> = Object.is\r\n): Selector<S, R> {\r\n let lastState: S | undefined\r\n let lastResult: R | undefined\r\n let initialized = false\r\n\r\n return (state: S): R => {\r\n // 如果状态引用未变,直接返回缓存结果\r\n if (initialized && lastState === state) {\r\n return lastResult as R\r\n }\r\n\r\n const result = selector(state)\r\n\r\n // 检查结果是否改变\r\n if (!initialized || !equalityFn(result, lastResult as R)) {\r\n lastResult = result\r\n }\r\n\r\n lastState = state\r\n initialized = true\r\n\r\n return lastResult as R\r\n }\r\n}\r\n\r\n/**\r\n * 创建带依赖的选择器\r\n *\r\n * 类似 reselect 的实现,支持多个输入选择器\r\n *\r\n * @template S - 状态类型\r\n * @template Deps - 依赖结果类型\r\n * @template R - 返回值类型\r\n * @param dependencies - 依赖选择器数组\r\n * @param combiner - 组合函数\r\n * @param options - 配置选项\r\n * @returns 记忆化的选择器\r\n *\r\n * @example\r\n * ```typescript\r\n * const selectVisibleTodos = createSelectorWithDeps(\r\n * [\r\n * (state) => state.todos,\r\n * (state) => state.visibilityFilter,\r\n * ],\r\n * (todos, filter) => {\r\n * switch (filter) {\r\n * case 'SHOW_COMPLETED': return todos.filter(t => t.completed)\r\n * case 'SHOW_ACTIVE': return todos.filter(t => !t.completed)\r\n * default: return todos\r\n * }\r\n * }\r\n * )\r\n * ```\r\n */\r\nexport function createSelectorWithDeps<\r\n S extends StateTree,\r\n Deps extends unknown[],\r\n R,\r\n>(\r\n dependencies: { [K in keyof Deps]: Selector<S, Deps[K]> },\r\n combiner: (...args: Deps) => R,\r\n options: MemoizedSelectorOptions<R> = {}\r\n): Selector<S, R> {\r\n const { equalityFn = Object.is, trackHitRate = false } = options\r\n\r\n let lastDeps: Deps | undefined\r\n let lastResult: R | undefined\r\n let initialized = false\r\n\r\n // 缓存统计(仅开发模式)\r\n let hits = 0\r\n let calls = 0\r\n\r\n const selector = (state: S): R => {\r\n if (trackHitRate) calls++\r\n\r\n // 计算所有依赖的结果\r\n const deps = dependencies.map(dep => dep(state)) as Deps\r\n\r\n // 检查依赖是否改变\r\n if (initialized && lastDeps) {\r\n let changed = false\r\n for (let i = 0; i < deps.length; i++) {\r\n if (!Object.is(deps[i], lastDeps[i])) {\r\n changed = true\r\n break\r\n }\r\n }\r\n\r\n if (!changed) {\r\n if (trackHitRate) hits++\r\n return lastResult as R\r\n }\r\n }\r\n\r\n // 计算新结果\r\n const result = combiner(...deps)\r\n\r\n // 检查结果是否改变\r\n if (!initialized || !equalityFn(result, lastResult as R)) {\r\n lastResult = result\r\n }\r\n\r\n lastDeps = deps\r\n initialized = true\r\n\r\n return lastResult as R\r\n }\r\n\r\n // 添加缓存统计方法\r\n if (trackHitRate) {\r\n ;(selector as Selector<S, R> & { getHitRate: () => number }).getHitRate =\r\n () => {\r\n return calls > 0 ? hits / calls : 0\r\n }\r\n }\r\n\r\n return selector\r\n}\r\n\r\n/**\r\n * 组合多个选择器\r\n *\r\n * 简单的选择器组合,不带记忆化\r\n *\r\n * @template S - 状态类型\r\n * @template R - 结果类型数组\r\n * @template C - 组合结果类型\r\n * @param selectors - 选择器数组\r\n * @param combiner - 组合函数\r\n * @returns 组合后的选择器\r\n *\r\n * @example\r\n * ```typescript\r\n * const selectUserAndTodos = combineSelectors(\r\n * [\r\n * (state) => state.user,\r\n * (state) => state.todos,\r\n * ],\r\n * (user, todos) => ({ user, todos })\r\n * )\r\n * ```\r\n */\r\nexport function combineSelectors<S extends StateTree, R extends unknown[], C>(\r\n selectors: { [K in keyof R]: Selector<S, R[K]> },\r\n combiner: (...results: R) => C\r\n): Selector<S, C> {\r\n return (state: S): C => {\r\n const results = selectors.map(selector => selector(state)) as R\r\n return combiner(...results)\r\n }\r\n}\r\n\r\n/**\r\n * 创建带高级缓存的选择器\r\n *\r\n * 支持多个缓存条目,使用 LRU 策略\r\n *\r\n * @template S - 状态类型\r\n * @template R - 返回值类型\r\n * @param selector - 选择器函数\r\n * @param options - 配置选项\r\n * @returns 带缓存的选择器\r\n *\r\n * @example\r\n * ```typescript\r\n * const selectFilteredItems = createCachedSelector(\r\n * (state, filter) => state.items.filter(item => item.type === filter),\r\n * { maxSize: 5 }\r\n * )\r\n * ```\r\n */\r\nexport function createCachedSelector<S extends StateTree, R>(\r\n selector: Selector<S, R>,\r\n options: MemoizedSelectorOptions<R> = {}\r\n): Selector<S, R> & { clearCache: () => void; getCacheSize: () => number } {\r\n const { maxSize = 10 } = options\r\n\r\n // 使用 Map 保持插入顺序(LRU 策略)\r\n const cache = new Map<S, R>()\r\n\r\n const memoizedSelector = (state: S): R => {\r\n // 检查缓存\r\n if (cache.has(state)) {\r\n const cached = cache.get(state) as R\r\n // 移到末尾(最近使用)\r\n cache.delete(state)\r\n cache.set(state, cached)\r\n return cached\r\n }\r\n\r\n // 计算结果\r\n const result = selector(state)\r\n\r\n // 管理缓存大小(LRU 淘汰)\r\n if (cache.size >= maxSize) {\r\n const firstKey = cache.keys().next().value\r\n if (firstKey !== undefined) {\r\n cache.delete(firstKey)\r\n }\r\n }\r\n\r\n cache.set(state, result)\r\n return result\r\n }\r\n\r\n // 添加缓存管理方法\r\n memoizedSelector.clearCache = () => cache.clear()\r\n memoizedSelector.getCacheSize = () => cache.size\r\n\r\n return memoizedSelector\r\n}\r\n\r\n/**\r\n * 创建记忆化选择器(别名,同 createSelector)\r\n *\r\n * @template S - 状态类型\r\n * @template R - 返回值类型\r\n * @param selector - 选择器函数\r\n * @param options - 配置选项\r\n * @returns 记忆化的选择器\r\n */\r\nexport function createMemoizedSelector<S extends StateTree, R>(\r\n selector: Selector<S, R>,\r\n options: MemoizedSelectorOptions<R> = {}\r\n): Selector<S, R> {\r\n return createSelector(selector, options.equalityFn)\r\n}\r\n\r\n/**\r\n * 获取嵌套对象的值\r\n *\r\n * 支持点表示法和数组索引\r\n *\r\n * @template T - 返回值类型\r\n * @param obj - 对象\r\n * @param path - 路径(支持 'a.b.c' 或 'a[0].b')\r\n * @param defaultValue - 默认值(当路径不存在时返回)\r\n * @returns 值\r\n *\r\n * @example\r\n * ```typescript\r\n * const value = getByPath({ a: { b: { c: 1 } } }, 'a.b.c')\r\n * // value: 1\r\n *\r\n * const arr = getByPath({ items: [{ name: 'test' }] }, 'items[0].name')\r\n * // arr: 'test'\r\n *\r\n * const missing = getByPath({ a: 1 }, 'b.c', 'default')\r\n * // missing: 'default'\r\n * ```\r\n */\r\nexport function getByPath<T = unknown>(\r\n obj: unknown,\r\n path: string,\r\n defaultValue?: T\r\n): T | undefined {\r\n if (!path || path.length === 0) {\r\n return obj as T\r\n }\r\n\r\n // 解析路径(支持 'a.b.c' 和 'a[0].b')\r\n const keys = path\r\n .replace(/\\[([^\\]]+)\\]/g, '.$1') // 将 [0] 转换为 .0\r\n .split('.')\r\n .filter(Boolean)\r\n\r\n let result: unknown = obj\r\n\r\n for (const key of keys) {\r\n if (result === null || result === undefined) {\r\n return defaultValue\r\n }\r\n\r\n if (typeof result !== 'object') {\r\n return defaultValue\r\n }\r\n\r\n result = (result as Record<string, unknown>)[key]\r\n }\r\n\r\n return result === undefined ? defaultValue : (result as T)\r\n}\r\n\r\n/**\r\n * 设置嵌套对象的值\r\n *\r\n * 支持自动创建中间路径\r\n *\r\n * @param obj - 对象\r\n * @param path - 路径\r\n * @param value - 值\r\n * @returns 是否成功\r\n *\r\n * @example\r\n * ```typescript\r\n * const obj = {}\r\n * setByPath(obj, 'a.b.c', 1)\r\n * // obj: { a: { b: { c: 1 } } }\r\n *\r\n * setByPath(obj, 'items[0].name', 'test')\r\n * // obj: { a: { b: { c: 1 } }, items: [{ name: 'test' }] }\r\n * ```\r\n */\r\nexport function setByPath(\r\n obj: Record<string, unknown>,\r\n path: string,\r\n value: unknown\r\n): boolean {\r\n if (!path || path.length === 0) {\r\n return false\r\n }\r\n\r\n // 解析路径\r\n const keys = path\r\n .replace(/\\[([^\\]]+)\\]/g, '.$1')\r\n .split('.')\r\n .filter(Boolean)\r\n\r\n let current: Record<string, unknown> = obj\r\n\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i]\r\n const nextKey = keys[i + 1] ?? ''\r\n\r\n const nextValue = current[key] ?? (ARRAY_INDEX_RE.test(nextKey) ? [] : {})\r\n // 根据下一个键决定创建对象还是数组\r\n current[key] = nextValue\r\n current = current[key] as Record<string, unknown>\r\n }\r\n\r\n const lastKey = keys[keys.length - 1]\r\n current[lastKey] = value\r\n return true\r\n}\r\n\r\n/**\r\n * 删除嵌套对象的值\r\n *\r\n * @param obj - 对象\r\n * @param path - 路径\r\n * @returns 是否成功删除\r\n *\r\n * @example\r\n * ```typescript\r\n * const obj = { a: { b: { c: 1 } } }\r\n * deleteByPath(obj, 'a.b.c')\r\n * // obj: { a: { b: {} } }\r\n * ```\r\n */\r\nexport function deleteByPath(\r\n obj: Record<string, unknown>,\r\n path: string\r\n): boolean {\r\n if (!path || path.length === 0) {\r\n return false\r\n }\r\n\r\n const keys = path\r\n .replace(/\\[([^\\]]+)\\]/g, '.$1')\r\n .split('.')\r\n .filter(Boolean)\r\n\r\n let current: Record<string, unknown> = obj\r\n\r\n for (let i = 0; i < keys.length - 1; i++) {\r\n const key = keys[i]\r\n if (current[key] === undefined || current[key] === null) {\r\n return false\r\n }\r\n current = current[key] as Record<string, unknown>\r\n }\r\n\r\n const lastKey = keys[keys.length - 1]\r\n if (lastKey in current) {\r\n if (Array.isArray(current)) {\r\n const index = Number.parseInt(lastKey, 10)\r\n if (!Number.isNaN(index)) {\r\n current.splice(index, 1)\r\n return true\r\n }\r\n }\r\n delete current[lastKey]\r\n return true\r\n }\r\n\r\n return false\r\n}\r\n\r\n/**\r\n * 检查嵌套对象中是否存在指定路径\r\n *\r\n * @param obj - 对象\r\n * @param path - 路径\r\n * @returns 是否存在\r\n *\r\n * @example\r\n * ```typescript\r\n * hasPath({ a: { b: 1 } }, 'a.b') // true\r\n * hasPath({ a: { b: 1 } }, 'a.c') // false\r\n * ```\r\n */\r\nexport function hasPath(obj: unknown, path: string): boolean {\r\n if (!path || path.length === 0) {\r\n return true\r\n }\r\n\r\n const keys = path\r\n .replace(/\\[([^\\]]+)\\]/g, '.$1')\r\n .split('.')\r\n .filter(Boolean)\r\n\r\n let current: unknown = obj\r\n\r\n for (const key of keys) {\r\n if (current === null || current === undefined) {\r\n return false\r\n }\r\n\r\n if (typeof current !== 'object') {\r\n return false\r\n }\r\n\r\n if (!(key in (current as Record<string, unknown>))) {\r\n return false\r\n }\r\n\r\n current = (current as Record<string, unknown>)[key]\r\n }\r\n\r\n return true\r\n}\r\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@composy/store-core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "框架无关的状态管理核心库 - 提供状态管理抽象层、插件系统、中间件机制",
|
|
6
6
|
"author": "ldesign",
|
|
7
7
|
"license": "MIT",
|
|
@@ -127,28 +127,31 @@
|
|
|
127
127
|
"build:watch": "ldesign-builder build --watch",
|
|
128
128
|
"clean": "rimraf es esm lib dist",
|
|
129
129
|
"dev": "ldesign-builder build --watch",
|
|
130
|
-
"lint": "eslint . --
|
|
131
|
-
"lint:check": "eslint .",
|
|
132
|
-
"lint:fix": "eslint . --fix",
|
|
130
|
+
"lint": "eslint . --cache --max-warnings 0",
|
|
131
|
+
"lint:check": "eslint . --cache --max-warnings 0",
|
|
132
|
+
"lint:fix": "eslint . --cache --fix",
|
|
133
133
|
"test": "ltesting run:unit",
|
|
134
134
|
"test:coverage": "ltesting run:unit --coverage",
|
|
135
135
|
"test:run": "ltesting run:unit",
|
|
136
|
-
"type-check": "tsc --noEmit",
|
|
136
|
+
"type-check": "tsc -p .ldesign/tsconfig.json --noEmit",
|
|
137
137
|
"test:watch": "ltesting run:unit --watch",
|
|
138
138
|
"test:changed": "ltesting run:unit --changed",
|
|
139
139
|
"test:failed": "ltesting run:unit --failed",
|
|
140
|
-
"test:ui": "ltesting dashboard"
|
|
140
|
+
"test:ui": "ltesting dashboard",
|
|
141
|
+
"release": "ldesign-release publish --package-dir ."
|
|
141
142
|
},
|
|
142
143
|
"dependencies": {
|
|
143
|
-
"tslib": "
|
|
144
|
+
"tslib": "2.8.1"
|
|
144
145
|
},
|
|
145
146
|
"devDependencies": {
|
|
146
147
|
"@antfu/eslint-config": "9.1.0",
|
|
147
|
-
"@composy/builder": "^0.0
|
|
148
|
-
"@composy/testing": "^0.0.
|
|
149
|
-
"@types/node": "26.
|
|
148
|
+
"@composy/builder": "^0.1.0",
|
|
149
|
+
"@composy/testing": "^0.0.2",
|
|
150
|
+
"@types/node": "26.6.3",
|
|
151
|
+
"@vitest/coverage-v8": "4.1.10",
|
|
150
152
|
"eslint": "10.7.0",
|
|
151
|
-
"typescript": "5.9.3"
|
|
153
|
+
"typescript": "5.9.3",
|
|
154
|
+
"@composy/release": "^0.1.0"
|
|
152
155
|
},
|
|
153
156
|
"typings": "./es/index.d.ts",
|
|
154
157
|
"browser": "./dist/index.js"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"async-action.d.ts","sourceRoot":"","sources":["../../src/core/async-action.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kBAAkB;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,WAAW;IACX,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,WAAW;IACX,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,YAAY;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW;IACX,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa;IACb,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,IAAI,SAAS,OAAO,EAAE;IACpD,WAAW;IACX,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAA;IACnC,aAAa;IACb,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IACtC,WAAW;IACX,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,aAAa;IACb,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,aAAa;IACb,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,WAAW,CAAA;IAC1E,aAAa;IACb,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,KAAK,WAAW,CAAA;IACvD,aAAa;IACb,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,KAAK,WAAW,CAAA;CAC3D;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,SAAS,OAAO,EAAE,GAAG,EAAE,EAC9D,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACjC,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CA0ItB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-store.d.ts","sourceRoot":"","sources":["../../src/core/base-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,OAAO,EACP,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACZ,MAAM,UAAU,CAAA;AAgBjB;;;;;;;GAOG;AACH,qBAAa,SAAS,CACpB,EAAE,SAAS,OAAO,GAAG,OAAO,EAC5B,CAAC,SAAS,SAAS,GAAG,SAAS,EAC/B,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAC3C,CAAC,SAAS,YAAY,GAAG,YAAY,CACrC,YAAW,aAAa,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACrC,eAAe;IACf,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAA;IAEhB,kBAAkB;IAClB,QAAQ,CAAC,OAAO,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE,CAAA;IAEtD,kBAAkB;IAClB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IAEnB,cAAc;IACd,OAAO,CAAC,gBAAgB,CAA2D;IAEnF,mBAAmB;IACnB,OAAO,CAAC,iBAAiB,CAAmC;IAE5D,aAAa;IACb,OAAO,CAAC,mBAAmB,CAAS;IAEpC,WAAW;IACX,OAAO,CAAC,MAAM,CAAG;IAEjB,YAAY;IACZ,OAAO,CAAC,QAAQ,CAAQ;IAExB;;;;;OAKG;gBAED,UAAU,EAAE,eAAe,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACxC,QAAQ,GAAE,YAAiB;IAY7B;;OAEG;IACH,IAAI,MAAM,IAAI,CAAC,CAEd;IAED;;OAEG;IACH,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,EAErB;IAED;;OAEG;IACH,MAAM,IAAI,IAAI;IAYd;;OAEG;IACH,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,IAAI;IAuB7D;;OAEG;IACH,UAAU,CACR,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,EAC5B,OAAO,GAAE,gBAAqB,GAC7B,WAAW;IASd;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,WAAW;IAMrD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAUhB;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAS7D;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI;IAIvD;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,aAAa;CA+CtB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batch-manager.d.ts","sourceRoot":"","sources":["../../src/core/batch-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,GACzC,YAAY,CA4Ed;AAOD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,YAAY,CAKpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEjE;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEvC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-store.d.ts","sourceRoot":"","sources":["../../src/core/create-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/core/event-bus.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAoD,MAAM,UAAU,CAAA;AAE1F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,IAAI,QAAQ,CAiGzC;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,UAAmB,CAAA"}
|