Skip to content

Commit

Permalink
feat(core): #38 di (symbol for map)
Browse files Browse the repository at this point in the history
  • Loading branch information
artalar committed Jan 16, 2020
1 parent f87693c commit 8a43b49
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 24 deletions.
6 changes: 3 additions & 3 deletions packages/core/src/createStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,10 @@ export function createStore(

if (isLazy && _listeners.length === 0) {
nextListeners.delete(targetId)
delete state[targetId]
delete state[targetId as string]
storeTree.disunion(targetTree, id => {
nextListeners.delete(id)
delete state[id]
delete state[id as string]
})
}
}
Expand All @@ -181,7 +181,7 @@ export function createStore(
assign(state, stateNew)
for (let i = 0; i < changedIds.length; i++) {
const id = changedIds[i]
callFromList(listeners.get(id) || [], stateNew[id])
callFromList(listeners.get(id) || [], stateNew[id as string])
}
}

Expand Down
40 changes: 21 additions & 19 deletions packages/core/src/declareAtom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Tree, State, TreeId, Ctx, createCtx } from './kernel'
import { Tree, State, TreeId, Ctx, createCtx, Leaf } from './kernel'
import {
TREE,
nameToId,
Expand All @@ -9,6 +9,7 @@ import {
safetyFunc,
getIsAction,
assign,
getName,
} from './shared'
import { Action, declareAction, PayloadActionCreator } from './declareAction'

Expand All @@ -18,7 +19,7 @@ const DEPS = Symbol('@@Reatom/DEPS')
const initActionCreator = declareAction(['@@Reatom/init'])
export const initAction = initActionCreator()

type AtomName = string | [TreeId] | symbol
type AtomName = TreeId | [string]
type AtomsMap = { [key: string]: Atom<any> }
type Reducer<TState, TValue> = (state: TState, value: TValue) => TState
type DependencyMatcher<TState> = (
Expand Down Expand Up @@ -54,9 +55,10 @@ export function declareAtom<TState>(
}

const _id = nameToId(name as AtomName)
const _name = getName(_id)

if (initialState === undefined)
throwError(`Atom "${_id}". Initial state can't be undefined`)
throwError(`Atom "${_name}". Initial state can't be undefined`)

const _tree = new Tree(_id)
const _deps = new Set<TreeId>()
Expand Down Expand Up @@ -89,13 +91,13 @@ export function declareAtom<TState>(
changedIds,
type,
}: Ctx) {
const atomStateSnapshot = state[_id]
const atomStateSnapshot = state[_id as string]
// first `walk` of lazy (dynamically added by subscription) atom
const isAtomLazy = atomStateSnapshot === undefined

if (!isAtomLazy && type === initAction.type && !payload) return

const atomStatePreviousReducer = stateNew[_id]
const atomStatePreviousReducer = stateNew[_id as string]
// it is mean atom has more than one dependencies
// that depended from dispatched action
// and one of the atom reducers already processed
Expand All @@ -104,8 +106,8 @@ export function declareAtom<TState>(
? atomStatePreviousReducer
: atomStateSnapshot) as TState

const depStateSnapshot = state[depId]
const depStateNew = stateNew[depId]
const depStateSnapshot = state[depId as string]
const depStateNew = stateNew[depId as string]
const isDepChanged = depStateNew !== undefined
const depState = isDepChanged ? depStateNew : depStateSnapshot
const depValue = isDepActionCreator ? payload : depState
Expand All @@ -115,16 +117,16 @@ export function declareAtom<TState>(

if (atomStateNew === undefined)
throwError(
`Invalid state. Reducer № ${position} in "${_id}" atom returns undefined`,
`Invalid state. Reducer № ${position} in "${_name}" atom returns undefined`,
)

if (atomStateNew !== atomState && !hasAtomNewState) changedIds.push(_id)
stateNew[_id] = atomStateNew
stateNew[_id as string] = atomStateNew
}
}
update._ownerAtomId = _id

if (isDepActionCreator) return _tree.addFn(update, depId)
if (isDepActionCreator) return _tree.addFn(update, depId as Leaf)
if (_deps.has(depId)) throwError('One of dependencies has the equal id')
_deps.add(depId)
depTree.fnsMap.forEach((_, key) => _tree.addFn(update, key))
Expand Down Expand Up @@ -153,7 +155,7 @@ export function declareAtom<TState>(
}

export function getState<T>(state: State, atom: Atom<T>): T | undefined {
return state[atom[TREE].id] as T | undefined
return state[atom[TREE].id as string] as T | undefined
}

export function map<T, TSource = unknown>(
Expand All @@ -173,7 +175,7 @@ export function map<T, TSource = unknown>(
if (!mapper) {
mapper = source as (dependedAtomState: TSource) => NonUndefined<T>
source = name as Atom<TSource>
name = getTree(source).id.toString() + ' [map]'
name = Symbol(getName(getTree(source).id) + ' [map]')
}
safetyFunc(mapper, 'mapper')

Expand All @@ -200,17 +202,17 @@ export function combine<T extends AtomsMap | TupleOfAtoms>(
name: AtomName | T,
shape?: T,
) {
let keys: (string | number)[]
if (!shape) {
shape = name as T
name = Symbol('{' + (keys = Object.keys(shape)).join() + '}')
}
if (arguments.length === 1) shape = name as T

const keys = Object.keys(shape!)
keys.push(...((Object.getOwnPropertySymbols(shape) as unknown) as string[]))

keys = keys! || Object.keys(shape)
if (arguments.length === 1)
name = Symbol('{' + keys.map(getName).join() + '}')

const isArray = Array.isArray(shape)

return declareAtom(name as string | [TreeId], isArray ? [] : {}, reduce =>
return declareAtom(name as AtomName, isArray ? [] : {}, reduce =>
keys.forEach(key =>
//@ts-ignore
reduce(shape[key], (state, payload) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/kernel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type Leaf = string // unique
export type TreeId = string // unique
export type TreeId = string | symbol // unique
export type State = Record<TreeId, unknown>
// reatom specific
export type Fn = {
Expand Down Expand Up @@ -63,7 +63,7 @@ export class Tree {
set.forEach(fn => fns.add(fn))
})
}
disunion(tree: Tree, cb: (key: Leaf) => any) {
disunion(tree: Tree, cb: (key: TreeId) => any) {
tree.fnsMap.forEach((set, key) => {
const fns = this._getFns(key)
set.forEach(fn => fns.delete(fn) && cb(fn._ownerAtomId))
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export function getTree(thing: Unit): Tree {
return thing && thing[TREE]
}

export function getName(treeId: TreeId): string {
return typeof treeId === 'symbol' ? treeId.description : treeId
}

export function getIsAtom(thing: any): thing is Atom<any> {
const vertex = getTree(thing)
return Boolean(vertex && !vertex.isLeaf)
Expand Down

0 comments on commit 8a43b49

Please sign in to comment.