@libeilong/mobx
Advanced tools
Sorry, the diff of this file is too big to display
+396
| import { action, computed, extendObservable, makeObservable, observable, reaction } from "mobx"; | ||
| import React from "react"; | ||
| //#region src/func/assignMobx.ts | ||
| function assignMobx(target, source) { | ||
| const toAdd = {}; | ||
| const keys = Object.keys(source); | ||
| for (const key of keys) if (key in target) target[key] = source[key]; | ||
| else toAdd[key] = source[key]; | ||
| if (Object.keys(toAdd).length > 0) extendObservable(target, toAdd); | ||
| } | ||
| //#endregion | ||
| //#region src/func/createPersistentObservable.ts | ||
| /** | ||
| * 创建一个 MobX 可观察对象,并将其状态与 localStorage 双向同步。 | ||
| * | ||
| * @param options - 配置对象 | ||
| * @returns 一个可以直接使用的 MobX 可观察代理对象 | ||
| */ | ||
| function createPersistentObservable(options) { | ||
| const { key, defaultValue = {}, version = 1 } = options; | ||
| const state = observable(loadFromLocalStorage(key, defaultValue, version)); | ||
| reaction(() => { | ||
| return JSON.stringify(state); | ||
| }, (serializedState) => { | ||
| try { | ||
| const dataToStore = { | ||
| version, | ||
| data: JSON.parse(serializedState) | ||
| }; | ||
| localStorage.setItem(key, JSON.stringify(dataToStore)); | ||
| } catch (error) { | ||
| console.warn("Failed to save state to localStorage:", error); | ||
| } | ||
| }); | ||
| return state; | ||
| } | ||
| /** | ||
| * 从 localStorage 加载数据的内部辅助函数 | ||
| */ | ||
| function loadFromLocalStorage(key, defaultValue, version) { | ||
| const storedJson = localStorage.getItem(key); | ||
| if (!storedJson) return defaultValue; | ||
| try { | ||
| const storedData = JSON.parse(storedJson); | ||
| if (storedData && storedData.version === version) return Object.assign({}, defaultValue, storedData.data); | ||
| else return defaultValue; | ||
| } catch (error) { | ||
| return defaultValue; | ||
| } | ||
| } | ||
| //#endregion | ||
| //#region src/modelManager/Model.ts | ||
| function Model(options = {}) { | ||
| return (target) => { | ||
| target.prototype._modelOptions = { | ||
| ...target.prototype._modelOptions, | ||
| ...options | ||
| }; | ||
| }; | ||
| } | ||
| /** | ||
| * @param target 可以是类或其实例 | ||
| * @returns 返回模型选项 | ||
| */ | ||
| function getModelOptions(target) { | ||
| if (typeof target === "function") return target.prototype._modelOptions || {}; | ||
| else if (target && typeof target === "object") return target._modelOptions || {}; | ||
| return {}; | ||
| } | ||
| function getPrimaryKey(target) { | ||
| if (!target) return void 0; | ||
| if (typeof target !== "object" && typeof target !== "function") return void 0; | ||
| return getModelOptions(target).primaryKey; | ||
| } | ||
| //#endregion | ||
| //#region src/modelManager/Relations.ts | ||
| let RelationType = /* @__PURE__ */ function(RelationType$1) { | ||
| RelationType$1["OneToMany"] = "OneToMany"; | ||
| RelationType$1["ManyToOne"] = "ManyToOne"; | ||
| RelationType$1["OneToOne"] = "OneToOne"; | ||
| RelationType$1["ManyToMany"] = "ManyToMany"; | ||
| return RelationType$1; | ||
| }({}); | ||
| function createRelationDecorator(relationType, modelClass) { | ||
| return function(target, propertyKey) { | ||
| if (!target.constructor._relations) target.constructor._relations = {}; | ||
| target.constructor._relations[propertyKey] = { | ||
| type: relationType, | ||
| modelClass | ||
| }; | ||
| }; | ||
| } | ||
| function OneToMany(modelClass) { | ||
| return createRelationDecorator(RelationType.OneToMany, modelClass); | ||
| } | ||
| function ManyToOne(modelClass) { | ||
| return createRelationDecorator(RelationType.ManyToOne, modelClass); | ||
| } | ||
| function OneToOne(modelClass) { | ||
| return createRelationDecorator(RelationType.OneToOne, modelClass); | ||
| } | ||
| function ManyToMany(modelClass) { | ||
| return createRelationDecorator(RelationType.ManyToMany, modelClass); | ||
| } | ||
| function getRelations(target) { | ||
| if (typeof target === "function") return target._relations || {}; | ||
| return target.constructor._relations || {}; | ||
| } | ||
| /** | ||
| * 解析模型类,支持直接类引用和函数形式 | ||
| */ | ||
| function resolveModelClass(modelClass) { | ||
| return typeof modelClass === "function" && modelClass.length === 0 ? modelClass() : modelClass; | ||
| } | ||
| //#endregion | ||
| //#region src/modelManager/assignModel.ts | ||
| function assignModel(instance, it) { | ||
| const relations = getRelations(instance); | ||
| const toAdd = {}; | ||
| const keys = Object.keys(it); | ||
| for (const key of keys) { | ||
| const relation = relations[key]; | ||
| if (relation) { | ||
| const modelClass = resolveModelClass(relation.modelClass); | ||
| const { primaryKey, createInstance } = getModelOptions(modelClass); | ||
| if (!primaryKey) continue; | ||
| if ([RelationType.ManyToMany, RelationType.OneToMany].includes(relation.type)) { | ||
| if (!Array.isArray(it[key])) throw new Error(`Expected an array for relation ${key.toString()}, but got ${typeof it[key]}`); | ||
| const value = it[key].map((element) => { | ||
| const params = typeof element === "object" ? element : { [primaryKey]: element }; | ||
| const it$1 = instance[key]?.find((i) => i[primaryKey] === params[primaryKey]); | ||
| if (it$1) return it$1; | ||
| return createInstance ? createInstance(params) : new modelClass(params); | ||
| }); | ||
| if (key in instance) instance[key] = value; | ||
| else toAdd[key] = value; | ||
| } else { | ||
| const params = typeof it[key] === "object" ? it[key] : { [primaryKey]: it[key] }; | ||
| const value = createInstance ? createInstance(params) : new modelClass(params); | ||
| if (key in instance) instance[key] = value; | ||
| else toAdd[key] = value; | ||
| } | ||
| } else if (key in instance) instance[key] = it[key]; | ||
| else toAdd[key] = it[key]; | ||
| } | ||
| if (Object.keys(toAdd).length > 0) extendObservable(instance, toAdd); | ||
| return instance; | ||
| } | ||
| //#endregion | ||
| //#region src/stores/CountDown.ts | ||
| var CountDownStore = class { | ||
| initCount = 60; | ||
| defaultText = "获取验证码"; | ||
| countTemplate = "{{count}}s"; | ||
| constructor(opts = {}) { | ||
| this.initCount = opts.initCount ?? 60; | ||
| this.defaultText = opts.defaultText ?? "获取验证码"; | ||
| this.countTemplate = opts.countTemplate ?? "{{count}}s"; | ||
| this.count = this.initCount; | ||
| makeObservable(this, { | ||
| count: observable, | ||
| isRunning: observable | ||
| }); | ||
| } | ||
| get text() { | ||
| if (!this.isRunning) return this.defaultText; | ||
| return this.countTemplate.replace("{{count}}", this.count.toString()); | ||
| } | ||
| count = 0; | ||
| isRunning = false; | ||
| start = () => { | ||
| if (this.isRunning) return; | ||
| this.isRunning = true; | ||
| this.count = this.initCount; | ||
| let down = () => { | ||
| setTimeout(() => { | ||
| this.count--; | ||
| if (this.count === 0) this.isRunning = false; | ||
| else down(); | ||
| }, 1e3); | ||
| }; | ||
| down(); | ||
| }; | ||
| }; | ||
| //#endregion | ||
| //#region src/stores/list/ListFooterAdapter.ts | ||
| var BaseFooterListAdapter = class { | ||
| createElement = (props, children) => { | ||
| return React.createElement("div", { | ||
| style: { | ||
| padding: "12px", | ||
| display: "flex", | ||
| alignItems: "center", | ||
| justifyContent: "center" | ||
| }, | ||
| ...props ?? {} | ||
| }, children); | ||
| }; | ||
| renderLoading = () => this.createElement(void 0, "加载中..."); | ||
| renderNotData = () => this.createElement(void 0, "暂无数据"); | ||
| renderNotMore = () => this.createElement(void 0, "没有更多数据了"); | ||
| renderFailure = (err, onRetry) => this.createElement({ onClick: onRetry }, "加载失败,请点击重试"); | ||
| }; | ||
| //#endregion | ||
| //#region src/stores/list/List.ts | ||
| let ListState = /* @__PURE__ */ function(ListState$1) { | ||
| ListState$1[ListState$1["normal"] = 0] = "normal"; | ||
| ListState$1[ListState$1["abort"] = 1] = "abort"; | ||
| ListState$1[ListState$1["loading"] = 2] = "loading"; | ||
| ListState$1[ListState$1["success"] = 3] = "success"; | ||
| ListState$1[ListState$1["failure"] = 4] = "failure"; | ||
| ListState$1[ListState$1["complete"] = 5] = "complete"; | ||
| return ListState$1; | ||
| }({}); | ||
| var ListStore = class ListStore { | ||
| /** 起始页码 */ | ||
| static startPageNumber = 1; | ||
| constructor(adapter = new BaseFooterListAdapter()) { | ||
| this.adapter = adapter; | ||
| makeObservable(this, { | ||
| list: observable, | ||
| hasMore: observable, | ||
| listLoading: observable, | ||
| paging: observable, | ||
| err: observable, | ||
| notData: computed, | ||
| state: computed, | ||
| stateWidget: computed, | ||
| fetch: action, | ||
| reset: action | ||
| }); | ||
| } | ||
| list = []; | ||
| hasMore = true; | ||
| listLoading = true; | ||
| err = void 0; | ||
| firstFetch = true; | ||
| needPagination = true; | ||
| paging = { | ||
| pageNumber: ListStore.startPageNumber, | ||
| pageSize: 10, | ||
| total: 0 | ||
| }; | ||
| get notData() { | ||
| if (this.listLoading) return false; | ||
| if (this.list.length > 0) return false; | ||
| return true; | ||
| } | ||
| get state() { | ||
| if (this.listLoading) return ListState.loading; | ||
| if (this.err) return ListState.failure; | ||
| if (this.notData) return ListState.complete; | ||
| if (!this.hasMore) return ListState.complete; | ||
| return ListState.loading; | ||
| } | ||
| get stateWidget() { | ||
| switch (this.state) { | ||
| case ListState.loading: return this.adapter.renderLoading(); | ||
| case ListState.complete: return this.notData ? this.adapter.renderNotData() : this.adapter.renderNotMore(); | ||
| case ListState.failure: return this.adapter.renderFailure(this.err, this.fetch); | ||
| default: return ""; | ||
| } | ||
| } | ||
| onFirstFetch; | ||
| fetch = async (opts) => { | ||
| if (this.firstFetch) this.firstFetch = false; | ||
| else if (!this.listLoading && opts?.reset) if (typeof opts.reset === "object") this.reset(opts.reset); | ||
| else this.reset(); | ||
| else if (this.listLoading || !this.hasMore) return; | ||
| try { | ||
| this.err = void 0; | ||
| this.listLoading = true; | ||
| if (this.onFirstFetch) { | ||
| await this.onFirstFetch(); | ||
| delete this.onFirstFetch; | ||
| } | ||
| const { list, total } = await this.fetchList(); | ||
| this.consumeFetchList({ | ||
| list, | ||
| total | ||
| }); | ||
| } catch (err) { | ||
| this.err = err; | ||
| console.log(err); | ||
| } finally { | ||
| this.listLoading = false; | ||
| } | ||
| }; | ||
| /** 消费 fetchList 的结果 */ | ||
| consumeFetchList = (opts) => { | ||
| const { list, total } = opts; | ||
| if (this.paging.pageNumber === 1) this.list = list; | ||
| else this.list.push(...list); | ||
| if (total !== void 0 && total !== null) { | ||
| this.paging.total = total; | ||
| if (this.list.length >= total) this.hasMore = false; | ||
| } else if (list.length < this.paging.pageSize) this.hasMore = false; | ||
| this.paging.pageNumber++; | ||
| }; | ||
| reset = (options) => { | ||
| this.paging.pageNumber = 1; | ||
| this.listLoading = false; | ||
| this.hasMore = true; | ||
| if (options?.list) this.list = []; | ||
| }; | ||
| }; | ||
| //#endregion | ||
| //#region src/stores/Result.ts | ||
| var ResultStore = class { | ||
| constructor() { | ||
| makeObservable(this, { | ||
| loading: observable, | ||
| result: observable, | ||
| firstFetch: observable | ||
| }); | ||
| } | ||
| loading = true; | ||
| firstFetch = true; | ||
| result = void 0; | ||
| err; | ||
| fetch = async () => { | ||
| if (this.loading && !this.firstFetch) return; | ||
| this.firstFetch = false; | ||
| try { | ||
| this.loading = true; | ||
| this.result = await this.fetchResult(); | ||
| } catch (err) { | ||
| this.err = err; | ||
| } finally { | ||
| this.loading = false; | ||
| } | ||
| }; | ||
| }; | ||
| //#endregion | ||
| //#region src/stores/TableList.ts | ||
| var TableListStore = class { | ||
| constructor() { | ||
| makeObservable(this, { | ||
| list: observable, | ||
| loading: observable, | ||
| paging: observable, | ||
| total: observable, | ||
| fetch: action, | ||
| reset: action | ||
| }); | ||
| } | ||
| list = []; | ||
| loading = false; | ||
| paging = { | ||
| current: 1, | ||
| pageSize: 10 | ||
| }; | ||
| total = 0; | ||
| get totalPage() { | ||
| return Math.ceil(this.total / this.paging.pageSize); | ||
| } | ||
| onFirstFetch; | ||
| fetch = async (opts) => { | ||
| if (this.loading) return; | ||
| const { reset } = opts || {}; | ||
| if (reset) this.reset(); | ||
| try { | ||
| this.loading = true; | ||
| if (this.onFirstFetch) { | ||
| await this.onFirstFetch(); | ||
| delete this.onFirstFetch; | ||
| } | ||
| const { list, total } = await this.fetchList(); | ||
| this.list = list || []; | ||
| this.total = total || 0; | ||
| } catch (err) { | ||
| console.log(err); | ||
| } finally { | ||
| this.loading = false; | ||
| } | ||
| }; | ||
| reset = () => { | ||
| this.paging.current = 1; | ||
| this.total = 0; | ||
| this.loading = false; | ||
| }; | ||
| }; | ||
| //#endregion | ||
| export { BaseFooterListAdapter, CountDownStore, ListStore, ManyToMany, ManyToOne, Model, OneToMany, OneToOne, ResultStore, TableListStore, assignMobx, assignModel, createPersistentObservable, getModelOptions, getPrimaryKey, getRelations, resolveModelClass }; | ||
| //# sourceMappingURL=index.mjs.map |
| {"version":3,"file":"index.mjs","names":["toAdd: any","dataToStore: StoredData<T>","storedData: StoredData<T>","toAdd: any","it","adapter: IListFooterAdapter","err: any","err: any","err: any"],"sources":["../src/func/assignMobx.ts","../src/func/createPersistentObservable.ts","../src/modelManager/Model.ts","../src/modelManager/Relations.ts","../src/modelManager/assignModel.ts","../src/stores/CountDown.ts","../src/stores/list/ListFooterAdapter.ts","../src/stores/list/List.ts","../src/stores/Result.ts","../src/stores/TableList.ts"],"sourcesContent":["import { extendObservable } from \"mobx\";\n\nexport function assignMobx(target: any, source: any) {\n const toAdd: any = {};\n const keys = Object.keys(source);\n\n for (const key of keys) {\n if (key in target) {\n target[key] = source[key];\n } else {\n toAdd[key] = source[key];\n }\n }\n\n if (Object.keys(toAdd).length > 0) {\n extendObservable(target, toAdd);\n }\n}","import { observable, reaction } from 'mobx'\n\n// StoredData 接口\ninterface StoredData<T> {\n version: string | number\n data: T\n}\n\n// Options 接口\nexport interface PersistentObservableOptions<T> {\n /** 存储的键 */\n key: string\n /** 默认值,如果 localStorage 中没有数据或版本不匹配时使用 */\n defaultValue?: T\n /** 版本号,用于数据迁移 */\n version?: string | number\n}\n\n/**\n * 创建一个 MobX 可观察对象,并将其状态与 localStorage 双向同步。\n *\n * @param options - 配置对象\n * @returns 一个可以直接使用的 MobX 可观察代理对象\n */\nexport function createPersistentObservable<T extends object>(options: PersistentObservableOptions<T>): T {\n // 如果 options 中没有提供 defaultValue,则默认为一个空对象\n const { key, defaultValue = {}, version = 1 } = options\n\n // 从 localStorage 加载初始值\n const initialValue = loadFromLocalStorage(key, defaultValue as T, version)\n\n // 创建 MobX 可观察对象\n const state = observable(initialValue) as T\n\n // 使用 MobX reaction 监听状态变化并同步到 localStorage\n reaction(\n () => {\n // 返回整个 state 对象,MobX 会自动追踪其中的变化\n return JSON.stringify(state)\n },\n (serializedState) => {\n try {\n const newValue = JSON.parse(serializedState)\n const dataToStore: StoredData<T> = {\n version: version,\n data: newValue,\n }\n localStorage.setItem(key, JSON.stringify(dataToStore))\n } catch (error) {\n console.warn('Failed to save state to localStorage:', error)\n }\n },\n )\n\n return state\n}\n\n/**\n * 从 localStorage 加载数据的内部辅助函数\n */\nfunction loadFromLocalStorage<T extends object>(key: string, defaultValue: T, version: string | number): T {\n const storedJson = localStorage.getItem(key)\n\n if (!storedJson) {\n return defaultValue\n }\n\n try {\n const storedData: StoredData<T> = JSON.parse(storedJson)\n\n if (storedData && storedData.version === version) {\n // 合并以确保新增的默认字段能够生效\n return Object.assign({}, defaultValue, storedData.data)\n } else {\n return defaultValue\n }\n } catch (error) {\n return defaultValue\n }\n}\n","export interface ModelOptions {\n primaryKey?: string\n createInstance?: (params: any) => any\n}\n\nexport function Model(options: ModelOptions = {}): ClassDecorator {\n return (target: Function) => {\n target.prototype._modelOptions = {\n ...target.prototype._modelOptions,\n ...options,\n }\n }\n}\n\n/**\n * @param target 可以是类或其实例\n * @returns 返回模型选项\n */\nexport function getModelOptions(target: any): ModelOptions {\n if (typeof target === 'function') {\n return target.prototype._modelOptions || {}\n } else if (target && typeof target === 'object') {\n return target._modelOptions || {}\n }\n return {}\n}\n\nexport function getPrimaryKey(target: any): string | undefined {\n if (!target) return undefined\n if (typeof target !== 'object' && typeof target !== 'function') return undefined\n\n const options = getModelOptions(target)\n return options.primaryKey\n}\n","// 关系类型枚举\nexport enum RelationType {\n OneToMany = 'OneToMany',\n ManyToOne = 'ManyToOne',\n OneToOne = 'OneToOne',\n ManyToMany = 'ManyToMany',\n}\n\n// 关系元数据接口\nexport interface RelationMetadata {\n type: RelationType\n modelClass: any | (() => any)\n}\n\n// 通用关系装饰器创建函数 - 使用传统装饰器语法\nfunction createRelationDecorator<T>(relationType: RelationType, modelClass: T | (() => T)) {\n return function(target: any, propertyKey: string | symbol) {\n // 确保构造函数有 _relations 属性\n if (!target.constructor._relations) {\n target.constructor._relations = {}\n }\n \n // 存储关系元数据\n target.constructor._relations[propertyKey] = {\n type: relationType,\n modelClass,\n }\n }\n}\n\nexport function OneToMany<T extends new () => any>(modelClass: T | (() => T)) {\n return createRelationDecorator(RelationType.OneToMany, modelClass)\n}\n\nexport function ManyToOne<T extends new () => any>(modelClass: T | (() => T)) {\n return createRelationDecorator(RelationType.ManyToOne, modelClass)\n}\n\nexport function OneToOne<T extends new () => any>(modelClass: T | (() => T)) {\n return createRelationDecorator(RelationType.OneToOne, modelClass)\n}\n\nexport function ManyToMany<T extends new () => any>(modelClass: T | (() => T)) {\n return createRelationDecorator(RelationType.ManyToMany, modelClass) \n}\n\nexport function getRelations(target: any): Record<string, RelationMetadata> {\n if (typeof target === 'function') {\n return target._relations || {}\n }\n\n return target.constructor._relations || {}\n}\n\n/** \n * 解析模型类,支持直接类引用和函数形式\n */\nexport function resolveModelClass(modelClass: any | (() => any)) {\n return typeof modelClass === 'function' && modelClass.length === 0\n ? modelClass()\n : modelClass\n}\n","import { extendObservable } from 'mobx'\nimport { getModelOptions } from './Model'\nimport { getRelations, RelationType, resolveModelClass } from './Relations'\n\nexport function assignModel<T extends object>(instance: T, it: { [K in keyof T]?: any }): T {\n const relations = getRelations(instance)\n const toAdd: any = {}\n\n const keys = Object.keys(it) as (keyof T)[]\n for (const key of keys) {\n // @ts-ignore\n const relation = relations[key]\n\n if (relation) {\n const modelClass = resolveModelClass(relation.modelClass)\n const { primaryKey, createInstance } = getModelOptions(modelClass)\n if (!primaryKey) continue\n\n if ([RelationType.ManyToMany, RelationType.OneToMany].includes(relation.type)) {\n if (!Array.isArray(it[key])) {\n throw new Error(`Expected an array for relation ${key.toString()}, but got ${typeof it[key]}`)\n }\n\n // @ts-ignore\n const value = it[key].map((element: any) => {\n const params = typeof element === 'object' ? element : { [primaryKey]: element }\n // @ts-ignore\n const it = instance[key]?.find((i: any) => i[primaryKey] === params[primaryKey])\n if (it) return it\n\n return createInstance ? createInstance(params) : new modelClass(params)\n })\n\n if (key in instance) {\n // @ts-ignore\n instance[key] = value\n } else {\n toAdd[key] = value\n }\n } else {\n const params = typeof it[key] === 'object' ? it[key] : { [primaryKey]: it[key] }\n const value = createInstance ? createInstance(params) : new modelClass(params)\n\n if (key in instance) {\n instance[key] = value\n } else {\n toAdd[key] = value\n }\n }\n } else {\n if (key in instance) {\n // @ts-ignore\n instance[key] = it[key]\n } else {\n toAdd[key] = it[key]\n }\n }\n }\n\n if (Object.keys(toAdd).length > 0) {\n extendObservable(instance, toAdd)\n }\n\n return instance\n}\n","import { makeObservable, observable } from 'mobx'\n\nexport class CountDownStore {\n initCount = 60\n defaultText = '获取验证码'\n countTemplate = '{{count}}s'\n\n constructor(opts: { initCount?: number; defaultText?: string; countTemplate?: string } = {}) {\n this.initCount = opts.initCount ?? 60\n this.defaultText = opts.defaultText ?? '获取验证码'\n this.countTemplate = opts.countTemplate ?? '{{count}}s'\n this.count = this.initCount\n makeObservable(this, {\n count: observable,\n isRunning: observable,\n })\n }\n\n get text() {\n if (!this.isRunning) return this.defaultText\n return this.countTemplate.replace('{{count}}', this.count.toString())\n }\n\n count = 0\n\n isRunning = false\n\n start = () => {\n if (this.isRunning) return\n this.isRunning = true\n this.count = this.initCount\n let down = () => {\n setTimeout(() => {\n this.count--\n if (this.count === 0) {\n this.isRunning = false\n } else {\n down()\n }\n }, 1000)\n }\n\n down()\n }\n}\n","import React, { ReactNode } from 'react'\n\nexport interface IListFooterAdapter {\n renderLoading: () => ReactNode\n renderNotData: () => ReactNode\n renderNotMore: () => ReactNode\n renderFailure: (err: Error, onRetry: () => void) => ReactNode\n}\n\nexport class BaseFooterListAdapter implements IListFooterAdapter {\n createElement = (\n props?: React.ClassAttributes<HTMLElement> & React.HTMLAttributes<HTMLElement>,\n children?: ReactNode,\n ) => {\n return React.createElement(\n 'div',\n {\n style: {\n padding: '12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n ...(props ?? {}),\n },\n children,\n )\n }\n\n renderLoading = () => this.createElement(undefined, '加载中...')\n renderNotData = () => this.createElement(undefined, '暂无数据')\n renderNotMore = () => this.createElement(undefined, '没有更多数据了')\n renderFailure = (err: Error, onRetry: () => void) => this.createElement({ onClick: onRetry }, '加载失败,请点击重试')\n}\n","import { action, computed, makeObservable, observable } from 'mobx'\nimport { ReactNode } from 'react'\nimport { BaseFooterListAdapter, IListFooterAdapter } from './ListFooterAdapter'\n\nexport enum ListState {\n normal = 0, // 普通\n abort = 1, // 中止\n loading = 2, // 加载中\n success = 3, // 加载成功\n failure = 4, // 加载失败\n complete = 5, // 加载完成(无新数据)\n}\n\nexport abstract class ListStore<\n T = typeof ListStore.prototype.fetchList extends () => Promise<{\n list: (infer A)[]\n total: number\n }>\n ? A\n : any,\n> {\n /** 起始页码 */\n static startPageNumber: 0 | 1 = 1\n\n constructor(private adapter: IListFooterAdapter = new BaseFooterListAdapter()) {\n makeObservable(this, {\n list: observable,\n hasMore: observable,\n listLoading: observable,\n paging: observable,\n err: observable,\n notData: computed,\n state: computed,\n stateWidget: computed,\n fetch: action,\n reset: action,\n })\n }\n\n list: T[] = []\n hasMore = true\n listLoading = true\n err?: Error = undefined\n firstFetch = true\n\n needPagination = true\n\n paging = {\n pageNumber: ListStore.startPageNumber as number,\n pageSize: 10,\n total: 0,\n }\n\n get notData() {\n if (this.listLoading) return false\n if (this.list.length > 0) return false\n return true\n }\n\n get state() {\n if (this.listLoading) return ListState.loading\n if (this.err) return ListState.failure\n if (this.notData) return ListState.complete\n if (!this.hasMore) return ListState.complete\n return ListState.loading\n }\n\n get stateWidget(): ReactNode {\n switch (this.state) {\n case ListState.loading:\n return this.adapter.renderLoading()\n case ListState.complete:\n return this.notData ? this.adapter.renderNotData() : this.adapter.renderNotMore()\n case ListState.failure:\n return this.adapter.renderFailure(this.err!, this.fetch)\n default:\n return ''\n }\n }\n\n abstract fetchList: () => Promise<{\n list: T[]\n total: number\n }>\n\n onFirstFetch?: () => Promise<void>\n\n fetch = async (opts?: { reset?: boolean | { list?: boolean } }) => {\n if (this.firstFetch) {\n this.firstFetch = false\n } else if (!this.listLoading && opts?.reset) {\n if (typeof opts.reset === 'object') {\n this.reset(opts.reset)\n } else {\n this.reset()\n }\n } else if (this.listLoading || !this.hasMore) {\n return\n }\n\n try {\n this.err = undefined\n this.listLoading = true\n\n if (this.onFirstFetch) {\n await this.onFirstFetch()\n delete this.onFirstFetch\n }\n\n const { list, total } = await this.fetchList()\n this.consumeFetchList({ list, total })\n } catch (err: any) {\n this.err = err\n console.log(err)\n } finally {\n this.listLoading = false\n }\n }\n\n /** 消费 fetchList 的结果 */\n consumeFetchList = (opts: { list: T[]; total: number }) => {\n const { list, total } = opts\n\n if (this.paging.pageNumber === 1) {\n this.list = list\n } else {\n this.list.push(...list)\n }\n\n if (total !== undefined && total !== null) {\n this.paging.total = total\n if (this.list.length >= total) this.hasMore = false\n } else if (list.length < this.paging.pageSize) {\n this.hasMore = false\n }\n\n this.paging.pageNumber++\n }\n\n reset = (options?: { list?: boolean }) => {\n this.paging.pageNumber = 1\n this.listLoading = false\n this.hasMore = true\n if (options?.list) this.list = []\n }\n}\n","import { makeObservable, observable } from 'mobx'\n\nexport abstract class ResultStore<\n T = typeof ResultStore.prototype.fetchResult extends () => Promise<infer A> ? A : unknown,\n> {\n constructor() {\n makeObservable(this, {\n loading: observable,\n result: observable,\n firstFetch: observable,\n })\n }\n\n loading = true\n\n firstFetch = true\n\n result?: T = undefined\n\n err?: Error\n\n fetch = async () => {\n if (this.loading && !this.firstFetch) return\n this.firstFetch = false\n\n try {\n this.loading = true\n this.result = await this.fetchResult()\n } catch (err: any) {\n this.err = err\n } finally {\n this.loading = false\n }\n }\n\n abstract fetchResult: () => Promise<T>\n}\n","import { action, makeObservable, observable } from 'mobx'\n\nexport abstract class TableListStore<\n T = typeof TableListStore.prototype.fetchList extends () => Promise<{\n list: (infer A)[]\n total: number\n }>\n ? A\n : any,\n> {\n constructor() {\n makeObservable(this, {\n list: observable,\n loading: observable,\n paging: observable,\n total: observable,\n fetch: action,\n reset: action,\n })\n }\n\n list: T[] = []\n loading = false\n\n paging = {\n current: 1,\n pageSize: 10,\n }\n\n total = 0\n\n get totalPage() {\n return Math.ceil(this.total / this.paging.pageSize)\n }\n\n abstract fetchList: () => Promise<{\n list: T[]\n total: number\n }>\n\n onFirstFetch?: () => Promise<void>\n\n fetch = async (opts?: { reset?: boolean }) => {\n if (this.loading) return\n\n const { reset } = opts || {}\n if (reset) this.reset()\n\n try {\n this.loading = true\n\n if (this.onFirstFetch) {\n await this.onFirstFetch()\n delete this.onFirstFetch\n }\n\n const { list, total } = await this.fetchList()\n\n this.list = list || []\n this.total = total || 0\n } catch (err: any) {\n console.log(err)\n } finally {\n this.loading = false\n }\n }\n\n reset = () => {\n this.paging.current = 1\n this.total = 0\n this.loading = false\n }\n}\n"],"mappings":"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"} |
+11
-15
| { | ||
| "name": "@libeilong/mobx", | ||
| "version": "0.4.9", | ||
| "type": "module", | ||
| "version": "0.4.10", | ||
| "main": "./dist/index.mjs", | ||
| "module": "./dist/index.mjs", | ||
| "types": "./dist/index.d.mts", | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "types": "./dist/index.d.ts", | ||
| "main": "./dist/index.js", | ||
| "module": "./dist/index.js", | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.js" | ||
| "types": "./dist/index.d.mts", | ||
| "import": "./dist/index.mjs" | ||
| } | ||
| }, | ||
| "dependencies": {}, | ||
| "devDependencies": { | ||
| "@types/react-dom": "^18.0.6", | ||
| "react": "^18.2.0", | ||
| "mobx": "^6.15.0", | ||
| "mobx-react-lite": "^4.1.1" | ||
| "@types/react-dom": "^18.0.6" | ||
| }, | ||
| "peerDependencies": { | ||
| "react": ">=16", | ||
| "mobx": ">=6.0.0", | ||
| "mobx-react-lite": ">=4.0.0" | ||
| "mobx": "^6.0.0" | ||
| }, | ||
| "scripts": { | ||
| "dev": "tsc && vite build -w", | ||
| "build": "tsc && vite build", | ||
| "preview": "vite preview" | ||
| "dev": "tsdown --watch", | ||
| "build": "tsdown" | ||
| } | ||
| } |
| export declare function assignMobx(target: any, source: any): void; |
| export { assignMobx } from './func/assignMobx'; | ||
| export * from './modelManager'; | ||
| export { CountDownStore } from './stores/CountDown'; | ||
| export * from './stores/list'; | ||
| export { ResultStore } from './stores/Result'; | ||
| export { TableListStore } from './stores/TableList'; |
-274
| import { extendObservable as O, makeObservable as f, observable as r, action as u, computed as M } from "mobx"; | ||
| import L from "react"; | ||
| function S(t, e) { | ||
| const i = {}, n = Object.keys(e); | ||
| for (const o of n) | ||
| o in t ? t[o] = e[o] : i[o] = e[o]; | ||
| Object.keys(i).length > 0 && O(t, i); | ||
| } | ||
| function C(t = {}) { | ||
| return (e) => { | ||
| e.prototype._modelOptions = { | ||
| ...e.prototype._modelOptions, | ||
| ...t | ||
| }; | ||
| }; | ||
| } | ||
| function T(t) { | ||
| return typeof t == "function" ? t.prototype._modelOptions || {} : t && typeof t == "object" ? t._modelOptions || {} : {}; | ||
| } | ||
| function D(t) { | ||
| return !t || typeof t != "object" && typeof t != "function" ? void 0 : T(t).primaryKey; | ||
| } | ||
| var m = /* @__PURE__ */ ((t) => (t.OneToMany = "OneToMany", t.ManyToOne = "ManyToOne", t.OneToOne = "OneToOne", t.ManyToMany = "ManyToMany", t))(m || {}); | ||
| function d(t, e) { | ||
| return function(i, n) { | ||
| i.constructor._relations || (i.constructor._relations = {}), i.constructor._relations[n] = { | ||
| type: t, | ||
| modelClass: e | ||
| }; | ||
| }; | ||
| } | ||
| function E(t) { | ||
| return d("OneToMany", t); | ||
| } | ||
| function R(t) { | ||
| return d("ManyToOne", t); | ||
| } | ||
| function _(t) { | ||
| return d("OneToOne", t); | ||
| } | ||
| function A(t) { | ||
| return d("ManyToMany", t); | ||
| } | ||
| function w(t) { | ||
| return typeof t == "function" ? t._relations || {} : t.constructor._relations || {}; | ||
| } | ||
| function x(t) { | ||
| return typeof t == "function" && t.length === 0 ? t() : t; | ||
| } | ||
| function P(t, e) { | ||
| const i = w(t), n = {}, o = Object.keys(e); | ||
| for (const s of o) { | ||
| const g = i[s]; | ||
| if (g) { | ||
| const p = x(g.modelClass), { primaryKey: l, createInstance: h } = T(p); | ||
| if (!l) continue; | ||
| if ([m.ManyToMany, m.OneToMany].includes(g.type)) { | ||
| if (!Array.isArray(e[s])) | ||
| throw new Error(`Expected an array for relation ${s.toString()}, but got ${typeof e[s]}`); | ||
| const c = e[s].map((a) => { | ||
| const y = typeof a == "object" ? a : { [l]: a }, F = t[s]?.find((v) => v[l] === y[l]); | ||
| return F || (h ? h(y) : new p(y)); | ||
| }); | ||
| s in t ? t[s] = c : n[s] = c; | ||
| } else { | ||
| const c = typeof e[s] == "object" ? e[s] : { [l]: e[s] }, a = h ? h(c) : new p(c); | ||
| s in t ? t[s] = a : n[s] = a; | ||
| } | ||
| } else | ||
| s in t ? t[s] = e[s] : n[s] = e[s]; | ||
| } | ||
| return Object.keys(n).length > 0 && O(t, n), t; | ||
| } | ||
| class z { | ||
| initCount = 60; | ||
| defaultText = "获取验证码"; | ||
| countTemplate = "{{count}}s"; | ||
| constructor(e = {}) { | ||
| this.initCount = e.initCount ?? 60, this.defaultText = e.defaultText ?? "获取验证码", this.countTemplate = e.countTemplate ?? "{{count}}s", this.count = this.initCount, f(this, { | ||
| count: r, | ||
| isRunning: r | ||
| }); | ||
| } | ||
| get text() { | ||
| return this.isRunning ? this.countTemplate.replace("{{count}}", this.count.toString()) : this.defaultText; | ||
| } | ||
| count = 0; | ||
| isRunning = !1; | ||
| start = () => { | ||
| if (this.isRunning) return; | ||
| this.isRunning = !0, this.count = this.initCount; | ||
| let e = () => { | ||
| setTimeout(() => { | ||
| this.count--, this.count === 0 ? this.isRunning = !1 : e(); | ||
| }, 1e3); | ||
| }; | ||
| e(); | ||
| }; | ||
| } | ||
| class j { | ||
| createElement = (e, i) => L.createElement( | ||
| "div", | ||
| { | ||
| style: { | ||
| padding: "12px", | ||
| display: "flex", | ||
| alignItems: "center", | ||
| justifyContent: "center" | ||
| }, | ||
| ...e ?? {} | ||
| }, | ||
| i | ||
| ); | ||
| renderLoading = () => this.createElement(void 0, "加载中..."); | ||
| renderNotData = () => this.createElement(void 0, "暂无数据"); | ||
| renderNotMore = () => this.createElement(void 0, "没有更多数据了"); | ||
| renderFailure = (e, i) => this.createElement({ onClick: i }, "加载失败,请点击重试"); | ||
| } | ||
| class b { | ||
| constructor(e = new j()) { | ||
| this.adapter = e, f(this, { | ||
| list: r, | ||
| hasMore: r, | ||
| listLoading: r, | ||
| paging: r, | ||
| err: r, | ||
| notData: M, | ||
| state: M, | ||
| stateWidget: M, | ||
| fetch: u, | ||
| reset: u | ||
| }); | ||
| } | ||
| /** 起始页码 */ | ||
| static startPageNumber = 1; | ||
| list = []; | ||
| hasMore = !0; | ||
| listLoading = !0; | ||
| err = void 0; | ||
| firstFetch = !0; | ||
| needPagination = !0; | ||
| paging = { | ||
| pageNumber: b.startPageNumber, | ||
| pageSize: 10, | ||
| total: 0 | ||
| }; | ||
| get notData() { | ||
| return !(this.listLoading || this.list.length > 0); | ||
| } | ||
| get state() { | ||
| return this.listLoading ? 2 : this.err ? 4 : this.notData || !this.hasMore ? 5 : 2; | ||
| } | ||
| get stateWidget() { | ||
| switch (this.state) { | ||
| case 2: | ||
| return this.adapter.renderLoading(); | ||
| case 5: | ||
| return this.notData ? this.adapter.renderNotData() : this.adapter.renderNotMore(); | ||
| case 4: | ||
| return this.adapter.renderFailure(this.err, this.fetch); | ||
| default: | ||
| return ""; | ||
| } | ||
| } | ||
| onFirstFetch; | ||
| fetch = async (e) => { | ||
| if (this.firstFetch) | ||
| this.firstFetch = !1; | ||
| else if (!this.listLoading && e?.reset) | ||
| typeof e.reset == "object" ? this.reset(e.reset) : this.reset(); | ||
| else if (this.listLoading || !this.hasMore) | ||
| return; | ||
| try { | ||
| this.err = void 0, this.listLoading = !0, this.onFirstFetch && (await this.onFirstFetch(), delete this.onFirstFetch); | ||
| const { list: i, total: n } = await this.fetchList(); | ||
| this.consumeFetchList({ list: i, total: n }); | ||
| } catch (i) { | ||
| this.err = i, console.log(i); | ||
| } finally { | ||
| this.listLoading = !1; | ||
| } | ||
| }; | ||
| /** 消费 fetchList 的结果 */ | ||
| consumeFetchList = (e) => { | ||
| const { list: i, total: n } = e; | ||
| this.paging.pageNumber === 1 ? this.list = i : this.list.push(...i), n != null ? (this.paging.total = n, this.list.length >= n && (this.hasMore = !1)) : i.length < this.paging.pageSize && (this.hasMore = !1), this.paging.pageNumber++; | ||
| }; | ||
| reset = (e) => { | ||
| this.paging.pageNumber = 1, this.listLoading = !1, this.hasMore = !0, e?.list && (this.list = []); | ||
| }; | ||
| } | ||
| class K { | ||
| constructor() { | ||
| f(this, { | ||
| loading: r, | ||
| result: r, | ||
| firstFetch: r | ||
| }); | ||
| } | ||
| loading = !0; | ||
| firstFetch = !0; | ||
| result = void 0; | ||
| err; | ||
| fetch = async () => { | ||
| if (!(this.loading && !this.firstFetch)) { | ||
| this.firstFetch = !1; | ||
| try { | ||
| this.loading = !0, this.result = await this.fetchResult(); | ||
| } catch (e) { | ||
| this.err = e; | ||
| } finally { | ||
| this.loading = !1; | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| class I { | ||
| constructor() { | ||
| f(this, { | ||
| list: r, | ||
| loading: r, | ||
| paging: r, | ||
| total: r, | ||
| fetch: u, | ||
| reset: u | ||
| }); | ||
| } | ||
| list = []; | ||
| loading = !1; | ||
| paging = { | ||
| current: 1, | ||
| pageSize: 10 | ||
| }; | ||
| total = 0; | ||
| get totalPage() { | ||
| return Math.ceil(this.total / this.paging.pageSize); | ||
| } | ||
| onFirstFetch; | ||
| fetch = async (e) => { | ||
| if (this.loading) return; | ||
| const { reset: i } = e || {}; | ||
| i && this.reset(); | ||
| try { | ||
| this.loading = !0, this.onFirstFetch && (await this.onFirstFetch(), delete this.onFirstFetch); | ||
| const { list: n, total: o } = await this.fetchList(); | ||
| this.list = n || [], this.total = o || 0; | ||
| } catch (n) { | ||
| console.log(n); | ||
| } finally { | ||
| this.loading = !1; | ||
| } | ||
| }; | ||
| reset = () => { | ||
| this.paging.current = 1, this.total = 0, this.loading = !1; | ||
| }; | ||
| } | ||
| export { | ||
| j as BaseFooterListAdapter, | ||
| z as CountDownStore, | ||
| b as ListStore, | ||
| A as ManyToMany, | ||
| R as ManyToOne, | ||
| C as Model, | ||
| E as OneToMany, | ||
| _ as OneToOne, | ||
| K as ResultStore, | ||
| I as TableListStore, | ||
| S as assignMobx, | ||
| P as assignModel, | ||
| T as getModelOptions, | ||
| D as getPrimaryKey, | ||
| w as getRelations, | ||
| x as resolveModelClass | ||
| }; |
| export declare function assignModel<T extends object>(instance: T, it: { | ||
| [K in keyof T]?: any; | ||
| }): T; |
| export { assignModel } from './assignModel'; | ||
| export { Model, getModelOptions, getPrimaryKey } from './Model'; | ||
| export { OneToMany, ManyToMany, ManyToOne, OneToOne, resolveModelClass, getRelations } from './Relations'; |
| export interface ModelOptions { | ||
| primaryKey?: string; | ||
| createInstance?: (params: any) => any; | ||
| } | ||
| export declare function Model(options?: ModelOptions): ClassDecorator; | ||
| /** | ||
| * @param target 可以是类或其实例 | ||
| * @returns 返回模型选项 | ||
| */ | ||
| export declare function getModelOptions(target: any): ModelOptions; | ||
| export declare function getPrimaryKey(target: any): string | undefined; |
| export declare enum RelationType { | ||
| OneToMany = "OneToMany", | ||
| ManyToOne = "ManyToOne", | ||
| OneToOne = "OneToOne", | ||
| ManyToMany = "ManyToMany" | ||
| } | ||
| export interface RelationMetadata { | ||
| type: RelationType; | ||
| modelClass: any | (() => any); | ||
| } | ||
| export declare function OneToMany<T extends new () => any>(modelClass: T | (() => T)): (target: any, propertyKey: string | symbol) => void; | ||
| export declare function ManyToOne<T extends new () => any>(modelClass: T | (() => T)): (target: any, propertyKey: string | symbol) => void; | ||
| export declare function OneToOne<T extends new () => any>(modelClass: T | (() => T)): (target: any, propertyKey: string | symbol) => void; | ||
| export declare function ManyToMany<T extends new () => any>(modelClass: T | (() => T)): (target: any, propertyKey: string | symbol) => void; | ||
| export declare function getRelations(target: any): Record<string, RelationMetadata>; | ||
| /** | ||
| * 解析模型类,支持直接类引用和函数形式 | ||
| */ | ||
| export declare function resolveModelClass(modelClass: any | (() => any)): any; |
| export declare class CountDownStore { | ||
| initCount: number; | ||
| defaultText: string; | ||
| countTemplate: string; | ||
| constructor(opts?: { | ||
| initCount?: number; | ||
| defaultText?: string; | ||
| countTemplate?: string; | ||
| }); | ||
| get text(): string; | ||
| count: number; | ||
| isRunning: boolean; | ||
| start: () => void; | ||
| } |
| export { BaseFooterListAdapter } from './ListFooterAdapter'; | ||
| export type { IListFooterAdapter } from './ListFooterAdapter'; | ||
| export { ListStore } from './List'; | ||
| export type { ListState } from './List'; |
| import { ReactNode } from 'react'; | ||
| import { IListFooterAdapter } from './ListFooterAdapter'; | ||
| export declare enum ListState { | ||
| normal = 0,// 普通 | ||
| abort = 1,// 中止 | ||
| loading = 2,// 加载中 | ||
| success = 3,// 加载成功 | ||
| failure = 4,// 加载失败 | ||
| complete = 5 | ||
| } | ||
| export declare abstract class ListStore<T = typeof ListStore.prototype.fetchList extends () => Promise<{ | ||
| list: (infer A)[]; | ||
| total: number; | ||
| }> ? A : any> { | ||
| private adapter; | ||
| /** 起始页码 */ | ||
| static startPageNumber: 0 | 1; | ||
| constructor(adapter?: IListFooterAdapter); | ||
| list: T[]; | ||
| hasMore: boolean; | ||
| listLoading: boolean; | ||
| err?: Error; | ||
| firstFetch: boolean; | ||
| needPagination: boolean; | ||
| paging: { | ||
| pageNumber: number; | ||
| pageSize: number; | ||
| total: number; | ||
| }; | ||
| get notData(): boolean; | ||
| get state(): ListState.loading | ListState.failure | ListState.complete; | ||
| get stateWidget(): ReactNode; | ||
| abstract fetchList: () => Promise<{ | ||
| list: T[]; | ||
| total: number; | ||
| }>; | ||
| onFirstFetch?: () => Promise<void>; | ||
| fetch: (opts?: { | ||
| reset?: boolean | { | ||
| list?: boolean; | ||
| }; | ||
| }) => Promise<void>; | ||
| /** 消费 fetchList 的结果 */ | ||
| consumeFetchList: (opts: { | ||
| list: T[]; | ||
| total: number; | ||
| }) => void; | ||
| reset: (options?: { | ||
| list?: boolean; | ||
| }) => void; | ||
| } |
Sorry, the diff of this file is too big to display
| export interface IListPagingAdapter { | ||
| getPaging: () => Record<string, number>; | ||
| /** 页码 */ | ||
| get pageNumber(): number; | ||
| /** 条数 */ | ||
| get pageSize(): number; | ||
| } |
| export declare abstract class ResultStore<T = typeof ResultStore.prototype.fetchResult extends () => Promise<infer A> ? A : unknown> { | ||
| constructor(); | ||
| loading: boolean; | ||
| firstFetch: boolean; | ||
| result?: T; | ||
| err?: Error; | ||
| fetch: () => Promise<void>; | ||
| abstract fetchResult: () => Promise<T>; | ||
| } |
| export declare abstract class TableListStore<T = typeof TableListStore.prototype.fetchList extends () => Promise<{ | ||
| list: (infer A)[]; | ||
| total: number; | ||
| }> ? A : any> { | ||
| constructor(); | ||
| list: T[]; | ||
| loading: boolean; | ||
| paging: { | ||
| current: number; | ||
| pageSize: number; | ||
| }; | ||
| total: number; | ||
| get totalPage(): number; | ||
| abstract fetchList: () => Promise<{ | ||
| list: T[]; | ||
| total: number; | ||
| }>; | ||
| onFirstFetch?: () => Promise<void>; | ||
| fetch: (opts?: { | ||
| reset?: boolean; | ||
| }) => Promise<void>; | ||
| reset: () => void; | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
124555
20.56%2
-33.33%1
-75%4
-73.33%384
-78.48%10
11.11%No
NaN