Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Jun 2, 2024
1 parent c128370 commit c5e6921
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 27 deletions.
22 changes: 12 additions & 10 deletions packages/reactive/src/computed/computedObject.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IStore, StoreDefine } from "../types"
import { IState, IStore, StoreDefine } from "../types"
import { getComputedId } from "../utils/getComputedId"
import { ComputedOptions, RuntimeComputedOptions } from "./types"

// id:string
Expand All @@ -14,21 +15,22 @@ import { ComputedOptions, RuntimeComputedOptions } from "./types"
// group:computedOptions.group,
// async:true,
// options:computedOptions,


// }

export class ComputedObject<T extends StoreDefine =StoreDefine> {
options:Required<ComputedOptions>
constructor(public store:IStore<T>,options:ComputedOptions){
constructor(public store:IStore<T>,public attachState:IState<T>,options:ComputedOptions){
this.options = Object.assign({

},options) as Required<ComputedOptions>
}
get enable(){ return this.options.enable as boolean }
get id(){return getComputedId(this.options.selfPath, this.options.id) }
get enable(){ return this.options.enable }
get group(){return this.options.group}
set enable(value:boolean){ this.options.enable = value }
get async(){return this.options.async}
run(options?:RuntimeComputedOptions) {
const params = {desc:mutateId,extraArgs:options}
return isExternal ? computedTo.stateCtx.runMutateTask(params) : store.stateCtx.runMutateTask(params)
}
}
return this.store.reactive.runMutate(this.id,options)
}
}

27 changes: 22 additions & 5 deletions packages/reactive/src/computed/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import { IMutateWitness, IOperateParams, ISharedCtx } from "helux";
import type { ComputedScope, ComputedContext, StoreDefine } from "../store/types";
import type { ComputedScope, ComputedContext, StoreDefine, IState } from "../store/types";
import { Dict } from "../types"
import { WatchDescriptor, WatchDescriptorCreator } from "../watch";

Expand Down Expand Up @@ -85,10 +85,10 @@ export interface ComputedProgressbar{

export interface ComputedOptions<Value=any,Extras extends Dict={}> {
// 计算函数的唯一标识,如果未指定,则自动生成一个唯一标识
id?:string | ((path:string[])=>string)
context?: ComputedContext // 计算函数的this
scope? : ComputedScope // 计算函数的第一个参数
initial?: Value
id? : string
context? : ComputedContext // 计算函数的this
scope? : ComputedScope // 计算函数的第一个参数
initial? : Value
// 异步计算,默认情况下,通过typeof(fn)=="async function"来判断是否是异步计算函数
// 但是在返回Promise或者Babel转码等情况下,判断可能失效时,需要手动指定async=true
async?:boolean
Expand Down Expand Up @@ -174,6 +174,23 @@ export interface ComputedProgressbar{
* 额外合并到计算结果AsyncComputedObject中的属性
*/
extras?:Extras
/**
* 计算函数computed所在的路径
*
* 一般不需要额外指定,当使用computed函数声明式时会自动指定
*
*/
selfPath?: string[]
/**
* 默认情况下,计算结果会写入到当前store中computed所在的位置,即selfPath
* 如果指定此属性,则会将计算结果写入attach指定的位置selfPath
*/
attach?: IState
/**
* 是否将计算结果写入到store或attach所在的位置,即selfPath所在位置
*
*/
rewrite?:boolean
};

export type ComputedDepends =Array<string | Array<string>>
Expand Down
10 changes: 9 additions & 1 deletion packages/reactive/src/reactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { sharex } from "helux"
import { createUseState } from "./store/useState"
import { ComputedState, Dict } from "./types"
import { ComputedState, Dict, RuntimeComputedOptions } from "./types"

export function reactive<T extends Dict=Dict>(data:T) {
const stateCtx = sharex<ComputedState<T>>(data)
Expand All @@ -21,3 +21,11 @@ export function reactive<T extends Dict=Dict>(data:T) {





export interface IReactive<T extends Dict = Dict>{
useState(fn:(draft:T)=>void):void
setState(fn:(draft:T)=>void):void
createMutate(fn:(draft:T)=>void):string
runMutate(id:string,params?:RuntimeComputedOptions):void
}
88 changes: 88 additions & 0 deletions packages/reactive/src/reactives/helux.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { ISharedCtx, sharex } from "helux"
import { CreateComputedOptions, IReactiveable } from "./types";
import { ComputedDepends, ComputedOptions, ComputedState, Dict, RequiredComputedState, RuntimeComputedOptions, StateGetter, StateSetter, StoreDefine } from "../types";
import { setVal } from "../utils";


export class HeluxReactiveable<T extends ComputedState<Dict> =ComputedState<Dict>> implements IReactiveable<T>{
private _stateCtx:ISharedCtx<T>
constructor(state:any){
this._stateCtx = sharex<T>(state)
}

get state(){
return this._stateCtx.state
}
/**
* const [ state ] = useState()
* const [ firstName ] = useState<string>((state)=>state.firstName)
* const [ fullName ] = useState<string>((state)=>state.firstName+state.lastName)
* const [ fullName,updateFullName ] = useState<string,string[]>(
* (state)=>state.firstName+state.lastName,
* (state,value)=>{
* state.firstName = value[0]
* state.lastName = value[1]
* }
* )
* updateFullName(['zhang','fisher])
*
* @param getter
* @param setter
* @returns
*/
useState<Value=ComputedState<T>,SetValue=Value>(
getter?:StateGetter<RequiredComputedState<T>,Value>,
setter?:StateSetter<RequiredComputedState<T>,SetValue>
):[Value,(value:SetValue)=>void]{
const [ state,setState ] = this._stateCtx.useState()
const value = (typeof(getter)==='function' ? getter(state as RequiredComputedState<T>) : state) as Value
const updateValue = (typeof(setter)=='function' ?
(value:SetValue)=>{
//@ts-ignore
setState((draft:any)=>{
setter.call(draft,draft as any,value)
})
} : setState ) as (value:SetValue)=>void

return [ value, updateValue ]
}

setState(fn:(draft:T)=>void):void{
//@ts-ignore
this._stateCtx.setState(fn)
}
/**
* 创建计算属性
* @param fn
* @param depents
* @param options
*/
createComputed(params: CreateComputedOptions<T>): string {
const {initial,onComputed,depends,options} = params
this._stateCtx.mutate({
deps: (state: any) =>{
return depends
},
fn: (draft, params) => {
if (params.isFirstCall) {
// @ts-ignore
initial(draft, params)
}
},
// 此函数在依赖变化时执行,用来异步计算
// extraArgs是在调用run方法时传入的额外参数,可用来覆盖计算参数
task: async ({ draft, setState, input, extraArgs }) => {
// @ts-ignore
return onComputed({draft,setState,input,options:Object.assign({},extraArgs)})
},
immediate : options.immediate,
desc : options.id,
checkDeadCycle: false,
});
return options.id as string
}
runComputed(id:string,options?:RuntimeComputedOptions):void{
const params = {desc:id,extraArgs:options}
this._stateCtx.runMutateTask(params)
}
}
1 change: 1 addition & 0 deletions packages/reactive/src/reactives/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./types"
53 changes: 53 additions & 0 deletions packages/reactive/src/reactives/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
*
* 对sharex的简单封装
*
* @param options
* @returns
*/

import { ComputedDepends, ComputedOptions, ComputedState, Dict, RequiredComputedState, RuntimeComputedOptions, StateGetter, StateSetter } from "../types"


export type CreateComputedOptions<T extends ComputedState<Dict> =ComputedState<Dict>>= {
depends?:ComputedDepends // 依赖的计算属性
initial(state:T,params:any):void // 首次计算时执行
getter():void // 计算函数
// 当依赖变化时执行
onComputed(params:{
draft:T,
setState:(state:T)=>void,
input:any,
options?: ComputedOptions
}):void // 当依赖变化时执行
options:ComputedOptions // 计算属性的选项
}

export interface IReactiveable<T extends ComputedState<Dict> =ComputedState<Dict>>{
get state():T
useState<Value=T,SetValue=Value>(
getter?:StateGetter<RequiredComputedState<T>,Value>,
setter?:StateSetter<RequiredComputedState<T>,SetValue>
):[Value,(value:SetValue)=>void]
/**
*
* @param fn
*/
setState(fn:(draft:T)=>void):void
/**
* 创建计算属性
*/
createComputed(params:CreateComputedOptions<T>):string
/**
* 手动运行计算函数
* @param id
* @param options
*/
runComputed(id:string,options?:RuntimeComputedOptions):void
/**
* 当读取响应对象时的回调
* @param params
*/
onRead(params:{valuePath:string[],value:any,parent:string[], replaceValue:(newValue:any)=>void}):void
}

26 changes: 16 additions & 10 deletions packages/reactive/src/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ import { createUseState } from "./useState"
import { createSetState } from "./setState";
import mitt,{Emitter} from "mitt";
import { createUseWatch } from '../watch/useWatch';
import { getRndId } from "../utils/getRndId";
import { HeluxReactiveable } from "../reactives/helux";



export function createStore<T extends StoreDefine = StoreDefine>(data:T,options?:Partial<StoreOptions<T>>){
// 1.初始化配置参数
const opts = Object.assign({
id:Math.random().toString(16).substring(2),
debug:true,
computedThis:()=>ComputedScopeRef.Root,
computedScope:()=>ComputedScopeRef.Current,
singleton:true
id : getRndId(),
debug : true,
computedThis : ()=>ComputedScopeRef.Root,
computedScope: ()=>ComputedScopeRef.Current,
singleton : true,
reactiveable : true,
},options) as StoreOptions<T>

opts.log = (...args:any[])=>{
Expand All @@ -33,17 +36,20 @@ export function createStore<T extends StoreDefine = StoreDefine>(data:T,options?

// @ts-ignore
const store:IStore<T> = {
options:opts,
on:storeEmitter.on,
off:storeEmitter.off,
emit:storeEmitter.emit,
options: opts,
on : storeEmitter.on,
off : storeEmitter.off,
emit : storeEmitter.emit,
_replacedKeys:{} // 用来保存已经替换过的key
}

store.computedObjects = new ComputedObjects<T>(store as IStore<T>),
store.watchObjects = new WatchObjects<T>(store as IStore<T>)

// 3. 创建响应式对象
// 3. 创建响应式对象, 此处使用helux
store.reactiveable = new HeluxReactiveable(data)


store.stateCtx = sharex<ComputedState<T>>(data as any, {
stopArrDep: false,
moduleName: opts.id,
Expand Down
6 changes: 5 additions & 1 deletion packages/reactive/src/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Dict } from "../types";
import type { createUseState } from "./useState";
import type { createSetState } from "./setState";
import { Emitter } from "mitt";
import { IReactive } from "../reactive";
import { IReactiveable } from "../reactives";


export type StoreDefine<State extends Dict = Dict> = State
Expand Down Expand Up @@ -89,15 +91,17 @@ export type IStore<T extends StoreDefine= StoreDefine> = {
// 启用与停止计算
enableComputed : (value:boolean)=>void
options : StoreOptions<T>
reactiveable : IReactiveable<ComputedState<T>>
stateCtx : ISharedCtx<ComputedState<T>>
reactive : IReactive<T>
// 计算
createComputed : ReturnType<typeof computedObjectCreator>
computedObjects: ComputedObjects<T>
// 侦测
watch : ReturnType<typeof createWatch<T>>
useWatch : ReturnType<typeof createUseWatch<T>>
watchObjects : WatchObjects<T>

// 用来同步表单时使用
sync : ISharedCtx<ComputedState<T>>['sync']
// 简单事件触发与侦听
Expand Down

0 comments on commit c5e6921

Please sign in to comment.