Skip to content
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.

Commit

Permalink
Update to shim Observables and remove legacy mixins (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
agubler committed Dec 19, 2016
1 parent e5114ed commit 7a566a0
Show file tree
Hide file tree
Showing 15 changed files with 59 additions and 1,404 deletions.
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -23,7 +23,6 @@
"dojo-core": ">=2.0.0-alpha.16"
},
"devDependencies": {
"@reactivex/rxjs": "5.0.0-beta.6",
"@types/chai": "~3.4.0",
"@types/glob": "~5.0.0",
"@types/grunt": "~0.4.0",
Expand Down
52 changes: 16 additions & 36 deletions src/bases/createStateful.ts
Expand Up @@ -3,59 +3,42 @@ import { Handle } from 'dojo-interfaces/core';
import {
Evented,
Stateful,
State,
StatefulOptions,
StatefulMixin
} from 'dojo-interfaces/bases';
import { Observable, Subscription } from 'dojo-interfaces/observables';
import Promise from 'dojo-shim/Promise';
import { StoreObservablePatchable } from 'dojo-interfaces/abilities';
import { Subscription } from 'dojo-shim/Observable';
import WeakMap from 'dojo-shim/WeakMap';
import createEvented from './createEvented';
import { ComposeFactory } from '../compose';
import createCancelableEvent from './createCancelableEvent';

export interface ObservableState<S extends State> {
/**
* A method that allows the return of an `Observable` interface for a particular `id`
* @param id The ID to observe
*/
observe(id: string): Observable<S>;

/**
* A method that allows the `Stateful` to provide a change to its state, instead of
* changing its state directly.
* @param partial The partial state to be *patched*
* @param options A map of options, which includes the `id` being observed
*/
patch(partial: any, options?: { id?: string }): Promise<S>;
}

export interface StatefulFactory extends ComposeFactory<Stateful<State>, StatefulOptions<State>> {
<S extends State>(options?: StatefulOptions<S>): Stateful<S>;
export interface StatefulFactory extends ComposeFactory<Stateful<Object>, StatefulOptions<Object>> {
<S extends Object>(options?: StatefulOptions<S>): Stateful<S>;
}

/**
* Internal interface which contains references to an observed state
*/
interface ObservedState {
id: string;
observable: ObservableState<State>;
observable: StoreObservablePatchable<Object>;
subscription: Subscription;
handle: Handle;
}

/**
* A weak map of stateful instances to their obseved state references
*/
const observedStateMap = new WeakMap<Stateful<State>, ObservedState>();
const observedStateMap = new WeakMap<Stateful<Object>, ObservedState>();

/**
* Internal function to unobserve the state of a `Stateful`. It emits a `statecomplete` event which can be
* cancelled.
*
* @param stateful The `Stateful` object to unobserve
*/
function completeStatefulState(stateful: Stateful<State>): void {
function completeStatefulState(stateful: Stateful<Object>): void {
const observedState = observedStateMap.get(stateful);
if (observedState) {
observedState.handle.destroy();
Expand All @@ -77,7 +60,7 @@ function completeStatefulState(stateful: Stateful<State>): void {
* @param stateful The Stateful instance
* @param state The State to be set
*/
function setStatefulState(target: Stateful<State>, state: State): void {
function setStatefulState(target: Stateful<Object>, state: Object): void {
const previousState = stateWeakMap.get(target);
if (!previousState) {
throw new Error('Unable to set destroyed state');
Expand All @@ -95,7 +78,7 @@ function setStatefulState(target: Stateful<State>, state: State): void {
/**
* A weak map that contains the stateful's state
*/
const stateWeakMap = new WeakMap<Stateful<State>, State>();
const stateWeakMap = new WeakMap<Stateful<Object>, Object>();

/**
* Create an instance of a stateful object
Expand All @@ -104,18 +87,18 @@ const createStateful: StatefulFactory = createEvented
.mixin({
className: 'Stateful',
mixin: {
get stateFrom(this: Stateful<State>): ObservableState<State> | undefined {
get stateFrom(this: Stateful<Object>): StoreObservablePatchable<Object> | undefined {
const observedState = observedStateMap.get(this);
if (observedState) {
return observedState.observable;
}
},

get state(this: Stateful<State>): State {
get state(this: Stateful<Object>): Object {
return stateWeakMap.get(this);
},

setState(this: Stateful<State>, value: State): void {
setState(this: Stateful<Object>, value: Object) {
const observedState = observedStateMap.get(this);
if (observedState) {
observedState.observable.patch(value, { id: observedState.id });
Expand All @@ -125,7 +108,7 @@ const createStateful: StatefulFactory = createEvented
}
},

observeState(this: Stateful<State>, id: string, observable: ObservableState<State>): Handle {
observeState(this: Stateful<Object>, id: string, observable: StoreObservablePatchable<Object>): Handle {
let observedState = observedStateMap.get(this);
if (observedState) {
if (observedState.id === id && observedState.observable === observable) {
Expand Down Expand Up @@ -157,28 +140,25 @@ const createStateful: StatefulFactory = createEvented
}
);

observedStateMap.set(stateful, { id, observable, subscription, handle });
observedStateMap.set(stateful, { id, observable, subscription: <Subscription> subscription, handle });
return handle;
}
},
initialize(instance: StatefulMixin<State> & Evented, options: StatefulOptions<State>) {
initialize(instance: StatefulMixin<Object> & Evented, options: StatefulOptions<Object>) {
stateWeakMap.set(instance, Object.create(null));
instance.own({
destroy() {
stateWeakMap.delete(instance);
}
});
if (options) {
const { id, stateFrom, state } = options;
const { id, stateFrom } = options;
if (typeof id !== 'undefined' && stateFrom) {
instance.own(instance.observeState(id, stateFrom));
}
else if (stateFrom) {
throw new TypeError('When "stateFrom" option is supplied, factory also requires "id" option.');
}
if (state) {
instance.setState(state);
}
}
}
});
Expand Down
6 changes: 3 additions & 3 deletions src/main.ts
@@ -1,7 +1,7 @@
import compose, { isComposeFactory } from './compose';
import createDestroyable from './mixins/createDestroyable';
import createEvented from './mixins/createEvented';
import createStateful from './mixins/createStateful';
import createDestroyable from './bases/createDestroyable';
import createEvented from './bases/createEvented';
import createStateful from './bases/createStateful';

export {
compose,
Expand Down
87 changes: 0 additions & 87 deletions src/mixins/createDestroyable.ts

This file was deleted.

0 comments on commit 7a566a0

Please sign in to comment.