Context
// @namespace Context
import { Context } from 'rcfm'
Custom Types
@typedef {Object} ContextInstance
@description - 上下文环境实例
@prop {DependencyInstance} dependency - 依赖关系实例
@prop {DispatcherInstance} dispatcher - 订阅器实例
@prop {ExecutorInstance} executor - 任务执行器实例
@prop {FamilyInstance} family - 家族关系实例
@prop {HookInstance} hooks - 钩子函数管理器实例
@prop {Object} members - 环境成员状态存储空间
@typedef {Object} ContextMember
@description - 环境成员
@prop {Object} props - 成员属性设定值构成的对象
@prop {integer} [props.order = Infinity] - 成员在同辈中的顺序设定值
@prop {Object[]} props.children = [] - ContextInstance 自动维护的成员子级设定值
@prop {string} props.children[i].id - 子成员唯一标识
@prop {*} props.<custom> - 其它任意自定义属性设定值
@typedef {Object} ContextMemberNaming
@description - 环境成员状态存储空间内存储路径
@prop {string} prop - 成员属性当前值存储路径
@prop {string} error - 成员属性当前值错误存储路径
@prop {Object} raw
@prop {string} raw.prop - 成员属性设定值存储路径
@prop {string} raw.error - 成员属性设定值错误存储路径
@typedef {Object} ContextMemberStore
@description - 环境成员状态存储空间,可通过 <ContextInstance>.members[<memberId>] 访问。
@prop {*} <ContextMemberNaming>.prop - 成员属性当前值
@prop {ExceptionInstance[] | null} <ContextMemberNaming>.error - 成员属性当前值错误
@prop {*} <ContextMemberNaming>.raw.prop - 成员属性设定值
@prop {ExceptionInstance[] | null} <ContextMemberNaming>.raw.error - 成员属性设定值错误
@typedef {Object} ContextAddMutation
@description - 新增环境成员变更
@prop {string} [action = "add"] - 变更类型
@prop {string} [id = <a_random_unique_id>] - 成员唯一标识
@prop {string} [parentId = <root_member_id>] - 父成员唯一标识
@prop {Object} [props = {}] - 成员属性设定值构成的对象
@prop {integer} [props.order = Infinity] - 成员在同辈中的顺序设定值
@prop {Object[]} props.children = [] - ContextInstance 自动维护的成员子级设定值
@prop {string} props.children[i].id - 子成员唯一标识
@prop {*} props.<custom> - 其它任意自定义属性设定值
@typedef {Object} ContextSetMutation
@description - 更新环境成员属性设定值变更
@prop {string} [action = "set"] - 变更类型
@prop {string} id - 成员唯一标识
@prop {string} prop - 变更属性名
@prop {*} value - 变更属性新值
@typedef {Object} ContextCalcMutation
@description - 更新环境成员属性当前值变更
@prop {string} [action = "calc"] - 变更类型
@prop {string} id - 成员唯一标识
@prop {string} prop - 变更属性名
@typedef {Object} ContextDelMutation
@description - 删除环境成员变更
@prop {string} [action = "del"] - 变更类型
@prop {string} id - 成员唯一标识
@typedef {Object} ContextHook
@description - 成员变更钩子定义
@prop {ContextHookType[]} hook
@prop {ContextHookHandler[]} handler
@typedef {string} ContextHookType
@description - 成员变更钩子节点类型
@typedef {Function} ContextHookHandler
@description - 成员变更钩子函数
不同 ContextHookType 的钩子函数按向该类型下添加的先后顺序调用
Exception Types
@type {ExceptionInstance}
@description - 不是合规的实例
@prop {string} type = "INVALID_CONTEXT_INSTANCE"
@prop {string} [name = type]
@prop {Object} [data = {}]
@prop {string} [message]
Builtin Hooks
@type {ContextHookType}
内置钩子节点及其执行顺序为:
"before-del" -> "after-del" -> "before-add" -> "after-add" ->
"before-set" -> "after-set" -> "before-calc" -> "after-calc"
@type {ContextHookHandler}
1.内置各类型的钩子函数接收到的参数分别为:
"before/after-del": ContextDelMutation、"before/after-add": ContextAddMutation、
"before/after-set": ContextSetMutation、"before/after-calc": ContextCalcMutation。
2.在 "before-<type>" 节点添加的返回值为 false 的函数会终止 mutation,但不终止同类型下后续钩子函数调用。
3.在 "before-add" 节点,对 <ContextAddMutation>.props.<prop> 的更改会反应到成员属性设定值上。
4.在 "after-set" 节点,成员设定值错误默认重置为 null,对 <ContextSetMutation>.value 的更改会反应到成员属性设定值上。
5.在 "after-calc" 节点,成员当前值及当前值错误默认指向其设定值及设定值错误。
// @example
Context.create().hooks.add("before-add", function(mutation){
mutation.props.createdAt = Date.now()
})
Class Methods
.create()
创建一个上下文环境实例。
// Context.create()
// @returns {ContextInstance}
// @example
const context = Context.create()
.isContext()
判断入参是否是一个上下文环境实例。
// Context.isContext(arg)
// @param {*} arg - 任意参数
// @returns {boolean} - 当入参是 ContextInstance 时返回 true,否则返回 false
// @examples
Context.isContext(Context.create()) // true
Context.isContext({}) // false
.isntContext()
判断入参是否不是一个上下文环境实例。
// Context.isntContext(arg)
// @param {*} arg - 任意参数
// @returns {boolean} - 当入参是 ContextInstance 时返回 false,否则返回 true
// @examples
Context.isntContext(Context.create()) // false
Context.isntContext({}) // true
.mustbeContext()
当入参不是一个上下文环境实例时抛出异常。
// Context.mustbeContext(arg, message)
// @param {*} arg - 任意参数
// @param {string} [message] - 自定义异常对象消息
// @returns {undefined}
// @examples
Context.mustbeContext(Context.create())
Context.mustbeContext({}) // Throws a INVALID_CONTEXT_INSTANCE exception.
Instance Methods
#add()
向上下文环境实例的任务执行器入队一个或多个 ContextAddMutation。
// context#add(mutation)
// @param {ContextAddMutation | ContextAddMutation[]} mutation
// @returns {string | string[]} - 返回新成员 id,或新成员 id 构成的数组。
// @examples
const parentId = context.add({props: {name: 'parent'}})
const childrenIds = context.add([
{parentId, props: {name: 'childOne'}},
{parentId, props: {name: 'childTwo'}}
])
#delete()
向上下文环境实例的任务执行器入队一个或多个 ContextDelMutation。
// context#delete(mutation)
// @param {ContextDelMutation | ContextDelMutation[]} mutation
// @returns {undefined}
// @examples
context.delete({id: parentId})
context.delete([{id: idOne}, {id: idTwo}])
#find()
根据匹配函数查找环境成员唯一标识。
// context#find(matcher)
// @param {Function} matcher - 被调用时会传入一个包含成员 id 的对象,返回 true 代表该成员匹配。
// @returns {string | null} - 如过有匹配 matcher 函数的成员,则返回该成员 id,否则返回 null。
// @example
const id = context.find(function({id}){
return context.get({id, prop: 'name'}) === 'Jacky'
})
#get()
获取上下文环境实例中某成员状态存储空间中的值和对应的错误信息。
// context#get(params, options)
// @param {Object} params
// @prop {string} params.id - 成员唯一标识
// @prop {string} [params.prop] - 成员属性名称,如果传入则只获取该属性状态,否则搜集所有属性状态
// @param {Object} [options = {}]
// @prop {string | Array} [options.include] - 返回结果是否要属性设定值和错误信息,
// 如传入值包含 "raw" 则返回结果包含设定值,如传入值包含 "error" 则返回结果包含错误信息。
// @returns {null | Object | *}
// @example - 获取成员某属性当前值
const value = context.get({id: idOne, prop: "age"})
// @example - 获取成员某属性当前值及当前值错误
let {value, error} = context.get({id: idOne, prop: "age"}, {include: "error"})
// @example - 获取成员某属性当前值及设定值
let {value, raw: {value: rawValue}}
= context.get({id: idOne. prop: "age"}, {include: "raw"})
// @example - 获取成员某属性当前值及当前值错误和设定值及设定值错误
let {value, error, raw: {value: rawValue, error: rawError}}
= context.get({id: idOne. prop: "age"}, {include: ["raw", "error"]})
// @example - 获取某成员所有属性当前值及当前值错误和设定值及设定值错误
// 值和错误信息以属性名作为对象的 key 进行聚合
let {values, errors, raw: {values: rawValues, errors: rawErrors}}
= context.get({id: idOne}, {include: ['raw', 'error']})
#naming()
获取成员状态存储空间中属性值及错误信息存储路径。
// context#naming(prop)
// @param {string} prop - 成员属性名称
// @returns {ContextMemberNaming}
// @example
// 新建成员
const id = context.add()
// 访问存储空间及存储路径
const [store, naming] = [context.members[id], context.naming('age')]
// 根据属性设定值计算当前值并写入存储空间
store[naming.prop] = store[naming.raw.prop] || 0 + 10
#set()
向上下文环境实例的任务执行器入队一个或多个 ContextSetMutation。
// context#set(mutation)
// @param {ContextSetMutation | ContextSetMutation[]} mutation
// @returns {undefined}
// @examples
context.set({id: jerryId, prop: 'age', value: 10})
context.set([
{id: jerryId, prop: 'age', value: 20},
{id: jackyId, prop: 'age', value: 30}
])
#subscribe()
订阅成员状态变更。
// context#subscribe(params, callback)
// @param {Object} params
// @prop {string} params.id - 成员唯一标识
// @prop {boolean} [params.immediately = true] - 是否立即触发 callback 调用
// @prop {Function} handler - 成员状态变更回调函数
// @returns {Function} - 返回一个用于取消订阅的函数
// @example
context.subscribe({id: jackyId}, function(){
const newState = context.get({id: jackyId}, {include: ['raw', 'error']})
})