diff --git a/flux/flux-tests.ts b/flux/flux-tests.ts index f41d15aff1..24369ef2dd 100644 --- a/flux/flux-tests.ts +++ b/flux/flux-tests.ts @@ -1,6 +1,12 @@ /// +/// import flux = require('flux') +import FluxUtils = require('flux/utils') +import React = require('react') + +var Component = React.Component +var Container = FluxUtils.Container // // Basic dispatcher usage @@ -78,4 +84,46 @@ class CustomDispatcher extends flux.Dispatcher { var customDispatcher = new CustomDispatcher() -export = customDispatcher \ No newline at end of file +export = customDispatcher + + +// Sample Reduce Store +class CounterStore extends FluxUtils.ReduceStore { + getInitialState(): number { + return 0; + } + + reduce(state: number, action: any): number { + switch (action.type) { + case 'increment': + return state + 1; + + case 'square': + return state * state; + + default: + return state; + } + } +} + +const Store = new CounterStore(basicDispatcher); + +// Sample Flux container with CounterStore +class CounterContainer extends Component { + static getStores() { + return [Store]; + } + + static calculateState(prevState: any) { + return { + counter: Store.getState(), + }; + } + + render() { + return this.state.counter; + } +} + +const container = Container.create(CounterContainer); diff --git a/flux/flux.d.ts b/flux/flux.d.ts index bf5bafac4b..c65892321c 100644 --- a/flux/flux.d.ts +++ b/flux/flux.d.ts @@ -1,8 +1,10 @@ // Type definitions for Flux // Project: http://facebook.github.io/flux/ -// Definitions by: Steve Baker +// Definitions by: Steve Baker , Giedrius Grabauskas // Definitions: https://github.com/borisyankov/DefinitelyTyped +/// + declare module Flux { /** @@ -65,3 +67,127 @@ declare module Flux { declare module "flux" { export = Flux; } + +declare module FluxUtils { + + export class Container { + constructor(); + /** + * Create is used to transform a react class into a container + * that updates its state when relevant stores change. + * The provided base class must have static methods getStores() and calculateState(). + */ + static create(base: React.ComponentClass, options?: any): React.ComponentClass; + } + + /** + * This class extends ReduceStore and defines the state as an immutable map. + */ + // TODO: Change to > + export class MapStore extends ReduceStore { + /** + * Access the value at the given key. + * Throws an error if the key does not exist in the cache. + */ + at(key: K): V; + + /** + * Check if the cache has a particular key + */ + has(key: K): boolean; + + /** + * Get the value of a particular key. + * Returns undefined if the key does not exist in the cache. + */ + get(key: K): V; + + /** + * Gets an array of keys and puts the values in a map if they exist, + * it allows providing a previous result to update instead of generating a new map. + * Providing a previous result allows the possibility of keeping the same reference if the keys did not change. + */ + // TODO: Update with Immutable interface. + // getAll(keys: Immutable.IndexedIterable, prev?: Immutable.Map): Immutable.Map; + getAll(keys: any, prev?: any): any; + } + + export class ReduceStore extends Store { + /** + * Getter that exposes the entire state of this store. + * If your state is not immutable you should override this and not expose state directly. + */ + getState(): T; + + /** + * Constructs the initial state for this store. + * This is called once during construction of the store. + */ + getInitialState(): T; + + /** + * Reduces the current state, and an action to the new state of this store. + * All subclasses must implement this method. + * This method should be pure and have no side-effects. + */ + reduce(state: T, action: any): T; + + /** + * Checks if two versions of state are the same. + * You do not need to override this if your state is immutable. + */ + areEqual(one: T, two: T): boolean; + + } + + export class Store { + + /** + * Constructs and registers an instance of this store with the given dispatcher. + */ + constructor(dispatcher: Flux.Dispatcher); + + /** + * Adds a listener to the store, when the store changes the given callback will be called. + * A token is returned that can be used to remove the listener. + * Calling the remove() function on the returned token will remove the listener. + */ + addListener(callback: Function): { remove: Function }; + + /** + * Returns the dispatcher this store is registered with. + */ + getDispatcher(): Flux.Dispatcher; + + /** + * Returns the dispatch token that the dispatcher recognizes this store by. + * Can be used to waitFor() this store. + */ + getDispatchToken(): string; + + /** + * Ask if a store has changed during the current dispatch. + * Can only be invoked while dispatching. + * This can be used for constructing derived stores that depend on data from other stores. + */ + hasChanged(): boolean; + + /** + *Emit an event notifying all listeners that this store has changed. + * This can only be invoked when dispatching. + * Changes are de-duplicated and resolved at the end of this store's __onDispatch function. + */ + __emitChange(): void; + + /** + * Subclasses must override this method. + * This is how the store receives actions from the dispatcher. + * All state mutation logic must be done during this method. + */ + __onDispatch(payload: any): void; + } +} + +declare module 'flux/utils' { + export = FluxUtils; +}