import { Store } from 'redux'; import { initModel } from '../utils/model'; import { NormalAction, IActionNormal } from '../actions/NormalAction'; import { ComposeAction } from '../actions/ComposeAction'; import { HttpServiceBuilderWithMeta } from '../services/HttpServiceBuilder'; import { IActionPayload } from '../actions/BaseAction'; export declare type FilterPersist = ((state: State) => StateReturn) | null; export declare type AnyModel = BaseModel; export declare type State = Data & { /** * `Modify data directly like this:` * ```javascript * this.action((state, i: number) => { * state.amount += i; * state.foo.bar = { is: 'cool' }; * state.names.push('dc'); * // Don't return state above. * // But new state must return. * }); * ``` */ readonly __mvvm: 'Modify data directly'; }; export declare type StateReturn = void | (Data & { readonly __mvvm?: 'Don\'t return state unless it\'s new'; }); export declare type Subscriptions = Array<{ when: string; then?: (state: State, action: any) => StateReturn; after?: (action: any) => void; duration?: number; }>; export declare type CreateNormalActionPayload = A extends (state: any, payload: infer P) => any ? P : never; export declare type CreateNormalActionEffect = A extends (state: any, ...args: infer P) => any ? (...args: P) => IActionNormal : never; export declare abstract class BaseModel { /** * Execute register at the end of the constructor for current model. * ```javascript * class TestModel extends Model { * constructor(p1, p2, p3) { * super(); // Auto register here for `new TestModel()` * ... * ... * // Auto register delay to here for `TestModel.init()` * } * } * * export const testModel = TestModel.init(); * ``` */ static init: typeof initModel; private readonly _name; private _action?; constructor(); getReducerName(): string; /** * The redux data for this model. The same as `store.getState()[model.getReducerName()]` * * @throws NullReducerError * @throws ForgetRegisterError */ get data(): Data extends null ? never : Data; /** * The same as action(), but it's a type of IIFE, we can't not use it twice. * * ```javascript * class TestModel extends Model { * custom() { * this.changeState((state) => { * state.amount += 1; * }); * * this.changeState((state) => { * state.amount += 2; * }); * } * } * ``` * @see action() */ protected changeState(fn: (state: State) => StateReturn): IActionNormal; /** * Common action to change state. * * ```javascript * class TestModel extends Model { * add = this.action((state, count: number) => { * state.amount += count; * }); * } * ``` */ protected action, payload: any) => StateReturn, After extends (action: IActionPayload>) => void>(changeState: Fn, options?: { afterSuccess: After; duration?: number; }): CreateNormalActionEffect & NormalAction, After>; /** * The action which compose aysnchorize program and hold loading. * ``` * class TestModel extends Model { * updateRoom = this.compose(async (id: number) => { * const roomId = await getRoomId(id); * const userId = await getUserId(roomId); * * this.changeState((state) => { * state.push([userId, roomId]); * }); * }); * } * * const testModel = new TestModel(); * * ------------- * * // Hold loading * const loading = testModel.updateRoom.useLoading(); * // Dispatch action * const promise = testModel.updateRoom(10); * ``` */ protected compose Promise>(fn: Fn): Fn & ComposeAction; /** * Filter data from storage. Assign model to allowlist before you can use persist: * * ```javascript * const store = createReduxStore({ * persist: { * allowlist: { * xxxModel, * yyyModel, * } * } * }); * ``` * * Then override this method: * * protected filterPersistData(): FilterPersist { * return (state) => { * // ... * // logic by mvvm * }; * } * */ protected filterPersistData(): FilterPersist; /** * The listeners subscribe events from other models. * ```javascript * import { Subscriptions } from '@redux-model/*'; * * class TestModel extends Model { * * protected subscriptions(): Subscriptions { * return [ * aModel.xxAction.onSuccess((state, action) => { * // Chagnge state here. * // The 'state' belongs to TestModel, and 'action' belongs to aModel. * * // state.name = action.response.name; * // state.name = action.payload.name; * }), * * aModel.xxAction.afterSuccess((action) => { * // Dispatch more action here. * }), * * ... * ]; * } * } * ``` */ protected subscriptions(): Subscriptions; /** * Request get method */ protected get(uri: string): HttpServiceBuilderWithMeta; /** * Request post method */ protected post(uri: string): HttpServiceBuilderWithMeta; /** * Request put method */ protected put(uri: string): HttpServiceBuilderWithMeta; /** * Request delete method */ protected delete(uri: string): HttpServiceBuilderWithMeta; /** * Request patch method */ protected patch(uri: string): HttpServiceBuilderWithMeta; /** * Request connect method */ protected connect(uri: string): HttpServiceBuilderWithMeta; /** * The callback on store is created and persist rehydrate is complete. */ protected onStoreCreated(store: Store): void; /** * Keep the current state when resetStore() is invoked. * @default false */ protected keepOnResetStore(): boolean; /** * The initial state for reducer. * When you enable persist to effect this model, the persist data will override it. */ protected abstract initialState(): Data; private _register; private _createBuilder; }