Skip to content

Commit fcdd20c

Browse files
committedNov 25, 2019
add and unify custom factory for sub-states on and on deep states
1 parent 28f510d commit fcdd20c

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed
 

‎src/agent/deep.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { KeyFunc } from "../util/keyed-array-diff";
22

33
import { State } from "./state";
4-
import { SimpleDeep } from "./simple-deep";
4+
import { SimpleDeep, DeepChildFactory, DeepAccessor } from "./simple-deep";
55
import { KeyedDeep } from "./keyed-deep";
6+
import { EqualityFunc } from ".";
67

78

89
export function deep(state: State): SimpleDeep;
@@ -24,4 +25,18 @@ export function deep(state: State, key?: KeyFunc): SimpleDeep | KeyedDeep {
2425
}
2526

2627

28+
/**
29+
*
30+
* Returns a deep child factory that creates [keyed deep](https://connective.dev/docs/deep#keyed-deep) sub-states
31+
* with given key function. Pass this to `.sub()` or `.key()` on [deep states](https://connective.dev/docs/deep)
32+
* to have keyed sub-states.
33+
*
34+
* @param keyfunc the key function to be used
35+
*
36+
*/
37+
export function keyed(keyfunc: KeyFunc): DeepChildFactory<KeyedDeep> {
38+
return (accessor: DeepAccessor, compare: EqualityFunc) => new KeyedDeep(accessor, keyfunc, compare);
39+
}
40+
41+
2742
export default deep;

‎src/agent/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import { composition } from './inline-composition';
2323

2424
import { KeyFunc, ChangeMap, AdditionList, DeletionList, MoveList } from '../util/keyed-array-diff';
2525
import { KeyedDeep } from './keyed-deep';
26-
import { SimpleDeep } from './simple-deep';
27-
import { deep } from './deep';
26+
import { SimpleDeep, DeepAccessor, DeepChildFactory } from './simple-deep';
27+
import { deep, keyed } from './deep';
2828

2929
import { ChildNotDefined } from './errors/child-not-defined.error';
3030
import { ChildIsNotAgent, ChildIsNotPin } from './errors/child-type-mismatch.error';
@@ -44,6 +44,7 @@ export {
4444
exec, call, singleton, sampler,
4545
ChildIsNotAgent, ChildIsNotPin, ChildNotDefined,
4646
InsufficientInputs, InputNotInSignature, OutputNotInSignature,
47-
deep, SimpleDeep, KeyedDeep,
47+
deep, keyed, SimpleDeep, KeyedDeep,
48+
DeepAccessor, DeepChildFactory,
4849
KeyFunc, ChangeMap, AdditionList, MoveList, DeletionList,
4950
}

‎src/agent/keyed-deep.ts

+7-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { value } from "../pin/value";
1010
import { pipe } from "../pin/pipe";
1111
import { PinLike } from "../pin/pin-like";
1212

13-
import { SimpleDeep, DeepAccessor } from "./simple-deep";
13+
import { SimpleDeep, DeepAccessor, DeepChildFactory } from "./simple-deep";
1414
import { State, EqualityFunc } from "./state";
1515

1616

@@ -40,21 +40,22 @@ export class KeyedDeep extends SimpleDeep {
4040
}
4141

4242
public key(key: string | number): SimpleDeep;
43-
public key(key: string | number, subkeyfunc: KeyFunc): KeyedDeep;
43+
public key<T extends SimpleDeep>(key: string | number, factory: DeepChildFactory<T>): T;
4444
/**
4545
*
4646
* Creates a sub-state bound to entity identified by given key. Entity `x` is
4747
* said to be identified by key `k` if `state.keyfunc(x) === k`.
4848
*
4949
* @param key the identifier of the entity to track
50-
* @param subkeyfunc a key function for the sub-state. provide IF the sub-state also needs to be keyed.
50+
* @param factory the factory function to be used to construct the sub-state
5151
*
5252
*/
53-
public key(key: string | number, subkeyfunc?: KeyFunc): SimpleDeep | KeyedDeep {
53+
public key<T extends SimpleDeep>(key: string | number, factory?: DeepChildFactory<T>): SimpleDeep | T {
5454
let initialized = false;
5555
let _this = this;
56+
let _factory = factory || ((accessor: DeepAccessor, compare: EqualityFunc) => new SimpleDeep(accessor, compare));
5657

57-
let accessor: DeepAccessor = {
58+
return _factory({
5859
initial: (_this._keyMap[key] || {item: undefined}).item
5960
|| (Object.values(this.value) || []).find((i: any) => this.keyfunc(i) == key),
6061
get: group(_this.changes, _this.reemit).to(map(() => (_this._keyMap[key] || {item: undefined}).item)),
@@ -79,10 +80,7 @@ export class KeyedDeep extends SimpleDeep {
7980
} catch (err) {}
8081
}),
8182
bind() { return this.set.subscribe(); },
82-
}
83-
84-
if (subkeyfunc) return new KeyedDeep(accessor, subkeyfunc, this.state.compare);
85-
else return new SimpleDeep(accessor, this.state.compare);
83+
}, this.state.compare);
8684
}
8785

8886
/**

‎src/agent/simple-deep.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export interface DeepAccessor {
2121
}
2222

2323

24+
export type DeepChildFactory<T extends SimpleDeep> = (accessor: DeepAccessor, compare: EqualityFunc) => T;
25+
2426
/**
2527
*
2628
* Represents non-keyed (simple) [deep states](https://connective.dev/docs/deep).
@@ -78,19 +80,23 @@ export class SimpleDeep extends Agent {
7880
}
7981
}
8082

83+
public sub(index: string | number): SimpleDeep;
84+
public sub<T extends SimpleDeep>(index: string | number, factory: DeepChildFactory<T>): T;
8185
/**
8286
*
8387
* Creates a sub-state for given index/property.
8488
* [Read this](https://connective.dev/docs/deep) for more details
8589
*
8690
* @param index
91+
* @param factory the factory function to be used to construct the sub-state
8792
*
8893
*/
89-
public sub(index: string | number): SimpleDeep {
94+
public sub<T extends SimpleDeep>(index: string | number, factory?: DeepChildFactory<T>): SimpleDeep | T {
9095
let initialized = false;
9196
let _this = this;
97+
let _factory = factory || ((accessor: DeepAccessor, compare: EqualityFunc) => new SimpleDeep(accessor, compare));
9298

93-
return new SimpleDeep({
99+
return _factory({
94100
initial: (_this.value || [])[index],
95101
get: _this.output.to(map((v: any) => (v || [])[index])),
96102
set: sink((v, context) => {

0 commit comments

Comments
 (0)
Failed to load comments.