@composy/store-core 0.0.1
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 +5 -0
- package/README.md +172 -0
- package/dist/index.js +1852 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +1082 -0
- package/dist/index.min.js.map +1 -0
- package/es/core/async-action.d.ts +95 -0
- package/es/core/async-action.d.ts.map +1 -0
- package/es/core/async-action.js +116 -0
- package/es/core/async-action.js.map +1 -0
- package/es/core/base-store.d.ts +85 -0
- package/es/core/base-store.d.ts.map +1 -0
- package/es/core/base-store.js +185 -0
- package/es/core/base-store.js.map +1 -0
- package/es/core/batch-manager.d.ts +46 -0
- package/es/core/batch-manager.d.ts.map +1 -0
- package/es/core/batch-manager.js +64 -0
- package/es/core/batch-manager.js.map +1 -0
- package/es/core/create-store.d.ts +66 -0
- package/es/core/create-store.d.ts.map +1 -0
- package/es/core/create-store.js +29 -0
- package/es/core/create-store.js.map +1 -0
- package/es/core/event-bus.d.ts +34 -0
- package/es/core/event-bus.d.ts.map +1 -0
- package/es/core/event-bus.js +71 -0
- package/es/core/event-bus.js.map +1 -0
- package/es/core/index.d.ts +14 -0
- package/es/core/index.d.ts.map +1 -0
- package/es/core/index.js +17 -0
- package/es/core/pub-sub.d.ts +41 -0
- package/es/core/pub-sub.d.ts.map +1 -0
- package/es/core/pub-sub.js +71 -0
- package/es/core/pub-sub.js.map +1 -0
- package/es/engine/index.d.ts +10 -0
- package/es/engine/index.d.ts.map +1 -0
- package/es/engine/index.js +12 -0
- package/es/engine/plugin.d.ts +20 -0
- package/es/engine/plugin.d.ts.map +1 -0
- package/es/engine/plugin.js +153 -0
- package/es/engine/plugin.js.map +1 -0
- package/es/engine/types.d.ts +81 -0
- package/es/engine/types.d.ts.map +1 -0
- package/es/engine/types.js +10 -0
- package/es/errors/index.d.ts +208 -0
- package/es/errors/index.d.ts.map +1 -0
- package/es/errors/index.js +217 -0
- package/es/errors/index.js.map +1 -0
- package/es/index.d.ts +27 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +34 -0
- package/es/index.js.map +1 -0
- package/es/middleware/index.d.ts +13 -0
- package/es/middleware/index.d.ts.map +1 -0
- package/es/middleware/index.js +16 -0
- package/es/middleware/logger.d.ts +67 -0
- package/es/middleware/logger.d.ts.map +1 -0
- package/es/middleware/logger.js +136 -0
- package/es/middleware/logger.js.map +1 -0
- package/es/middleware/middleware-manager.d.ts +40 -0
- package/es/middleware/middleware-manager.d.ts.map +1 -0
- package/es/middleware/middleware-manager.js +79 -0
- package/es/middleware/middleware-manager.js.map +1 -0
- package/es/middleware/persist.d.ts +34 -0
- package/es/middleware/persist.d.ts.map +1 -0
- package/es/middleware/persist.js +102 -0
- package/es/middleware/persist.js.map +1 -0
- package/es/middleware/time-travel.d.ts +30 -0
- package/es/middleware/time-travel.d.ts.map +1 -0
- package/es/middleware/time-travel.js +151 -0
- package/es/middleware/time-travel.js.map +1 -0
- package/es/middleware/validation.d.ts +100 -0
- package/es/middleware/validation.d.ts.map +1 -0
- package/es/middleware/validation.js +74 -0
- package/es/middleware/validation.js.map +1 -0
- package/es/plugins/define-plugin.d.ts +74 -0
- package/es/plugins/define-plugin.d.ts.map +1 -0
- package/es/plugins/define-plugin.js +52 -0
- package/es/plugins/define-plugin.js.map +1 -0
- package/es/plugins/index.d.ts +8 -0
- package/es/plugins/index.d.ts.map +1 -0
- package/es/plugins/index.js +13 -0
- package/es/plugins/plugin-manager.d.ts +35 -0
- package/es/plugins/plugin-manager.d.ts.map +1 -0
- package/es/plugins/plugin-manager.js +77 -0
- package/es/plugins/plugin-manager.js.map +1 -0
- package/es/types/index.d.ts +12 -0
- package/es/types/index.d.ts.map +1 -0
- package/es/types/index.js +10 -0
- package/es/types/middleware.d.ts +172 -0
- package/es/types/middleware.d.ts.map +1 -0
- package/es/types/middleware.js +10 -0
- package/es/types/plugin.d.ts +136 -0
- package/es/types/plugin.d.ts.map +1 -0
- package/es/types/plugin.js +10 -0
- package/es/types/store.d.ts +198 -0
- package/es/types/store.d.ts.map +1 -0
- package/es/types/store.js +10 -0
- package/es/types/subscription.d.ts +158 -0
- package/es/types/subscription.d.ts.map +1 -0
- package/es/types/subscription.js +10 -0
- package/es/types/utility.d.ts +312 -0
- package/es/types/utility.d.ts.map +1 -0
- package/es/types/utility.js +10 -0
- package/es/utils/debounce-throttle.d.ts +86 -0
- package/es/utils/debounce-throttle.d.ts.map +1 -0
- package/es/utils/debounce-throttle.js +86 -0
- package/es/utils/debounce-throttle.js.map +1 -0
- package/es/utils/deep-clone.d.ts +143 -0
- package/es/utils/deep-clone.d.ts.map +1 -0
- package/es/utils/deep-clone.js +193 -0
- package/es/utils/deep-clone.js.map +1 -0
- package/es/utils/index.d.ts +13 -0
- package/es/utils/index.d.ts.map +1 -0
- package/es/utils/index.js +14 -0
- package/es/utils/selector.d.ts +213 -0
- package/es/utils/selector.d.ts.map +1 -0
- package/es/utils/selector.js +151 -0
- package/es/utils/selector.js.map +1 -0
- package/esm/core/async-action.d.ts +95 -0
- package/esm/core/async-action.js +116 -0
- package/esm/core/async-action.js.map +1 -0
- package/esm/core/base-store.d.ts +85 -0
- package/esm/core/base-store.js +185 -0
- package/esm/core/base-store.js.map +1 -0
- package/esm/core/batch-manager.d.ts +46 -0
- package/esm/core/batch-manager.js +64 -0
- package/esm/core/batch-manager.js.map +1 -0
- package/esm/core/create-store.d.ts +66 -0
- package/esm/core/create-store.js +29 -0
- package/esm/core/create-store.js.map +1 -0
- package/esm/core/event-bus.d.ts +34 -0
- package/esm/core/event-bus.js +71 -0
- package/esm/core/event-bus.js.map +1 -0
- package/esm/core/index.d.ts +14 -0
- package/esm/core/index.js +17 -0
- package/esm/core/pub-sub.d.ts +41 -0
- package/esm/core/pub-sub.js +71 -0
- package/esm/core/pub-sub.js.map +1 -0
- package/esm/engine/index.d.ts +10 -0
- package/esm/engine/index.js +12 -0
- package/esm/engine/plugin.d.ts +20 -0
- package/esm/engine/plugin.js +153 -0
- package/esm/engine/plugin.js.map +1 -0
- package/esm/engine/types.d.ts +81 -0
- package/esm/errors/index.d.ts +208 -0
- package/esm/errors/index.js +217 -0
- package/esm/errors/index.js.map +1 -0
- package/esm/index.d.ts +27 -0
- package/esm/index.js +36 -0
- package/esm/index.js.map +1 -0
- package/esm/middleware/index.d.ts +13 -0
- package/esm/middleware/logger.d.ts +67 -0
- package/esm/middleware/logger.js +119 -0
- package/esm/middleware/logger.js.map +1 -0
- package/esm/middleware/middleware-manager.d.ts +40 -0
- package/esm/middleware/middleware-manager.js +79 -0
- package/esm/middleware/middleware-manager.js.map +1 -0
- package/esm/middleware/persist.d.ts +34 -0
- package/esm/middleware/persist.js +102 -0
- package/esm/middleware/persist.js.map +1 -0
- package/esm/middleware/time-travel.d.ts +30 -0
- package/esm/middleware/time-travel.js +151 -0
- package/esm/middleware/time-travel.js.map +1 -0
- package/esm/middleware/validation.d.ts +100 -0
- package/esm/middleware/validation.js +74 -0
- package/esm/middleware/validation.js.map +1 -0
- package/esm/plugins/define-plugin.d.ts +74 -0
- package/esm/plugins/define-plugin.js +52 -0
- package/esm/plugins/define-plugin.js.map +1 -0
- package/esm/plugins/index.d.ts +8 -0
- package/esm/plugins/plugin-manager.d.ts +35 -0
- package/esm/plugins/plugin-manager.js +77 -0
- package/esm/plugins/plugin-manager.js.map +1 -0
- package/esm/types/index.d.ts +12 -0
- package/esm/types/middleware.d.ts +172 -0
- package/esm/types/plugin.d.ts +136 -0
- package/esm/types/store.d.ts +198 -0
- package/esm/types/subscription.d.ts +158 -0
- package/esm/types/utility.d.ts +312 -0
- package/esm/utils/debounce-throttle.d.ts +86 -0
- package/esm/utils/debounce-throttle.js +86 -0
- package/esm/utils/debounce-throttle.js.map +1 -0
- package/esm/utils/deep-clone.d.ts +143 -0
- package/esm/utils/deep-clone.js +193 -0
- package/esm/utils/deep-clone.js.map +1 -0
- package/esm/utils/index.d.ts +13 -0
- package/esm/utils/selector.d.ts +213 -0
- package/esm/utils/selector.js +151 -0
- package/esm/utils/selector.js.map +1 -0
- package/lib/core/async-action.cjs +118 -0
- package/lib/core/async-action.cjs.map +1 -0
- package/lib/core/async-action.d.ts +95 -0
- package/lib/core/base-store.cjs +187 -0
- package/lib/core/base-store.cjs.map +1 -0
- package/lib/core/base-store.d.ts +85 -0
- package/lib/core/batch-manager.cjs +69 -0
- package/lib/core/batch-manager.cjs.map +1 -0
- package/lib/core/batch-manager.d.ts +46 -0
- package/lib/core/create-store.cjs +31 -0
- package/lib/core/create-store.cjs.map +1 -0
- package/lib/core/create-store.d.ts +66 -0
- package/lib/core/event-bus.cjs +74 -0
- package/lib/core/event-bus.cjs.map +1 -0
- package/lib/core/event-bus.d.ts +34 -0
- package/lib/core/index.cjs +29 -0
- package/lib/core/index.d.ts +14 -0
- package/lib/core/pub-sub.cjs +74 -0
- package/lib/core/pub-sub.cjs.map +1 -0
- package/lib/core/pub-sub.d.ts +41 -0
- package/lib/engine/index.cjs +16 -0
- package/lib/engine/index.d.ts +10 -0
- package/lib/engine/plugin.cjs +157 -0
- package/lib/engine/plugin.cjs.map +1 -0
- package/lib/engine/plugin.d.ts +20 -0
- package/lib/engine/types.cjs +12 -0
- package/lib/engine/types.d.ts +81 -0
- package/lib/errors/index.cjs +233 -0
- package/lib/errors/index.cjs.map +1 -0
- package/lib/errors/index.d.ts +208 -0
- package/lib/index.cjs +101 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.ts +27 -0
- package/lib/middleware/index.cjs +28 -0
- package/lib/middleware/index.d.ts +13 -0
- package/lib/middleware/logger.cjs +140 -0
- package/lib/middleware/logger.cjs.map +1 -0
- package/lib/middleware/logger.d.ts +67 -0
- package/lib/middleware/middleware-manager.cjs +83 -0
- package/lib/middleware/middleware-manager.cjs.map +1 -0
- package/lib/middleware/middleware-manager.d.ts +40 -0
- package/lib/middleware/persist.cjs +105 -0
- package/lib/middleware/persist.cjs.map +1 -0
- package/lib/middleware/persist.d.ts +34 -0
- package/lib/middleware/time-travel.cjs +154 -0
- package/lib/middleware/time-travel.cjs.map +1 -0
- package/lib/middleware/time-travel.d.ts +30 -0
- package/lib/middleware/validation.cjs +76 -0
- package/lib/middleware/validation.cjs.map +1 -0
- package/lib/middleware/validation.d.ts +100 -0
- package/lib/package.json +3 -0
- package/lib/plugins/define-plugin.cjs +56 -0
- package/lib/plugins/define-plugin.cjs.map +1 -0
- package/lib/plugins/define-plugin.d.ts +74 -0
- package/lib/plugins/index.cjs +20 -0
- package/lib/plugins/index.d.ts +8 -0
- package/lib/plugins/plugin-manager.cjs +81 -0
- package/lib/plugins/plugin-manager.cjs.map +1 -0
- package/lib/plugins/plugin-manager.d.ts +35 -0
- package/lib/types/index.cjs +12 -0
- package/lib/types/index.d.ts +12 -0
- package/lib/types/middleware.cjs +12 -0
- package/lib/types/middleware.d.ts +172 -0
- package/lib/types/plugin.cjs +12 -0
- package/lib/types/plugin.d.ts +136 -0
- package/lib/types/store.cjs +12 -0
- package/lib/types/store.d.ts +198 -0
- package/lib/types/subscription.cjs +12 -0
- package/lib/types/subscription.d.ts +158 -0
- package/lib/types/utility.cjs +12 -0
- package/lib/types/utility.d.ts +312 -0
- package/lib/utils/debounce-throttle.cjs +89 -0
- package/lib/utils/debounce-throttle.cjs.map +1 -0
- package/lib/utils/debounce-throttle.d.ts +86 -0
- package/lib/utils/deep-clone.cjs +202 -0
- package/lib/utils/deep-clone.cjs.map +1 -0
- package/lib/utils/deep-clone.d.ts +143 -0
- package/lib/utils/index.cjs +34 -0
- package/lib/utils/index.d.ts +13 -0
- package/lib/utils/selector.cjs +161 -0
- package/lib/utils/selector.cjs.map +1 -0
- package/lib/utils/selector.d.ts +213 -0
- package/package.json +155 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["StoreErrorCode","ErrorSeverity"],"sources":["../../src/errors/index.ts"],"sourcesContent":["/**\n * 自定义错误类\n *\n * 提供统一的错误处理模式\n * @module errors\n */\n\n/**\n * Store 错误代码\n */\nexport enum StoreErrorCode {\n /** Store 已销毁 */\n STORE_DISPOSED = 'STORE_DISPOSED',\n /** Store 不存在 */\n STORE_NOT_FOUND = 'STORE_NOT_FOUND',\n /** Store 已存在 */\n STORE_ALREADY_EXISTS = 'STORE_ALREADY_EXISTS',\n /** 无效的状态 */\n INVALID_STATE = 'INVALID_STATE',\n /** 无效的 Action */\n INVALID_ACTION = 'INVALID_ACTION',\n /** 序列化错误 */\n SERIALIZATION_ERROR = 'SERIALIZATION_ERROR',\n /** 反序列化错误 */\n DESERIALIZATION_ERROR = 'DESERIALIZATION_ERROR',\n /** 存储错误 */\n STORAGE_ERROR = 'STORAGE_ERROR',\n /** 插件错误 */\n PLUGIN_ERROR = 'PLUGIN_ERROR',\n /** 中间件错误 */\n MIDDLEWARE_ERROR = 'MIDDLEWARE_ERROR',\n /** 订阅错误 */\n SUBSCRIPTION_ERROR = 'SUBSCRIPTION_ERROR',\n /** 超时错误 */\n TIMEOUT_ERROR = 'TIMEOUT_ERROR',\n /** 未知错误 */\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n}\n\n/**\n * 错误严重级别\n */\nexport enum ErrorSeverity {\n /** 警告 - 不影响功能,但需要注意 */\n WARNING = 'warning',\n /** 错误 - 影响部分功能 */\n ERROR = 'error',\n /** 致命 - 导致系统无法正常运行 */\n FATAL = 'fatal',\n}\n\n/**\n * Store 错误上下文\n */\nexport interface StoreErrorContext {\n /** Store ID */\n storeId?: string\n /** Action 名称 */\n action?: string\n /** 插件名称 */\n plugin?: string\n /** 中间件名称 */\n middleware?: string\n /** 额外数据 */\n data?: unknown\n /** 时间戳 */\n timestamp?: number\n}\n\n/**\n * Store 基础错误类\n *\n * 所有 Store 相关错误的基类\n *\n * @example\n * ```typescript\n * try {\n * store.someAction()\n * } catch (error) {\n * if (error instanceof StoreError) {\n * console.log('Store error:', error.code, error.message)\n * console.log('Context:', error.context)\n * }\n * }\n * ```\n */\nexport class StoreError extends Error {\n /** 错误代码 */\n readonly code: StoreErrorCode\n\n /** 错误上下文 */\n readonly context: StoreErrorContext\n\n /** 错误严重级别 */\n readonly severity: ErrorSeverity\n\n /** 原始错误 */\n readonly cause?: Error\n\n /**\n * 创建 Store 错误\n *\n * @param message - 错误消息\n * @param code - 错误代码\n * @param context - 错误上下文\n * @param severity - 错误严重级别\n * @param cause - 原始错误\n */\n constructor(\n message: string,\n code: StoreErrorCode = StoreErrorCode.UNKNOWN_ERROR,\n context: StoreErrorContext = {},\n severity: ErrorSeverity = ErrorSeverity.ERROR,\n cause?: Error,\n ) {\n super(message)\n this.name = 'StoreError'\n this.code = code\n this.context = {\n ...context,\n timestamp: context.timestamp ?? Date.now(),\n }\n this.severity = severity\n this.cause = cause\n\n // 保持正确的原型链\n Object.setPrototypeOf(this, StoreError.prototype)\n\n // 捕获堆栈跟踪\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, StoreError)\n }\n }\n\n /**\n * 转换为 JSON\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n context: this.context,\n severity: this.severity,\n stack: this.stack,\n }\n }\n\n /**\n * 格式化错误信息\n */\n format(): string {\n const parts = [`[${this.code}] ${this.message}`]\n\n if (this.context.storeId) {\n parts.push(`Store: ${this.context.storeId}`)\n }\n\n if (this.context.action) {\n parts.push(`Action: ${this.context.action}`)\n }\n\n return parts.join(' | ')\n }\n}\n\n/**\n * Store 销毁错误\n *\n * 当尝试操作已销毁的 Store 时抛出\n */\nexport class StoreDisposedError extends StoreError {\n constructor(storeId: string, action?: string) {\n super(\n `Store \"${storeId}\" 已被销毁,无法执行操作${action ? `: ${action}` : ''}`,\n StoreErrorCode.STORE_DISPOSED,\n { storeId, action },\n ErrorSeverity.ERROR,\n )\n this.name = 'StoreDisposedError'\n Object.setPrototypeOf(this, StoreDisposedError.prototype)\n }\n}\n\n/**\n * Store 不存在错误\n */\nexport class StoreNotFoundError extends StoreError {\n constructor(storeId: string) {\n super(\n `Store \"${storeId}\" 不存在`,\n StoreErrorCode.STORE_NOT_FOUND,\n { storeId },\n ErrorSeverity.ERROR,\n )\n this.name = 'StoreNotFoundError'\n Object.setPrototypeOf(this, StoreNotFoundError.prototype)\n }\n}\n\n/**\n * Store 已存在错误\n */\nexport class StoreAlreadyExistsError extends StoreError {\n constructor(storeId: string) {\n super(\n `Store \"${storeId}\" 已存在`,\n StoreErrorCode.STORE_ALREADY_EXISTS,\n { storeId },\n ErrorSeverity.WARNING,\n )\n this.name = 'StoreAlreadyExistsError'\n Object.setPrototypeOf(this, StoreAlreadyExistsError.prototype)\n }\n}\n\n/**\n * 无效状态错误\n */\nexport class InvalidStateError extends StoreError {\n constructor(message: string, storeId?: string, data?: unknown) {\n super(\n message,\n StoreErrorCode.INVALID_STATE,\n { storeId, data },\n ErrorSeverity.ERROR,\n )\n this.name = 'InvalidStateError'\n Object.setPrototypeOf(this, InvalidStateError.prototype)\n }\n}\n\n/**\n * 序列化错误\n */\nexport class SerializationError extends StoreError {\n constructor(message: string, cause?: Error, storeId?: string) {\n super(\n message,\n StoreErrorCode.SERIALIZATION_ERROR,\n { storeId },\n ErrorSeverity.ERROR,\n cause,\n )\n this.name = 'SerializationError'\n Object.setPrototypeOf(this, SerializationError.prototype)\n }\n}\n\n/**\n * 反序列化错误\n */\nexport class DeserializationError extends StoreError {\n constructor(message: string, cause?: Error, storeId?: string) {\n super(\n message,\n StoreErrorCode.DESERIALIZATION_ERROR,\n { storeId },\n ErrorSeverity.ERROR,\n cause,\n )\n this.name = 'DeserializationError'\n Object.setPrototypeOf(this, DeserializationError.prototype)\n }\n}\n\n/**\n * 存储错误\n */\nexport class StorageError extends StoreError {\n constructor(message: string, cause?: Error, storeId?: string) {\n super(\n message,\n StoreErrorCode.STORAGE_ERROR,\n { storeId },\n ErrorSeverity.ERROR,\n cause,\n )\n this.name = 'StorageError'\n Object.setPrototypeOf(this, StorageError.prototype)\n }\n}\n\n/**\n * 插件错误\n */\nexport class PluginError extends StoreError {\n constructor(message: string, pluginName: string, cause?: Error) {\n super(\n message,\n StoreErrorCode.PLUGIN_ERROR,\n { plugin: pluginName },\n ErrorSeverity.ERROR,\n cause,\n )\n this.name = 'PluginError'\n Object.setPrototypeOf(this, PluginError.prototype)\n }\n}\n\n/**\n * 中间件错误\n */\nexport class MiddlewareError extends StoreError {\n constructor(message: string, middlewareName: string, cause?: Error) {\n super(\n message,\n StoreErrorCode.MIDDLEWARE_ERROR,\n { middleware: middlewareName },\n ErrorSeverity.ERROR,\n cause,\n )\n this.name = 'MiddlewareError'\n Object.setPrototypeOf(this, MiddlewareError.prototype)\n }\n}\n\n/**\n * 订阅错误\n */\nexport class SubscriptionError extends StoreError {\n constructor(message: string, cause?: Error, storeId?: string) {\n super(\n message,\n StoreErrorCode.SUBSCRIPTION_ERROR,\n { storeId },\n ErrorSeverity.WARNING,\n cause,\n )\n this.name = 'SubscriptionError'\n Object.setPrototypeOf(this, SubscriptionError.prototype)\n }\n}\n\n/**\n * 超时错误\n */\nexport class TimeoutError extends StoreError {\n constructor(message: string, storeId?: string, action?: string) {\n super(\n message,\n StoreErrorCode.TIMEOUT_ERROR,\n { storeId, action },\n ErrorSeverity.ERROR,\n )\n this.name = 'TimeoutError'\n Object.setPrototypeOf(this, TimeoutError.prototype)\n }\n}\n\n/**\n * 错误处理工具\n */\nexport const errorUtils = {\n /**\n * 判断是否为 Store 错误\n */\n isStoreError(error: unknown): error is StoreError {\n return error instanceof StoreError\n },\n\n /**\n * 判断是否为特定类型的错误\n */\n isErrorCode(error: unknown, code: StoreErrorCode): boolean {\n return error instanceof StoreError && error.code === code\n },\n\n /**\n * 包装错误为 Store 错误\n */\n wrap(error: unknown, code: StoreErrorCode = StoreErrorCode.UNKNOWN_ERROR, context: StoreErrorContext = {}): StoreError {\n if (error instanceof StoreError) {\n return error\n }\n\n const message = error instanceof Error ? error.message : String(error)\n const cause = error instanceof Error ? error : undefined\n\n return new StoreError(message, code, context, ErrorSeverity.ERROR, cause)\n },\n\n /**\n * 安全执行函数,捕获并包装错误\n */\n async tryCatch<T>(\n fn: () => T | Promise<T>,\n code: StoreErrorCode = StoreErrorCode.UNKNOWN_ERROR,\n context: StoreErrorContext = {},\n ): Promise<T> {\n try {\n return await fn()\n }\n catch (error) {\n throw errorUtils.wrap(error, code, context)\n }\n },\n\n /**\n * 创建错误日志记录器\n */\n createLogger(prefix: string) {\n return {\n error(error: StoreError): void {\n console.error(`[${prefix}]`, error.format())\n if (error.cause) {\n console.error(`[${prefix}] Caused by:`, error.cause)\n }\n },\n\n warn(error: StoreError): void {\n console.warn(`[${prefix}]`, error.format())\n },\n\n log(error: StoreError): void {\n if (error.severity === ErrorSeverity.FATAL || error.severity === ErrorSeverity.ERROR) {\n this.error(error)\n }\n else {\n this.warn(error)\n }\n },\n }\n },\n}\n\n"],"mappings":"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"}
|
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @composy/store-core - 框架无关的状态管理核心库
|
|
3
|
+
*
|
|
4
|
+
* 主要功能模块:
|
|
5
|
+
* - 核心抽象:Store、State、Action、Getter 等核心概念
|
|
6
|
+
* - 插件系统:可扩展的插件机制
|
|
7
|
+
* - 中间件:日志、持久化、时间旅行等
|
|
8
|
+
* - 订阅发布:状态变化订阅、事件总线
|
|
9
|
+
* - 批量更新:性能优化的批量状态更新
|
|
10
|
+
* - 工具函数:深拷贝、选择器等
|
|
11
|
+
*
|
|
12
|
+
* @module @composy/store-core
|
|
13
|
+
*/
|
|
14
|
+
export { BaseStore, batch, createAsyncAction, createBatchManager, createEventBus, createPubSub, createPubSubWithValue, createStore, getGlobalBatchManager, globalEventBus, setGlobalBatchManager, } from './core';
|
|
15
|
+
export type { AsyncAction, AsyncActionOptions, AsyncActionState, CreateStoreDefinition, StoreAPI, } from './core';
|
|
16
|
+
export * from './engine';
|
|
17
|
+
export { DeserializationError, ErrorSeverity, errorUtils, InvalidStateError, MiddlewareError, PluginError, SerializationError, StorageError, StoreAlreadyExistsError, StoreDisposedError, StoreError, StoreErrorCode, StoreNotFoundError, SubscriptionError, TimeoutError, } from './errors';
|
|
18
|
+
export type { StoreErrorContext, } from './errors';
|
|
19
|
+
export { createLoggerMiddleware, createMiddlewareManager, createPersistMiddleware, createSimpleLoggerMiddleware, createTimeTravelMiddleware, createValidationMiddleware, getGlobalMiddlewareManager, restoreState, setGlobalMiddlewareManager, setRestoreCallback, } from './middleware';
|
|
20
|
+
export type { StoreValidationRules, ValidationError, ValidationMiddlewareOptions, ValidationResult, ValidationRule, } from './middleware';
|
|
21
|
+
export { composePlugins, createPluginFactory, createPluginManager, defineStorePlugin, getGlobalPluginManager, setGlobalPluginManager, } from './plugins';
|
|
22
|
+
export type { ActionContext, ActionSubscriber, BatchContext, BatchManager, DefinePluginOptions, EventBus, EventData, EventListener, EventType, LoggerMiddlewareOptions, Middleware, MiddlewareActionType, MiddlewareContext, MiddlewareFunction, MiddlewareManager, PersistMiddlewareOptions, PersistOptions, PluginContext, PluginFactory, PluginManager, PubSub, Selector, SelectorOptions, StateMutation, StateSnapshot, StateSubscriber, StateTree, StorageAdapter, StoreAction, StoreActions, StoreDefinition, StoreGetter, StoreGetters, StoreId, StoreInstance, StoreManagerLike, StoreOptions, StorePlugin, SubscribeOptions, Subscriber, SubscriptionOptions, TimeTravelController, TimeTravelMiddlewareOptions, Unsubscribe, } from './types';
|
|
23
|
+
export { combineSelectors, createCachedSelector, createMemoizedSelector, createSelector, createSelectorWithDeps, debounce, deepClone, deepEqual, deepFreeze, deepMerge, deepMergeWithOptions, deleteByPath, getByPath, hasPath, isObject, isPlainObject, setByPath, shallowClone, throttle, } from './utils';
|
|
24
|
+
export declare const version = "1.0.0";
|
|
25
|
+
export declare const name = "@composy/store-core";
|
|
26
|
+
export type { DebouncedFunction, DeepCloneOptions, DeepMergeOptions, MemoizedSelectorOptions, SelectorEqualityFn, ThrottledFunction, } from './utils';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:27:33 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
import { createPubSub, createPubSubWithValue } from "./core/pub-sub.js";
|
|
11
|
+
import { createAsyncAction } from "./core/async-action.js";
|
|
12
|
+
import { createEventBus, globalEventBus } from "./core/event-bus.js";
|
|
13
|
+
import { BaseStore } from "./core/base-store.js";
|
|
14
|
+
import { batch, createBatchManager, getGlobalBatchManager, setGlobalBatchManager } from "./core/batch-manager.js";
|
|
15
|
+
import { createStore } from "./core/create-store.js";
|
|
16
|
+
import "./core/index.js";
|
|
17
|
+
import { createStoreEngineBridge, storeEventKeys, storeStateKeys } from "./engine/plugin.js";
|
|
18
|
+
import "./engine/index.js";
|
|
19
|
+
import { DeserializationError, ErrorSeverity, InvalidStateError, MiddlewareError, PluginError, SerializationError, StorageError, StoreAlreadyExistsError, StoreDisposedError, StoreError, StoreErrorCode, StoreNotFoundError, SubscriptionError, TimeoutError, errorUtils } from "./errors/index.js";
|
|
20
|
+
import { debounce, throttle } from "./utils/debounce-throttle.js";
|
|
21
|
+
import { deepClone, deepEqual, deepFreeze, deepMerge, deepMergeWithOptions, isObject, isPlainObject, shallowClone } from "./utils/deep-clone.js";
|
|
22
|
+
import { combineSelectors, createCachedSelector, createMemoizedSelector, createSelector, createSelectorWithDeps, deleteByPath, getByPath, hasPath, setByPath } from "./utils/selector.js";
|
|
23
|
+
import { createLoggerMiddleware, createSimpleLoggerMiddleware } from "./middleware/logger.js";
|
|
24
|
+
import { createMiddlewareManager, getGlobalMiddlewareManager, setGlobalMiddlewareManager } from "./middleware/middleware-manager.js";
|
|
25
|
+
import { createPersistMiddleware, restoreState } from "./middleware/persist.js";
|
|
26
|
+
import { createTimeTravelMiddleware, setRestoreCallback } from "./middleware/time-travel.js";
|
|
27
|
+
import { createValidationMiddleware } from "./middleware/validation.js";
|
|
28
|
+
import { composePlugins, createPluginFactory, defineStorePlugin } from "./plugins/define-plugin.js";
|
|
29
|
+
import { createPluginManager, getGlobalPluginManager, setGlobalPluginManager } from "./plugins/plugin-manager.js";
|
|
30
|
+
//#region src/index.ts
|
|
31
|
+
const version = "1.0.0";
|
|
32
|
+
const name = "@composy/store-core";
|
|
33
|
+
//#endregion
|
|
34
|
+
export { BaseStore, DeserializationError, ErrorSeverity, InvalidStateError, MiddlewareError, PluginError, SerializationError, StorageError, StoreAlreadyExistsError, StoreDisposedError, StoreError, StoreErrorCode, StoreNotFoundError, SubscriptionError, TimeoutError, batch, combineSelectors, composePlugins, createAsyncAction, createBatchManager, createCachedSelector, createEventBus, createLoggerMiddleware, createMemoizedSelector, createMiddlewareManager, createPersistMiddleware, createPluginFactory, createPluginManager, createPubSub, createPubSubWithValue, createSelector, createSelectorWithDeps, createSimpleLoggerMiddleware, createStore, createStoreEngineBridge, createTimeTravelMiddleware, createValidationMiddleware, debounce, deepClone, deepEqual, deepFreeze, deepMerge, deepMergeWithOptions, defineStorePlugin, deleteByPath, errorUtils, getByPath, getGlobalBatchManager, getGlobalMiddlewareManager, getGlobalPluginManager, globalEventBus, hasPath, isObject, isPlainObject, name, restoreState, setByPath, setGlobalBatchManager, setGlobalMiddlewareManager, setGlobalPluginManager, setRestoreCallback, shallowClone, storeEventKeys, storeStateKeys, throttle, version };
|
|
35
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @composy/store-core - 框架无关的状态管理核心库\n *\n * 主要功能模块:\n * - 核心抽象:Store、State、Action、Getter 等核心概念\n * - 插件系统:可扩展的插件机制\n * - 中间件:日志、持久化、时间旅行等\n * - 订阅发布:状态变化订阅、事件总线\n * - 批量更新:性能优化的批量状态更新\n * - 工具函数:深拷贝、选择器等\n *\n * @module @composy/store-core\n */\n\n// === 核心模块 ===\nexport {\n BaseStore,\n batch,\n createAsyncAction,\n createBatchManager,\n createEventBus,\n createPubSub,\n createPubSubWithValue,\n createStore,\n getGlobalBatchManager,\n globalEventBus,\n setGlobalBatchManager,\n} from './core'\n\nexport type {\n AsyncAction,\n AsyncActionOptions,\n AsyncActionState,\n CreateStoreDefinition,\n StoreAPI,\n} from './core'\n\n// Engine 插件\nexport * from './engine'\n\n// === 错误处理 ===\nexport {\n DeserializationError,\n ErrorSeverity,\n errorUtils,\n InvalidStateError,\n MiddlewareError,\n PluginError,\n SerializationError,\n StorageError,\n StoreAlreadyExistsError,\n StoreDisposedError,\n StoreError,\n StoreErrorCode,\n StoreNotFoundError,\n SubscriptionError,\n TimeoutError,\n} from './errors'\n\nexport type {\n StoreErrorContext,\n} from './errors'\n\n// === 中间件模块 ===\nexport {\n createLoggerMiddleware,\n createMiddlewareManager,\n createPersistMiddleware,\n createSimpleLoggerMiddleware,\n createTimeTravelMiddleware,\n createValidationMiddleware,\n getGlobalMiddlewareManager,\n restoreState,\n setGlobalMiddlewareManager,\n setRestoreCallback,\n} from './middleware'\n\nexport type {\n StoreValidationRules,\n ValidationError,\n ValidationMiddlewareOptions,\n ValidationResult,\n ValidationRule,\n} from './middleware'\n\n// === 插件模块 ===\nexport {\n composePlugins,\n createPluginFactory,\n createPluginManager,\n defineStorePlugin,\n getGlobalPluginManager,\n setGlobalPluginManager,\n} from './plugins'\n\n// === 类型定义 ===\nexport type {\n // Store 类型\n ActionContext,\n ActionSubscriber,\n // 订阅类型\n BatchContext,\n BatchManager,\n // 插件类型\n DefinePluginOptions,\n EventBus,\n EventData,\n EventListener,\n EventType,\n // 中间件类型\n LoggerMiddlewareOptions,\n Middleware,\n MiddlewareActionType,\n MiddlewareContext,\n MiddlewareFunction,\n MiddlewareManager,\n PersistMiddlewareOptions,\n PersistOptions,\n PluginContext,\n PluginFactory,\n PluginManager,\n PubSub,\n Selector,\n SelectorOptions,\n StateMutation,\n StateSnapshot,\n StateSubscriber,\n StateTree,\n StorageAdapter,\n StoreAction,\n StoreActions,\n StoreDefinition,\n StoreGetter,\n StoreGetters,\n StoreId,\n StoreInstance,\n StoreManagerLike,\n StoreOptions,\n StorePlugin,\n SubscribeOptions,\n Subscriber,\n SubscriptionOptions,\n TimeTravelController,\n TimeTravelMiddlewareOptions,\n Unsubscribe,\n} from './types'\n\n// === 工具函数 ===\nexport {\n combineSelectors,\n createCachedSelector,\n createMemoizedSelector,\n createSelector,\n createSelectorWithDeps,\n debounce,\n deepClone,\n deepEqual,\n deepFreeze,\n deepMerge,\n deepMergeWithOptions,\n deleteByPath,\n getByPath,\n hasPath,\n isObject,\n isPlainObject,\n setByPath,\n shallowClone,\n throttle,\n} from './utils'\n\n// === 版本信息 ===\nexport const version = '1.0.0'\nexport const name = '@composy/store-core'\n\nexport type {\n DebouncedFunction,\n DeepCloneOptions,\n DeepMergeOptions,\n MemoizedSelectorOptions,\n SelectorEqualityFn,\n ThrottledFunction,\n} from './utils'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2KO,MAAM,UAAU;AAChB,MAAM,OAAO"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 中间件模块导出
|
|
3
|
+
*
|
|
4
|
+
* 提供日志、持久化、时间旅行等中间件
|
|
5
|
+
* @module middleware
|
|
6
|
+
*/
|
|
7
|
+
export { createLoggerMiddleware, createProductionLoggerMiddleware, createSimpleLoggerMiddleware, } from './logger';
|
|
8
|
+
export { createMiddlewareManager, getGlobalMiddlewareManager, setGlobalMiddlewareManager, } from './middleware-manager';
|
|
9
|
+
export { createPersistMiddleware, restoreState, } from './persist';
|
|
10
|
+
export { createTimeTravelMiddleware, setRestoreCallback, } from './time-travel';
|
|
11
|
+
export { createValidationMiddleware, } from './validation';
|
|
12
|
+
export type { StoreValidationRules, ValidationError, ValidationMiddlewareOptions, ValidationResult, ValidationRule, } from './validation';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日志中间件
|
|
3
|
+
*
|
|
4
|
+
* 提供状态变化和 Action 调用的日志记录,支持多种日志级别和格式化选项
|
|
5
|
+
* @module middleware/logger
|
|
6
|
+
*/
|
|
7
|
+
import type { LoggerMiddlewareOptions, Middleware, MiddlewareContext } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* 创建日志中间件
|
|
10
|
+
*
|
|
11
|
+
* 提供完整的状态变化和 Action 调用日志记录,支持时间戳、分组和性能计时
|
|
12
|
+
*
|
|
13
|
+
* @param options - 日志选项
|
|
14
|
+
* @returns 日志中间件
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const logger = createLoggerMiddleware({
|
|
19
|
+
* logState: true,
|
|
20
|
+
* collapsed: true,
|
|
21
|
+
* timestamp: true,
|
|
22
|
+
* filter: (context) => context.storeId !== 'internal'
|
|
23
|
+
* })
|
|
24
|
+
*
|
|
25
|
+
* middlewareManager.use(logger)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function createLoggerMiddleware(options?: LoggerMiddlewareOptions): Middleware;
|
|
29
|
+
/**
|
|
30
|
+
* 简单日志中间件(不使用分组,适合生产环境)
|
|
31
|
+
*
|
|
32
|
+
* @param options - 配置选项
|
|
33
|
+
* @param options.includePayload - 是否输出 payload
|
|
34
|
+
* @param options.format - 自定义日志格式化函数
|
|
35
|
+
* @param options.filter - 日志过滤器
|
|
36
|
+
* @returns 简单日志中间件
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const logger = createSimpleLoggerMiddleware({
|
|
41
|
+
* includePayload: true,
|
|
42
|
+
* format: (ctx) => `${ctx.storeId}: ${ctx.type}`
|
|
43
|
+
* })
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function createSimpleLoggerMiddleware(options?: {
|
|
47
|
+
/** 是否包含 payload */
|
|
48
|
+
includePayload?: boolean;
|
|
49
|
+
/** 自定义格式化函数 */
|
|
50
|
+
format?: (context: MiddlewareContext) => string;
|
|
51
|
+
/** 过滤器 */
|
|
52
|
+
filter?: (context: MiddlewareContext) => boolean;
|
|
53
|
+
}): Middleware;
|
|
54
|
+
/**
|
|
55
|
+
* 创建生产环境日志中间件
|
|
56
|
+
*
|
|
57
|
+
* 只记录错误和警告,不记录正常状态变化
|
|
58
|
+
*
|
|
59
|
+
* @param options - 配置选项
|
|
60
|
+
* @param options.onError - 自定义错误处理器
|
|
61
|
+
* @returns 生产环境日志中间件
|
|
62
|
+
*/
|
|
63
|
+
export declare function createProductionLoggerMiddleware(options?: {
|
|
64
|
+
/** 自定义错误处理器 */
|
|
65
|
+
onError?: (error: Error, context: MiddlewareContext) => void;
|
|
66
|
+
}): Middleware;
|
|
67
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:27:33 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
import { MiddlewareError } from "../errors/index.js";
|
|
11
|
+
import { deepClone } from "../utils/deep-clone.js";
|
|
12
|
+
//#region src/middleware/logger.ts
|
|
13
|
+
const defaultOptions = {
|
|
14
|
+
logState: true,
|
|
15
|
+
logAction: true,
|
|
16
|
+
collapsed: true,
|
|
17
|
+
timestamp: true,
|
|
18
|
+
level: "log"
|
|
19
|
+
};
|
|
20
|
+
const LOG_COLORS = {
|
|
21
|
+
prevState: "color: #9E9E9E; font-weight: bold",
|
|
22
|
+
action: "color: #03A9F4; font-weight: bold",
|
|
23
|
+
nextState: "color: #4CAF50; font-weight: bold",
|
|
24
|
+
error: "color: #F44336; font-weight: bold",
|
|
25
|
+
duration: "color: #9C27B0; font-weight: normal",
|
|
26
|
+
title: "color: inherit; font-weight: bold"
|
|
27
|
+
};
|
|
28
|
+
function formatTime(date) {
|
|
29
|
+
return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}:${date.getSeconds().toString().padStart(2, "0")}.${date.getMilliseconds().toString().padStart(3, "0")}`;
|
|
30
|
+
}
|
|
31
|
+
function formatDuration(startTime, endTime) {
|
|
32
|
+
const duration = endTime - startTime;
|
|
33
|
+
if (duration < 1) return "< 1ms";
|
|
34
|
+
return `${duration.toFixed(2)}ms`;
|
|
35
|
+
}
|
|
36
|
+
function safeCloneState(state) {
|
|
37
|
+
try {
|
|
38
|
+
return deepClone(state);
|
|
39
|
+
} catch {
|
|
40
|
+
return { ...state };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function createLoggerMiddleware(options = {}) {
|
|
44
|
+
const opts = {
|
|
45
|
+
...defaultOptions,
|
|
46
|
+
...options
|
|
47
|
+
};
|
|
48
|
+
const logger = opts.logger ?? console;
|
|
49
|
+
return {
|
|
50
|
+
name: "logger",
|
|
51
|
+
priority: 0,
|
|
52
|
+
handler: async (context, next) => {
|
|
53
|
+
const { storeId, type, state, payload } = context;
|
|
54
|
+
if (opts.filter && !opts.filter(context)) {
|
|
55
|
+
await next();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const isStateChange = type.startsWith("state:");
|
|
59
|
+
const isAction = type.startsWith("action:");
|
|
60
|
+
if (isStateChange && !opts.logState || isAction && !opts.logAction) {
|
|
61
|
+
await next();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const timestamp = opts.timestamp ? formatTime(/* @__PURE__ */ new Date()) : "";
|
|
65
|
+
const prefix = `[Store: ${storeId}]`;
|
|
66
|
+
const startTime = performance.now();
|
|
67
|
+
const prevState = safeCloneState(state);
|
|
68
|
+
const groupTitle = timestamp ? `${timestamp} ${prefix} ${type}` : `${prefix} ${type}`;
|
|
69
|
+
const startGroup = () => {
|
|
70
|
+
if (opts.collapsed && typeof logger.groupCollapsed === "function") logger.groupCollapsed(`%c${groupTitle}`, LOG_COLORS.title);
|
|
71
|
+
else if (typeof logger.group === "function") logger.group(`%c${groupTitle}`, LOG_COLORS.title);
|
|
72
|
+
};
|
|
73
|
+
const endGroup = () => {
|
|
74
|
+
if (typeof logger.groupEnd === "function") logger.groupEnd();
|
|
75
|
+
};
|
|
76
|
+
startGroup();
|
|
77
|
+
try {
|
|
78
|
+
const logFn = logger[opts.level ?? "log"] ?? logger.log;
|
|
79
|
+
if (typeof logFn === "function") {
|
|
80
|
+
logFn.call(logger, "%c prev state", LOG_COLORS.prevState, prevState);
|
|
81
|
+
if (payload !== void 0) logFn.call(logger, "%c payload", LOG_COLORS.action, payload);
|
|
82
|
+
}
|
|
83
|
+
await next();
|
|
84
|
+
const endTime = performance.now();
|
|
85
|
+
if (typeof logFn === "function") {
|
|
86
|
+
logFn.call(logger, "%c next state", LOG_COLORS.nextState, safeCloneState(context.state));
|
|
87
|
+
logFn.call(logger, "%c duration", LOG_COLORS.duration, formatDuration(startTime, endTime));
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (typeof logger.error === "function") logger.error("%c error", LOG_COLORS.error, error);
|
|
91
|
+
throw new MiddlewareError(`\u65E5\u5FD7\u4E2D\u95F4\u4EF6\u6267\u884C\u9519\u8BEF: ${error instanceof Error ? error.message : String(error)}`, "logger", error instanceof Error ? error : void 0);
|
|
92
|
+
} finally {
|
|
93
|
+
endGroup();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function createSimpleLoggerMiddleware(options = {}) {
|
|
99
|
+
const { includePayload = true, format, filter } = options;
|
|
100
|
+
return {
|
|
101
|
+
name: "simple-logger",
|
|
102
|
+
priority: 0,
|
|
103
|
+
handler: async (context, next) => {
|
|
104
|
+
const { storeId, type, payload } = context;
|
|
105
|
+
if (filter && !filter(context)) {
|
|
106
|
+
await next();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const message = format ? format(context) : `[Store: ${storeId}] ${type}`;
|
|
110
|
+
if (includePayload && payload !== void 0) console.info(message, payload);
|
|
111
|
+
else console.info(message);
|
|
112
|
+
await next();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
export { createLoggerMiddleware, createSimpleLoggerMiddleware };
|
|
118
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
|
119
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","names":[],"sources":["../../src/middleware/logger.ts"],"sourcesContent":["/**\n * 日志中间件\n *\n * 提供状态变化和 Action 调用的日志记录,支持多种日志级别和格式化选项\n * @module middleware/logger\n */\n\nimport type { LoggerMiddlewareOptions, Middleware, MiddlewareContext, StateTree } from '../types'\nimport { MiddlewareError } from '../errors'\nimport { deepClone } from '../utils'\n\n/**\n * 默认日志选项\n */\nconst defaultOptions: Required<Omit<LoggerMiddlewareOptions, 'logger' | 'filter'>> = {\n logState: true,\n logAction: true,\n collapsed: true,\n timestamp: true,\n level: 'log',\n}\n\n/**\n * 日志颜色配置\n */\nconst LOG_COLORS = {\n prevState: 'color: #9E9E9E; font-weight: bold',\n action: 'color: #03A9F4; font-weight: bold',\n nextState: 'color: #4CAF50; font-weight: bold',\n error: 'color: #F44336; font-weight: bold',\n duration: 'color: #9C27B0; font-weight: normal',\n title: 'color: inherit; font-weight: bold',\n} as const\n\n/**\n * 格式化时间戳\n *\n * @param date - 日期对象\n * @returns 格式化的时间字符串\n */\nfunction formatTime(date: Date): string {\n const hours = date.getHours().toString().padStart(2, '0')\n const minutes = date.getMinutes().toString().padStart(2, '0')\n const seconds = date.getSeconds().toString().padStart(2, '0')\n const ms = date.getMilliseconds().toString().padStart(3, '0')\n return `${hours}:${minutes}:${seconds}.${ms}`\n}\n\n/**\n * 格式化时间差\n *\n * @param startTime - 开始时间\n * @param endTime - 结束时间\n * @returns 格式化的时间差字符串\n */\nfunction formatDuration(startTime: number, endTime: number): string {\n const duration = endTime - startTime\n if (duration < 1) {\n return '< 1ms'\n }\n return `${duration.toFixed(2)}ms`\n}\n\n/**\n * 安全克隆状态(防止日志中的对象被修改)\n *\n * @param state - 状态对象\n * @returns 克隆后的状态\n */\nfunction safeCloneState<S extends StateTree>(state: S): S {\n try {\n return deepClone(state)\n }\n catch {\n // 如果克隆失败,返回浅拷贝\n return { ...state }\n }\n}\n\n/**\n * 创建日志中间件\n *\n * 提供完整的状态变化和 Action 调用日志记录,支持时间戳、分组和性能计时\n *\n * @param options - 日志选项\n * @returns 日志中间件\n *\n * @example\n * ```typescript\n * const logger = createLoggerMiddleware({\n * logState: true,\n * collapsed: true,\n * timestamp: true,\n * filter: (context) => context.storeId !== 'internal'\n * })\n *\n * middlewareManager.use(logger)\n * ```\n */\nexport function createLoggerMiddleware(\n options: LoggerMiddlewareOptions = {},\n): Middleware {\n const opts = { ...defaultOptions, ...options }\n const logger = opts.logger ?? console\n\n return {\n name: 'logger',\n priority: 0, // 最先执行,确保能记录所有操作\n\n handler: async (context: MiddlewareContext, next: () => void | Promise<void>) => {\n const { storeId, type, state, payload } = context\n\n // 应用自定义过滤器\n if (opts.filter && !opts.filter(context)) {\n await next()\n return\n }\n\n // 判断是否需要记录\n const isStateChange = type.startsWith('state:')\n const isAction = type.startsWith('action:')\n\n if ((isStateChange && !opts.logState) || (isAction && !opts.logAction)) {\n await next()\n return\n }\n\n const timestamp = opts.timestamp ? formatTime(new Date()) : ''\n const prefix = `[Store: ${storeId}]`\n const startTime = performance.now()\n\n // 保存操作前的状态\n const prevState = safeCloneState(state)\n\n // 开始分组\n const groupTitle = timestamp ? `${timestamp} ${prefix} ${type}` : `${prefix} ${type}`\n\n const startGroup = (): void => {\n if (opts.collapsed && typeof logger.groupCollapsed === 'function') {\n logger.groupCollapsed(`%c${groupTitle}`, LOG_COLORS.title)\n }\n else if (typeof logger.group === 'function') {\n logger.group(`%c${groupTitle}`, LOG_COLORS.title)\n }\n }\n\n const endGroup = (): void => {\n if (typeof logger.groupEnd === 'function') {\n logger.groupEnd()\n }\n }\n\n startGroup()\n\n try {\n // 记录操作前的状态\n const logFn = logger[opts.level ?? 'log'] ?? logger.log\n\n if (typeof logFn === 'function') {\n logFn.call(logger, '%c prev state', LOG_COLORS.prevState, prevState)\n\n if (payload !== undefined) {\n logFn.call(logger, '%c payload', LOG_COLORS.action, payload)\n }\n }\n\n // 执行下一个中间件\n await next()\n\n const endTime = performance.now()\n\n // 记录操作后的状态\n if (typeof logFn === 'function') {\n logFn.call(logger, '%c next state', LOG_COLORS.nextState, safeCloneState(context.state))\n logFn.call(logger, '%c duration', LOG_COLORS.duration, formatDuration(startTime, endTime))\n }\n }\n catch (error) {\n // 记录错误\n if (typeof logger.error === 'function') {\n logger.error('%c error', LOG_COLORS.error, error)\n }\n\n // 包装并重新抛出错误\n throw new MiddlewareError(\n `日志中间件执行错误: ${error instanceof Error ? error.message : String(error)}`,\n 'logger',\n error instanceof Error ? error : undefined,\n )\n }\n finally {\n endGroup()\n }\n },\n }\n}\n\n/**\n * 简单日志中间件(不使用分组,适合生产环境)\n *\n * @param options - 配置选项\n * @param options.includePayload - 是否输出 payload\n * @param options.format - 自定义日志格式化函数\n * @param options.filter - 日志过滤器\n * @returns 简单日志中间件\n *\n * @example\n * ```typescript\n * const logger = createSimpleLoggerMiddleware({\n * includePayload: true,\n * format: (ctx) => `${ctx.storeId}: ${ctx.type}`\n * })\n * ```\n */\nexport function createSimpleLoggerMiddleware(options: {\n /** 是否包含 payload */\n includePayload?: boolean\n /** 自定义格式化函数 */\n format?: (context: MiddlewareContext) => string\n /** 过滤器 */\n filter?: (context: MiddlewareContext) => boolean\n} = {}): Middleware {\n const { includePayload = true, format, filter } = options\n\n return {\n name: 'simple-logger',\n priority: 0,\n\n handler: async (context: MiddlewareContext, next: () => void | Promise<void>) => {\n const { storeId, type, payload } = context\n\n // 应用过滤器\n if (filter && !filter(context)) {\n await next()\n return\n }\n\n // 使用自定义格式化或默认格式\n const message = format\n ? format(context)\n : `[Store: ${storeId}] ${type}`\n\n if (includePayload && payload !== undefined) {\n console.info(message, payload)\n }\n else {\n console.info(message)\n }\n\n await next()\n },\n }\n}\n\n/**\n * 创建生产环境日志中间件\n *\n * 只记录错误和警告,不记录正常状态变化\n *\n * @param options - 配置选项\n * @param options.onError - 自定义错误处理器\n * @returns 生产环境日志中间件\n */\nexport function createProductionLoggerMiddleware(options: {\n /** 自定义错误处理器 */\n onError?: (error: Error, context: MiddlewareContext) => void\n} = {}): Middleware {\n const { onError } = options\n\n return {\n name: 'production-logger',\n priority: 0,\n\n handler: async (context: MiddlewareContext, next: () => void | Promise<void>) => {\n try {\n await next()\n }\n catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n\n if (onError) {\n onError(err, context)\n }\n else {\n console.error(`[Store Error] ${context.storeId}:`, err)\n }\n\n throw error\n }\n },\n }\n}\n\n"],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 中间件管理器
|
|
3
|
+
*
|
|
4
|
+
* @module middleware/middleware-manager
|
|
5
|
+
*/
|
|
6
|
+
import type { MiddlewareManager } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* 创建中间件管理器
|
|
9
|
+
*
|
|
10
|
+
* @returns 中间件管理器实例
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const manager = createMiddlewareManager()
|
|
15
|
+
*
|
|
16
|
+
* // 添加日志中间件
|
|
17
|
+
* manager.use({
|
|
18
|
+
* name: 'logger',
|
|
19
|
+
* priority: 1,
|
|
20
|
+
* handler: async (ctx, next) => {
|
|
21
|
+
* console.log('Before:', ctx.type)
|
|
22
|
+
* await next()
|
|
23
|
+
* console.log('After:', ctx.type)
|
|
24
|
+
* }
|
|
25
|
+
* })
|
|
26
|
+
*
|
|
27
|
+
* // 执行中间件链
|
|
28
|
+
* await manager.execute({ storeId: 'test', state: {}, type: 'state:patch' })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createMiddlewareManager(): MiddlewareManager;
|
|
32
|
+
/**
|
|
33
|
+
* 获取全局中间件管理器
|
|
34
|
+
*/
|
|
35
|
+
export declare function getGlobalMiddlewareManager(): MiddlewareManager;
|
|
36
|
+
/**
|
|
37
|
+
* 设置全局中间件管理器
|
|
38
|
+
*/
|
|
39
|
+
export declare function setGlobalMiddlewareManager(manager: MiddlewareManager): void;
|
|
40
|
+
//# sourceMappingURL=middleware-manager.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:27:33 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
//#region src/middleware/middleware-manager.ts
|
|
11
|
+
function createMiddlewareManager() {
|
|
12
|
+
const middlewares = /* @__PURE__ */ new Map();
|
|
13
|
+
let sortedMiddlewares = null;
|
|
14
|
+
const getSortedMiddlewares = () => {
|
|
15
|
+
if (sortedMiddlewares === null) sortedMiddlewares = Array.from(middlewares.values()).sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100));
|
|
16
|
+
return sortedMiddlewares;
|
|
17
|
+
};
|
|
18
|
+
const invalidateCache = () => {
|
|
19
|
+
sortedMiddlewares = null;
|
|
20
|
+
};
|
|
21
|
+
const use = (middleware) => {
|
|
22
|
+
if (middlewares.has(middleware.name)) console.warn(`[Middleware] \u4E2D\u95F4\u4EF6 "${middleware.name}" \u5DF2\u5B58\u5728\uFF0C\u5C06\u88AB\u8986\u76D6`);
|
|
23
|
+
middlewares.set(middleware.name, middleware);
|
|
24
|
+
invalidateCache();
|
|
25
|
+
};
|
|
26
|
+
const remove = (name) => {
|
|
27
|
+
if (middlewares.delete(name)) invalidateCache();
|
|
28
|
+
};
|
|
29
|
+
const get = (name) => {
|
|
30
|
+
return middlewares.get(name);
|
|
31
|
+
};
|
|
32
|
+
const has = (name) => {
|
|
33
|
+
return middlewares.has(name);
|
|
34
|
+
};
|
|
35
|
+
const execute = async (context) => {
|
|
36
|
+
const sorted = getSortedMiddlewares();
|
|
37
|
+
if (sorted.length === 0) return;
|
|
38
|
+
const dispatch = async (index) => {
|
|
39
|
+
const middleware = sorted[index];
|
|
40
|
+
if (!middleware) return;
|
|
41
|
+
let called = false;
|
|
42
|
+
const next = async () => {
|
|
43
|
+
if (called) throw new Error(`[Middleware] next() called multiple times in "${middleware.name}"`);
|
|
44
|
+
called = true;
|
|
45
|
+
await dispatch(index + 1);
|
|
46
|
+
};
|
|
47
|
+
await middleware.handler(context, next);
|
|
48
|
+
};
|
|
49
|
+
await dispatch(0);
|
|
50
|
+
};
|
|
51
|
+
const getAll = () => {
|
|
52
|
+
return getSortedMiddlewares();
|
|
53
|
+
};
|
|
54
|
+
const clear = () => {
|
|
55
|
+
middlewares.clear();
|
|
56
|
+
invalidateCache();
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
use,
|
|
60
|
+
remove,
|
|
61
|
+
get,
|
|
62
|
+
has,
|
|
63
|
+
execute,
|
|
64
|
+
getAll,
|
|
65
|
+
clear
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
let globalMiddlewareManager = null;
|
|
69
|
+
function getGlobalMiddlewareManager() {
|
|
70
|
+
if (!globalMiddlewareManager) globalMiddlewareManager = createMiddlewareManager();
|
|
71
|
+
return globalMiddlewareManager;
|
|
72
|
+
}
|
|
73
|
+
function setGlobalMiddlewareManager(manager) {
|
|
74
|
+
globalMiddlewareManager = manager;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { createMiddlewareManager, getGlobalMiddlewareManager, setGlobalMiddlewareManager };
|
|
78
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
|
79
|
+
//# sourceMappingURL=middleware-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-manager.js","names":[],"sources":["../../src/middleware/middleware-manager.ts"],"sourcesContent":["/**\n * 中间件管理器\n *\n * @module middleware/middleware-manager\n */\n\nimport type { Middleware, MiddlewareContext, MiddlewareManager } from '../types'\n\n/**\n * 创建中间件管理器\n *\n * @returns 中间件管理器实例\n *\n * @example\n * ```typescript\n * const manager = createMiddlewareManager()\n *\n * // 添加日志中间件\n * manager.use({\n * name: 'logger',\n * priority: 1,\n * handler: async (ctx, next) => {\n * console.log('Before:', ctx.type)\n * await next()\n * console.log('After:', ctx.type)\n * }\n * })\n *\n * // 执行中间件链\n * await manager.execute({ storeId: 'test', state: {}, type: 'state:patch' })\n * ```\n */\nexport function createMiddlewareManager(): MiddlewareManager {\n /** 中间件列表 */\n const middlewares = new Map<string, Middleware>()\n\n /** 已排序的中间件列表缓存 */\n let sortedMiddlewares: Middleware[] | null = null\n\n /**\n * 获取排序后的中间件列表\n */\n const getSortedMiddlewares = (): Middleware[] => {\n if (sortedMiddlewares === null) {\n sortedMiddlewares = Array.from(middlewares.values()).sort(\n (a, b) => (a.priority ?? 100) - (b.priority ?? 100),\n )\n }\n return sortedMiddlewares\n }\n\n /**\n * 使中间件缓存失效\n */\n const invalidateCache = (): void => {\n sortedMiddlewares = null\n }\n\n /**\n * 添加中间件\n */\n const use = (middleware: Middleware): void => {\n if (middlewares.has(middleware.name)) {\n console.warn(`[Middleware] 中间件 \"${middleware.name}\" 已存在,将被覆盖`)\n }\n middlewares.set(middleware.name, middleware)\n invalidateCache()\n }\n\n /**\n * 移除中间件\n */\n const remove = (name: string): void => {\n if (middlewares.delete(name)) {\n invalidateCache()\n }\n }\n\n /**\n * 获取中间件\n */\n const get = (name: string): Middleware | undefined => {\n return middlewares.get(name)\n }\n\n /**\n * 是否存在中间件\n */\n const has = (name: string): boolean => {\n return middlewares.has(name)\n }\n\n /**\n * 执行中间件链\n */\n const execute = async (context: MiddlewareContext): Promise<void> => {\n const sorted = getSortedMiddlewares()\n\n if (sorted.length === 0) {\n return\n }\n\n const dispatch = async (index: number): Promise<void> => {\n const middleware = sorted[index]\n if (!middleware) {\n return\n }\n\n let called = false\n const next = async (): Promise<void> => {\n if (called) {\n throw new Error(`[Middleware] next() called multiple times in \"${middleware.name}\"`)\n }\n\n called = true\n await dispatch(index + 1)\n }\n\n await middleware.handler(context, next)\n }\n\n await dispatch(0)\n }\n\n /**\n * 获取所有中间件\n */\n const getAll = (): Middleware[] => {\n return getSortedMiddlewares()\n }\n\n /**\n * 清空所有中间件\n */\n const clear = (): void => {\n middlewares.clear()\n invalidateCache()\n }\n\n return {\n use,\n remove,\n get,\n has,\n execute,\n getAll,\n clear,\n }\n}\n\n/**\n * 全局中间件管理器\n */\nlet globalMiddlewareManager: MiddlewareManager | null = null\n\n/**\n * 获取全局中间件管理器\n */\nexport function getGlobalMiddlewareManager(): MiddlewareManager {\n if (!globalMiddlewareManager) {\n globalMiddlewareManager = createMiddlewareManager()\n }\n return globalMiddlewareManager\n}\n\n/**\n * 设置全局中间件管理器\n */\nexport function setGlobalMiddlewareManager(manager: MiddlewareManager): void {\n globalMiddlewareManager = manager\n}\n\n"],"mappings":";;;;;;;;;;AAgCO,SAAS,0BAA6C;CAE3D,MAAM,8BAAc,IAAI,IAAwB;CAGhD,IAAI,oBAAyC;CAK7C,MAAM,6BAA2C;EAC/C,IAAI,sBAAsB,MACxB,oBAAoB,MAAM,KAAK,YAAY,OAAO,CAAC,CAAA,CAAE,MAClD,GAAG,OAAO,EAAE,YAAY,QAAQ,EAAE,YAAY,IACjD;EAEF,OAAO;CACT;CAKA,MAAM,wBAA8B;EAClC,oBAAoB;CACtB;CAKA,MAAM,OAAO,eAAiC;EAC5C,IAAI,YAAY,IAAI,WAAW,IAAI,GACjC,QAAQ,KAAK,oCAAqB,WAAW,KAAI,mDAAY;EAE/D,YAAY,IAAI,WAAW,MAAM,UAAU;EAC3C,gBAAgB;CAClB;CAKA,MAAM,UAAU,SAAuB;EACrC,IAAI,YAAY,OAAO,IAAI,GACzB,gBAAgB;CAEpB;CAKA,MAAM,OAAO,SAAyC;EACpD,OAAO,YAAY,IAAI,IAAI;CAC7B;CAKA,MAAM,OAAO,SAA0B;EACrC,OAAO,YAAY,IAAI,IAAI;CAC7B;CAKA,MAAM,UAAU,OAAO,YAA8C;EACnE,MAAM,SAAS,qBAAqB;EAEpC,IAAI,OAAO,WAAW,GACpB;EAGF,MAAM,WAAW,OAAO,UAAiC;GACvD,MAAM,aAAa,OAAO;GAC1B,IAAI,CAAC,YACH;GAGF,IAAI,SAAS;GACb,MAAM,OAAO,YAA2B;IACtC,IAAI,QACF,MAAM,IAAI,MAAM,iDAAiD,WAAW,KAAI,EAAG;IAGrF,SAAS;IACT,MAAM,SAAS,QAAQ,CAAC;GAC1B;GAEA,MAAM,WAAW,QAAQ,SAAS,IAAI;EACxC;EAEA,MAAM,SAAS,CAAC;CAClB;CAKA,MAAM,eAA6B;EACjC,OAAO,qBAAqB;CAC9B;CAKA,MAAM,cAAoB;EACxB,YAAY,MAAM;EAClB,gBAAgB;CAClB;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAKA,IAAI,0BAAoD;AAKjD,SAAS,6BAAgD;CAC9D,IAAI,CAAC,yBACH,0BAA0B,wBAAwB;CAEpD,OAAO;AACT;AAKO,SAAS,2BAA2B,SAAkC;CAC3E,0BAA0B;AAC5B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 持久化中间件
|
|
3
|
+
*
|
|
4
|
+
* 提供状态持久化功能
|
|
5
|
+
* @module middleware/persist
|
|
6
|
+
*/
|
|
7
|
+
import type { Middleware, PersistMiddlewareOptions, StateTree, StoreId } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* 创建持久化中间件
|
|
10
|
+
*
|
|
11
|
+
* @param options - 持久化选项
|
|
12
|
+
* @returns 持久化中间件
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const persist = createPersistMiddleware({
|
|
17
|
+
* storage: 'localStorage',
|
|
18
|
+
* stores: ['user', 'settings'],
|
|
19
|
+
* debounce: 200,
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* middlewareManager.use(persist)
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function createPersistMiddleware(options?: PersistMiddlewareOptions): Middleware;
|
|
26
|
+
/**
|
|
27
|
+
* 从存储恢复状态
|
|
28
|
+
*
|
|
29
|
+
* @param storeId - Store ID
|
|
30
|
+
* @param options - 持久化选项
|
|
31
|
+
* @returns 恢复的状态或 null
|
|
32
|
+
*/
|
|
33
|
+
export declare function restoreState<S extends StateTree>(storeId: StoreId, options?: PersistMiddlewareOptions): S | null;
|
|
34
|
+
//# sourceMappingURL=persist.d.ts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-core v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:27:33 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
import { debounce } from "../utils/debounce-throttle.js";
|
|
11
|
+
//#region src/middleware/persist.ts
|
|
12
|
+
const defaultOptions = {
|
|
13
|
+
keyPrefix: "ldesign-store:",
|
|
14
|
+
storage: "localStorage",
|
|
15
|
+
debounce: 100,
|
|
16
|
+
serialize: JSON.stringify,
|
|
17
|
+
deserialize: JSON.parse
|
|
18
|
+
};
|
|
19
|
+
function resolveOptions(options) {
|
|
20
|
+
return {
|
|
21
|
+
...defaultOptions,
|
|
22
|
+
...options
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function getStorage(type) {
|
|
26
|
+
if (typeof window === "undefined") return null;
|
|
27
|
+
return type === "localStorage" ? localStorage : sessionStorage;
|
|
28
|
+
}
|
|
29
|
+
function createPersistMiddleware(options = {}) {
|
|
30
|
+
const opts = resolveOptions(options);
|
|
31
|
+
const storage = getStorage(opts.storage);
|
|
32
|
+
const debouncedSave = /* @__PURE__ */ new Map();
|
|
33
|
+
const getKey = (storeId) => {
|
|
34
|
+
return `${opts.keyPrefix}${storeId}`;
|
|
35
|
+
};
|
|
36
|
+
const filterState = (storeId, state) => {
|
|
37
|
+
const paths = opts.paths?.[storeId];
|
|
38
|
+
if (!paths || paths.length === 0) return state;
|
|
39
|
+
const filtered = {};
|
|
40
|
+
for (const path of paths) {
|
|
41
|
+
const keys = path.split(".");
|
|
42
|
+
let source = state;
|
|
43
|
+
let target = filtered;
|
|
44
|
+
for (let i = 0; i < keys.length; i++) {
|
|
45
|
+
const key = keys[i];
|
|
46
|
+
if (i === keys.length - 1) target[key] = source?.[key];
|
|
47
|
+
else {
|
|
48
|
+
target[key] = target[key] || {};
|
|
49
|
+
target = target[key];
|
|
50
|
+
source = source?.[key];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return filtered;
|
|
55
|
+
};
|
|
56
|
+
const saveState = (storeId, state) => {
|
|
57
|
+
if (!storage) return;
|
|
58
|
+
try {
|
|
59
|
+
const filteredState = filterState(storeId, state);
|
|
60
|
+
const serialized = opts.serialize(filteredState);
|
|
61
|
+
storage.setItem(getKey(storeId), serialized);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(`[Persist] \u4FDD\u5B58\u72B6\u6001\u5931\u8D25 (${storeId}):`, error);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const getDebouncedSave = (storeId) => {
|
|
67
|
+
let fn = debouncedSave.get(storeId);
|
|
68
|
+
if (!fn) {
|
|
69
|
+
fn = debounce((state) => saveState(storeId, state), opts.debounce);
|
|
70
|
+
debouncedSave.set(storeId, fn);
|
|
71
|
+
}
|
|
72
|
+
return fn;
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
name: "persist",
|
|
76
|
+
priority: 100,
|
|
77
|
+
handler: async (context, next) => {
|
|
78
|
+
await next();
|
|
79
|
+
const { storeId, type, state } = context;
|
|
80
|
+
if (!type.startsWith("state:")) return;
|
|
81
|
+
if (opts.stores && !opts.stores.includes(storeId)) return;
|
|
82
|
+
getDebouncedSave(storeId)(state);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function restoreState(storeId, options = {}) {
|
|
87
|
+
const opts = resolveOptions(options);
|
|
88
|
+
const storage = getStorage(opts.storage);
|
|
89
|
+
if (!storage) return null;
|
|
90
|
+
try {
|
|
91
|
+
const key = `${opts.keyPrefix}${storeId}`;
|
|
92
|
+
const data = storage.getItem(key);
|
|
93
|
+
if (data) return opts.deserialize(data);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error(`[Persist] \u6062\u590D\u72B6\u6001\u5931\u8D25 (${storeId}):`, error);
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
export { createPersistMiddleware, restoreState };
|
|
101
|
+
/*! End of @composy/store-core | Powered by @composy/builder */
|
|
102
|
+
//# sourceMappingURL=persist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persist.js","names":[],"sources":["../../src/middleware/persist.ts"],"sourcesContent":["/**\n * 持久化中间件\n *\n * 提供状态持久化功能\n * @module middleware/persist\n */\n\nimport type { Middleware, MiddlewareContext, PersistMiddlewareOptions, StateTree, StoreId } from '../types'\nimport { debounce } from '../utils/debounce-throttle'\n\ntype ResolvedPersistMiddlewareOptions = Required<\n Pick<PersistMiddlewareOptions, 'debounce' | 'deserialize' | 'keyPrefix' | 'serialize' | 'storage'>\n> & Omit<PersistMiddlewareOptions, 'debounce' | 'deserialize' | 'keyPrefix' | 'serialize' | 'storage'>\n\n/**\n * 默认持久化选项\n */\nconst defaultOptions: ResolvedPersistMiddlewareOptions = {\n keyPrefix: 'ldesign-store:',\n storage: 'localStorage',\n debounce: 100,\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n}\n\nfunction resolveOptions(options: PersistMiddlewareOptions): ResolvedPersistMiddlewareOptions {\n return { ...defaultOptions, ...options }\n}\n\n/**\n * 获取存储对象\n */\nfunction getStorage(type: 'localStorage' | 'sessionStorage'): Storage | null {\n if (typeof window === 'undefined') {\n return null\n }\n return type === 'localStorage' ? localStorage : sessionStorage\n}\n\n/**\n * 创建持久化中间件\n *\n * @param options - 持久化选项\n * @returns 持久化中间件\n *\n * @example\n * ```typescript\n * const persist = createPersistMiddleware({\n * storage: 'localStorage',\n * stores: ['user', 'settings'],\n * debounce: 200,\n * })\n *\n * middlewareManager.use(persist)\n * ```\n */\nexport function createPersistMiddleware(\n options: PersistMiddlewareOptions = {},\n): Middleware {\n const opts = resolveOptions(options)\n const storage = getStorage(opts.storage)\n\n /** 保存状态的防抖函数映射 */\n const debouncedSave = new Map<StoreId, (state: StateTree) => void>()\n\n /**\n * 获取存储键名\n */\n const getKey = (storeId: StoreId): string => {\n return `${opts.keyPrefix}${storeId}`\n }\n\n /**\n * 筛选需要持久化的状态路径\n */\n const filterState = (storeId: StoreId, state: StateTree): StateTree => {\n const paths = opts.paths?.[storeId]\n if (!paths || paths.length === 0) {\n return state\n }\n\n const filtered: StateTree = {}\n for (const path of paths) {\n const keys = path.split('.')\n let source: unknown = state\n let target: StateTree = filtered\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]\n if (i === keys.length - 1) {\n target[key] = (source as StateTree)?.[key]\n }\n else {\n target[key] = target[key] || {}\n target = target[key] as StateTree\n source = (source as StateTree)?.[key]\n }\n }\n }\n\n return filtered\n }\n\n /**\n * 保存状态到存储\n */\n const saveState = (storeId: StoreId, state: StateTree): void => {\n if (!storage) return\n\n try {\n const filteredState = filterState(storeId, state)\n const serialized = opts.serialize(filteredState)\n storage.setItem(getKey(storeId), serialized)\n }\n catch (error) {\n console.error(`[Persist] 保存状态失败 (${storeId}):`, error)\n }\n }\n\n /**\n * 获取或创建防抖保存函数\n */\n const getDebouncedSave = (storeId: StoreId): (state: StateTree) => void => {\n let fn = debouncedSave.get(storeId)\n if (!fn) {\n fn = debounce((state: StateTree) => saveState(storeId, state), opts.debounce)\n debouncedSave.set(storeId, fn)\n }\n return fn\n }\n\n return {\n name: 'persist',\n priority: 100, // 最后执行\n\n handler: async (context: MiddlewareContext, next: () => void | Promise<void>) => {\n await next()\n\n const { storeId, type, state } = context\n\n // 只在状态变化时持久化\n if (!type.startsWith('state:')) {\n return\n }\n\n // 检查是否需要持久化此 Store\n if (opts.stores && !opts.stores.includes(storeId)) {\n return\n }\n\n // 使用防抖保存\n getDebouncedSave(storeId)(state)\n },\n }\n}\n\n/**\n * 从存储恢复状态\n *\n * @param storeId - Store ID\n * @param options - 持久化选项\n * @returns 恢复的状态或 null\n */\nexport function restoreState<S extends StateTree>(\n storeId: StoreId,\n options: PersistMiddlewareOptions = {},\n): S | null {\n const opts = resolveOptions(options)\n const storage = getStorage(opts.storage)\n\n if (!storage) return null\n\n try {\n const key = `${opts.keyPrefix}${storeId}`\n const data = storage.getItem(key)\n if (data) {\n return opts.deserialize(data) as S\n }\n }\n catch (error) {\n console.error(`[Persist] 恢复状态失败 (${storeId}):`, error)\n }\n\n return null\n}\n\n"],"mappings":";;;;;;;;;;;AAiBA,MAAM,iBAAmD;CACvD,WAAW;CACX,SAAS;CACT,UAAU;CACV,WAAW,KAAK;CAChB,aAAa,KAAK;AACpB;AAEA,SAAS,eAAe,SAAqE;CAC3F,OAAO;EAAE,GAAG;EAAgB,GAAG;CAAQ;AACzC;AAKA,SAAS,WAAW,MAAyD;CAC3E,IAAI,OAAO,WAAW,aACpB,OAAO;CAET,OAAO,SAAS,iBAAiB,eAAe;AAClD;AAmBO,SAAS,wBACd,UAAoC,CAAC,GACzB;CACZ,MAAM,OAAO,eAAe,OAAO;CACnC,MAAM,UAAU,WAAW,KAAK,OAAO;CAGvC,MAAM,gCAAgB,IAAI,IAAyC;CAKnE,MAAM,UAAU,YAA6B;EAC3C,OAAO,GAAG,KAAK,YAAY;CAC7B;CAKA,MAAM,eAAe,SAAkB,UAAgC;EACrE,MAAM,QAAQ,KAAK,QAAQ;EAC3B,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,OAAO;EAGT,MAAM,WAAsB,CAAC;EAC7B,KAAA,MAAW,QAAQ,OAAO;GACxB,MAAM,OAAO,KAAK,MAAM,GAAG;GAC3B,IAAI,SAAkB;GACtB,IAAI,SAAoB;GAExB,KAAA,IAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;IACpC,MAAM,MAAM,KAAK;IACjB,IAAI,MAAM,KAAK,SAAS,GACtB,OAAO,OAAQ,SAAuB;SAEnC;KACH,OAAO,OAAO,OAAO,QAAQ,CAAC;KAC9B,SAAS,OAAO;KAChB,SAAU,SAAuB;IACnC;GACF;EACF;EAEA,OAAO;CACT;CAKA,MAAM,aAAa,SAAkB,UAA2B;EAC9D,IAAI,CAAC,SAAS;EAEd,IAAI;GACF,MAAM,gBAAgB,YAAY,SAAS,KAAK;GAChD,MAAM,aAAa,KAAK,UAAU,aAAa;GAC/C,QAAQ,QAAQ,OAAO,OAAO,GAAG,UAAU;EAC7C,SACO,OAAO;GACZ,QAAQ,MAAM,mDAAqB,QAAO,KAAM,KAAK;EACvD;CACF;CAKA,MAAM,oBAAoB,YAAiD;EACzE,IAAI,KAAK,cAAc,IAAI,OAAO;EAClC,IAAI,CAAC,IAAI;GACP,KAAK,UAAU,UAAqB,UAAU,SAAS,KAAK,GAAG,KAAK,QAAQ;GAC5E,cAAc,IAAI,SAAS,EAAE;EAC/B;EACA,OAAO;CACT;CAEA,OAAO;EACL,MAAM;EACN,UAAU;EAEV,SAAS,OAAO,SAA4B,SAAqC;GAC/E,MAAM,KAAK;GAEX,MAAM,EAAE,SAAS,MAAM,UAAU;GAGjC,IAAI,CAAC,KAAK,WAAW,QAAQ,GAC3B;GAIF,IAAI,KAAK,UAAU,CAAC,KAAK,OAAO,SAAS,OAAO,GAC9C;GAIF,iBAAiB,OAAO,CAAA,CAAE,KAAK;EACjC;CACF;AACF;AASO,SAAS,aACd,SACA,UAAoC,CAAC,GAC3B;CACV,MAAM,OAAO,eAAe,OAAO;CACnC,MAAM,UAAU,WAAW,KAAK,OAAO;CAEvC,IAAI,CAAC,SAAS,OAAO;CAErB,IAAI;EACF,MAAM,MAAM,GAAG,KAAK,YAAY;EAChC,MAAM,OAAO,QAAQ,QAAQ,GAAG;EAChC,IAAI,MACF,OAAO,KAAK,YAAY,IAAI;CAEhC,SACO,OAAO;EACZ,QAAQ,MAAM,mDAAqB,QAAO,KAAM,KAAK;CACvD;CAEA,OAAO;AACT"}
|