Skip to content

Commit

Permalink
Merge branch 'master' into tm/prepare-0.12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
taras committed Nov 3, 2018
2 parents 163e873 + af41ee7 commit 8f19d97
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
19 changes: 12 additions & 7 deletions src/identity.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { foldl } from 'funcadelic';
import { promap, valueOf, pathOf, Meta } from './meta';
import { promap, valueOf, pathOf, Meta, mount } from './meta';
import CachedProperty from './cached-property';
import { methodsOf } from './reflection';
import { isArrayType } from './types/array';
import { create } from './microstates';

//function composition should probably not be part of lens :)
import { At, view, Path, compose, set } from './lens';

class Location {
static data = At(Symbol('@location'));
static id = compose(Location.data, At("id"));
static microstate = compose(Location.data, At("microstate"));
static id = At(Symbol('@id'));
}

export default function Identity(microstate, observe = x => x) {
Expand All @@ -32,8 +32,6 @@ export default function Identity(microstate, observe = x => x) {
let Type = microstate.constructor.Type;
let value = valueOf(microstate);

pathmap = set(compose(Path(path), Location.microstate), microstate, pathmap);

let id = view(compose(Path(path), Location.id), pathmap);

let Id = id != null && id.constructor.Type === Type ? id.constructor : IdType(Type, path);
Expand Down Expand Up @@ -71,7 +69,14 @@ export default function Identity(microstate, observe = x => x) {
Object.assign(Id.prototype, foldl((methods, name) => {
methods[name] = function(...args) {
let path = P;
let microstate = view(compose(Path(path), Location.microstate), pathmap);
let microstate = path.reduce((microstate, key) => {
if (isArrayType(microstate)) {
let value = valueOf(microstate)[key];
return mount(microstate, create(microstate.constructor.T, value), key);
} else {
return microstate[key];
}
}, current);
let next = microstate[name](...args);

return next === current ? identity : tick(next);
Expand Down
9 changes: 9 additions & 0 deletions src/types/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ import { Profunctor, promap, mount, valueOf } from '../meta';
import { create } from '../microstates';
import parameterized from '../parameterized';


const ARRAY_TYPE = Symbol('ArrayType');

export function isArrayType(microstate) {
return microstate.constructor && microstate.constructor[ARRAY_TYPE];
}

export default parameterized(T => class ArrayType {
static T = T;
static get [ARRAY_TYPE]() { return true; }

static get name() {
return `Array<${T.name}>`;
}
Expand Down
27 changes: 27 additions & 0 deletions tests/identity.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,31 @@ describe('Identity', () => {
});
});
});

describe('identity support of type reuse', () => {
class Person {
name = String;
father = Person;
mother = Person;
}

it('it keeps both branches', () => {
let s = Identity(create(Person), next => (s = next));
let { name, father, mother } = s;

name.set('Bart');
father.name.set('Homer');
mother.name.set('Marge');

expect({
name: s.name.state,
father: { name: s.father.name.state },
mother: { name: s.mother.name.state }
}).toEqual({
name: 'Bart',
father: { name: 'Homer' },
mother: { name: 'Marge' }
});
});
});
});

0 comments on commit 8f19d97

Please sign in to comment.