Created
June 18, 2019 11:01
-
-
Save zerobias/0521b5a0e450ad7bdd40950a731c5e53 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {createEvent, createStore, Event, forward, Store} from 'effector' | |
export class Iteration<T> { | |
index: number | |
item: T | |
list: T[] | |
constructor(index: number, item: T, list: T[]) { | |
this.index = index | |
this.item = item | |
this.list = list | |
} | |
} | |
export function storeList<T>({ | |
list, | |
handler, | |
}: { | |
handler?: (item: T) => any | |
list?: Store<T[]> | |
} = {}): Event<void> & { | |
installStore: Event<Store<T[]>> | |
trigger: Event<void> | |
start: Event<T[]> | |
end: Event<T[]> | |
step: Event<Iteration<T>> | |
item: Event<T> | |
} { | |
const {start, end, step, item} = eventList<T>() | |
const trigger = createEvent<void>() | |
const noop = createStore<T[]>([]) | |
const installStore = createEvent<Store<T[]>>() | |
const installedStore = createStore({ | |
store: noop, | |
dispose: noop.watch(trigger, list => { | |
start(list) | |
}), | |
}) | |
installedStore.on(installStore, (state, store) => { | |
if (state.store === store) return state | |
state.dispose() | |
return { | |
store, | |
dispose: store.watch(trigger, list => { | |
start(list) | |
}), | |
} | |
}) | |
if (list) { | |
installStore(list) | |
} | |
if (handler) { | |
item.watch(handler) | |
} | |
const result = trigger as any | |
result.installStore = installStore | |
result.trigger = trigger | |
result.start = start | |
result.end = end | |
result.step = step | |
result.item = item | |
return result | |
} | |
export function eventList<T>() { | |
const start = createEvent<T[]>() | |
const end = createEvent<T[]>() | |
const step = createEvent<Iteration<T>>() | |
const item = step.map(step => step.item) | |
const nonEmptyList = start.filter({ | |
fn: list => list.length > 0, | |
}) | |
forward({ | |
from: nonEmptyList.map(list => new Iteration(0, list[0], list)), | |
to: step, | |
}) | |
forward({ | |
from: step.filter(({index, list}) => { | |
if (index + 1 < list.length) | |
return new Iteration(index + 1, list[index + 1], list) | |
}), | |
to: step, | |
}) | |
forward({ | |
from: step.filter(({index, list}) => { | |
if (index + 1 === list.length) return list | |
}), | |
to: end, | |
}) | |
forward({ | |
from: start.filter({ | |
fn: list => list.length === 0, | |
}), | |
to: end, | |
}) | |
return { | |
start, | |
end, | |
step, | |
item, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment