Skip to content

Commit

Permalink
feat(core): bean force update (#40)
Browse files Browse the repository at this point in the history
* feat(core): supports bean force update

* chore(npm): version 0.1.3-beta
  • Loading branch information
foreleven authored and JounQin committed Aug 26, 2019
1 parent dd4037f commit 99460d3
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 13 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stated-bean",
"version": "0.1.2-RC.4",
"version": "0.1.3-beta",
"repository": "[email protected]:mjolnirjs/stated-bean.git",
"license": "MIT",
"main": "dist/cjs",
Expand Down
1 change: 1 addition & 0 deletions src/core/ForceUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ForceUpdate = Symbol('stated-bean-force-update');
38 changes: 34 additions & 4 deletions src/core/StatedBeanContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getMetadataStorage } from '../metadata';

import { StatedBeanApplication } from './StatedBeanApplication';
import { EffectContext } from './EffectContext';
import { ForceUpdate } from './ForceUpdate';

export class StatedBeanContainer extends Event {
private readonly _parent?: StatedBeanContainer;
Expand Down Expand Up @@ -75,11 +76,12 @@ export class StatedBeanContainer extends Event {
return;
}

this.addForceUpdate(bean, beanMeta);

const fields = beanMeta.statedFields || [];
const observers = (fields || []).map(field =>
this.observeBeanField(bean, field, beanMeta),
);

await Promise.all(observers);

if (
Expand All @@ -91,6 +93,32 @@ export class StatedBeanContainer extends Event {
}
}

addForceUpdate<T>(bean: T, beanMeta: StatedBeanMeta) {
const self = this;
Object.defineProperty(bean, ForceUpdate, {
value: function(field: keyof T & string) {
if (bean[field] === undefined) {
return;
}
const fieldMeta = (beanMeta.statedFields || []).find(
f => f.name === field,
);
if (fieldMeta === undefined) {
return;
}
const effect = self.createEffectContext(
bean[field],
bean,
beanMeta,
fieldMeta,
bean[field],
);

self.emit(bean, effect);
},
});
}

async observeBeanField(
bean: any,
fieldMeta: StatedFieldMeta,
Expand Down Expand Up @@ -123,11 +151,13 @@ export class StatedBeanContainer extends Event {
value,
);

bean[proxyField] = effect.getValue();
bean[proxyField] = value;
self.application.interceptStateChange(effect).then(() => {
bean[proxyField] = effect.getValue();
if (effect.getValue() !== value) {
bean[proxyField] = effect.getValue();
}
// console.log(bean.constructor.name + '_changed');
self.emit(beanMeta.target, effect);
self.emit(bean, effect);
});
},
get() {
Expand Down
1 change: 1 addition & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './StatedBeanApplication';
export * from './StatedBeanContainer';
export * from './StatedBeanFactory';
export * from './StatedBeanScope';
export * from './ForceUpdate';
10 changes: 6 additions & 4 deletions src/event/Event.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { ClassType } from '../types';

type EventListenFn = (...args: any) => void;
type EventTypes = WeakMap<Function, EventListenFn[]>;
type EventTypes = WeakMap<InstanceType<ClassType>, EventListenFn[]>;

export class Event {
events: EventTypes = new WeakMap();

on(type: Function, cb: EventListenFn) {
on(type: InstanceType<ClassType>, cb: EventListenFn) {
this.events.set(type, (this.events.get(type) || []).concat(cb));
}

emit(type: Function, ...data: any) {
emit(type: InstanceType<ClassType>, ...data: any) {
if (this.events.has(type)) {
this.events.get(type)!.forEach(cb => {
cb(...data);
});
}
}

off(type: Function, cb: EventListenFn) {
off(type: InstanceType<ClassType>, cb: EventListenFn) {
if (this.events.has(type)) {
this.events.set(type, this.events.get(type)!.filter(c => c !== cb));
}
Expand Down
9 changes: 5 additions & 4 deletions src/hooks/useStatedBean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ export function useStatedBean<T extends ClassType>(
container.register(type);
}

if (container !== undefined) {
container.on(type, beanChangeListener);
}
return container;
});

Expand All @@ -59,7 +56,11 @@ export function useStatedBean<T extends ClassType>(
}

const [bean] = useState(() => {
return container.getBean<InstanceType<T>>(type);
const bean = container.getBean<InstanceType<T>>(type);
if (container !== undefined) {
container.on(bean, beanChangeListener);
}
return bean;
});

if (bean === undefined) {
Expand Down

0 comments on commit 99460d3

Please sign in to comment.