import {
Atom,
Desc,
EventStream,
EventStreamSeed,
isAtom,
ObservableSeed,
Property,
PropertySeed,
} from "./abstractions"
import { LensedAtom } from "./atom"
import * as L from "./lens"
import { map } from "./map"
import { rename, toString } from "./util"
import {
Function1,
Function2,
Function3,
Function4,
Function5,
Function6,
} from "./abstractions"
import { combine } from "./combine"
import { LensLike, mkLens } from "./lenslike"
// Views for Atom
export function view(
a: Atom,
key: K
): K extends number ? Atom : Atom
export function view(a: Atom, lens: LensLike): Atom
// Views for Property
export function view(
a: Property,
key: K
): K extends number ? Property : Property
export function view(a: Property, lens: LensLike): Property
export function view(a: Property, fn: Function1): Property
export function view(
a: Property,
fn1: Function1,
fn2: Function1
): Property
export function view(
a: Property,
fn1: Function1,
fn2: Function1,
fn3: Function1
): Property
// Views for 2 or more Properties (combining latest values)
export function view(
a: Property,
b: Property,
fn: Function2
): Property
export function view(
a: Property,
b: Property,
c: Property,
fn: Function3
): Property
export function view(
a: Property,
b: Property,
c: Property,
d: Property,
fn: Function4
): Property
export function view(
a: Property,
b: Property,
c: Property,
d: Property,
e: Property,
fn: Function5
): Property
export function view(
a: Property,
b: Property,
c: Property,
d: Property,
e: Property,
f: Property,
fn: Function6
): Property
// Views for PropertySeed
export function view(
a: PropertySeed,
key: K
): K extends number ? PropertySeed : PropertySeed
export function view(
a: PropertySeed,
lens: LensLike
): PropertySeed
export function view(
a: PropertySeed,
fn: Function1
): PropertySeed
export function view(
a: PropertySeed,
fn1: Function1,
fn2: Function1
): PropertySeed
export function view(
a: PropertySeed,
fn1: Function1,
fn2: Function1,
fn3: Function1
): PropertySeed
// Views for EventStream
export function view(
a: EventStream,
key: K
): K extends number ? EventStream : EventStream
export function view(
a: EventStream,
lens: LensLike
): EventStream
export function view(
a: EventStream,
fn: Function1
): EventStream
export function view(
a: EventStream,
fn1: Function1,
fn2: Function1
): EventStream
export function view(
a: EventStream,
fn1: Function1,
fn2: Function1,
fn3: Function1
): EventStream
// Views for EventStreamSeed
export function view(
a: EventStreamSeed,
key: K
): K extends number ? EventStreamSeed : EventStreamSeed
export function view(
a: EventStreamSeed,
lens: LensLike
): EventStreamSeed
export function view(
a: EventStreamSeed,
fn: Function1
): EventStreamSeed
export function view(
a: EventStreamSeed,
fn1: Function1,
fn2: Function1
): EventStreamSeed
export function view(
a: EventStreamSeed,
fn1: Function1,
fn2: Function1,
fn3: Function1
): EventStreamSeed
export function view(...args: any[]): any {
if (args[args.length - 1] instanceof Function) {
// properties + function
let fnIndex = 0
while (!(args[fnIndex] instanceof Function)) fnIndex++
const properties = args.slice(0, fnIndex)
if (properties.length === 1) {
const property = properties[0]
let o = property
for (let i = fnIndex; i < args.length; i++) {
const fn = args[i]
o = map(fn)(o)
}
const desc = [property, "view", args.slice(fnIndex)] as Desc
return rename(desc, o)
} else {
const fn = args[args.length - 1]
return rename(["view", [...properties, fn]], combine(properties, fn))
}
} else {
// property/atom + lens
const atom = args[0]
const view = args[1]
let lens = keyOrLens2Lens(view)
const desc = [atom, "view", [view]] as Desc
if (isAtom(atom)) {
return new LensedAtom(desc, atom, lens)
} else {
return rename(desc, map(lens.get)(atom as any))
}
}
}
function keyOrLens2Lens(view: any) {
if (typeof view === "string") {
return L.prop(view)
} else if (typeof view === "number") {
return L.item(view as number)
} else {
return mkLens(view)
}
}