diff --git a/alt/alt-tests.ts b/alt/alt-tests.ts new file mode 100644 index 000000000..403c9d99a --- /dev/null +++ b/alt/alt-tests.ts @@ -0,0 +1,143 @@ +/** + * Created by shearerbeard on 6/28/15. + */ +/// +/// + +import Alt = require("alt"); +import Promise = require("es6-promise"); + +//New alt instance +var alt = new Alt(); + +//Interfaces for our Action Types +interface TestActionsGenerate { + notifyTest(str:string):void; +} + +interface TestActionsExplicit { + doTest(str:string):void; + success():void; + error():void; + loading():void; +} + +//Create abstracts to inherit ghost methods +class AbstractActions implements AltJS.ActionsClass { + constructor( alt:AltJS.Alt){} + actions:any; + dispatch: ( ...payload:Array) => void; + generateActions:( ...actions:Array) => void; +} + +class AbstractStoreModel implements AltJS.StoreModel { + bindActions:( ...actions:Array) => void; + bindAction:( ...args:Array) => void; + bindListeners:(obj:any)=> void; + exportPublicMethods:(config:{[key:string]:(...args:Array) => any}) => any; + exportAsync:( source:any) => void; + waitFor:any; + exportConfig:any; + getState:() => S; +} + +class GenerateActionsClass extends AbstractActions { + constructor(config:AltJS.Alt) { + this.generateActions("notifyTest"); + super(config); + } +} + +class ExplicitActionsClass extends AbstractActions { + doTest(str:string) { + this.dispatch(str); + } + success() { + this.dispatch(); + } + error() { + this.dispatch(); + } + loading() { + this.dispatch(); + } +} + +var generatedActions = alt.createActions(GenerateActionsClass); +var explicitActions = alt.createActions(ExplicitActionsClass); + +interface AltTestState { + hello:string; +} + +var testSource:AltJS.Source = { + fakeLoad():AltJS.SourceModel { + return { + remote() { + return new Promise.Promise((res:any, rej:any) => { + setTimeout(() => { + if(true) { + res("stuff"); + } else { + rej("Things have broken"); + } + }, 250) + }); + }, + local() { + return "local"; + }, + success: explicitActions.success, + error: explicitActions.error, + loading:explicitActions.loading + }; + } +}; + +class TestStore extends AbstractStoreModel implements AltTestState { + hello:string = "world"; + constructor() { + super(); + this.bindAction(generatedActions.notifyTest, this.onTest); + this.bindActions(explicitActions); + this.exportAsync(testSource); + this.exportPublicMethods({ + split: this.split + }); + } + onTest(str:string) { + this.hello = str; + } + + onDoTest(str:string) { + this.hello = str; + } + + split():string[] { + return this.hello.split(""); + } +} + +interface ExtendedTestStore extends AltJS.AltStore { + fakeLoad():string; + split():Array; +} + +var testStore = alt.createStore(TestStore); + +function testCallback(state:AltTestState) { + console.log(state); +} + +//Listen allows a typed state callback +testStore.listen(testCallback); +testStore.unlisten(testCallback); + +//State generic passes to derived store +var name:string = testStore.getState().hello; +var nameChars:Array = testStore.split(); + +generatedActions.notifyTest("types"); +explicitActions.doTest("more types"); + +export var result = testStore.getState(); diff --git a/alt/alt.d.ts b/alt/alt.d.ts new file mode 100644 index 000000000..0e0b40d8f --- /dev/null +++ b/alt/alt.d.ts @@ -0,0 +1,167 @@ +// Type definitions for Alt 0.16.10 +// Project: https://github.com/goatslacker/alt +// Definitions by: Michael Shearer +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +/// + +declare module AltJS { + + interface StoreReduce { + action:any; + data: any; + } + + export interface StoreModel { + //Actions + bindAction?( action:Action, handler:ActionHandler):void; + bindActions?(actions:ActionsClass):void; + + //Methods/Listeners + exportPublicMethods?(exportConfig:any):void; + bindListeners?(config:{[methodName:string]:Action | Actions}):void; + exportAsync?(source:Source):void; + registerAsync?(datasource:Source):void; + + //state + setState?(state:S):void; + setState?(stateFn:(currentState:S, nextState:S) => S):void; + getState?():S; + waitFor?(store:AltStore):void; + + //events + onSerialize?(fn:(data:any) => any):void; + onDeserialize?(fn:(data:any) => any):void; + on?(event:AltJS.lifeCycleEvents, callback:() => any):void; + emitChange?():void; + waitFor?(storeOrStores:AltStore | Array>):void; + otherwise?(data:any, action:AltJS.Action):void; + observe?(alt:Alt):any; + reduce?(state:any, config:StoreReduce):Object; + preventDefault?():void; + afterEach?(payload:Object, state:Object):void; + beforeEach?(payload:Object, state:Object):void; + // TODO: Embed dispatcher interface in def + dispatcher?:any; + + //instance + getInstance?():AltJS.AltStore; + alt?:Alt; + displayName?:string; + } + + export type Source = {[name:string]: () => SourceModel}; + + export interface SourceModel { + local(state:any):any; + remote(state:any):Promise; + shouldFetch?(fetchFn:(...args:Array) => boolean):void; + loading?:(args:any) => void; + success?:(state:S) => void; + error?:(args:any) => void; + interceptResponse?(response:any, action:Action, ...args:Array):any; + } + + export interface AltStore { + getState():S; + listen(handler:(state:S) => any):() => void; + unlisten(handler:(state:S) => any):void; + emitChange():void; + } + + export enum lifeCycleEvents { + bootstrap, + snapshot, + init, + rollback, + error + } + + export type Actions = {[action:string]:Action}; + + export interface Action { + ( args:T):void; + defer(data:any):void; + } + + export interface ActionsClass { + generateActions?( ...action:Array):void; + dispatch( ...payload:Array):void; + actions?:Actions; + } + + type StateTransform = (store:StoreModel) => AltJS.AltStore; + + interface AltConfig { + dispatcher?:any; + serialize?:(serializeFn:(data:Object) => string) => void; + deserialize?:(deserializeFn:(serialData:string) => Object) => void; + storeTransforms?:Array; + batchingFunction?:(callback:( ...data:Array) => any) => void; + } + + class Alt { + constructor(config?:AltConfig); + actions:Actions; + bootstrap(jsonData:string):void; + takeSnapshot( ...storeNames:Array):string; + flush():Object; + recycle( ...stores:Array>):void; + rollback():void; + dispatch(action?:AltJS.Action, data?:Object, details?:any):void; + + //Actions methods + addActions(actionsName:string, ActionsClass: ActionsClassConstructor):void; + createActions(ActionsClass: ActionsClassConstructor, exportObj?: Object):T; + createActions(ActionsClass: ActionsClassConstructor, exportObj?: Object, ...constructorArgs:Array):T; + generateActions( ...actions:Array):T; + getActions(actionsName:string):AltJS.Actions; + + //Stores methods + addStore(name:string, store:StoreModel, saveStore?:boolean):void; + createStore(store:StoreModel, name?:string):AltJS.AltStore; + getStore(name:string):AltJS.AltStore; + } + + export interface AltFactory { + new(config?:AltConfig):Alt; + } + + type ActionsClassConstructor = new (alt:Alt) => AltJS.ActionsClass; + + type ActionHandler = ( ...data:Array) => any; + type ExportConfig = {[key:string]:(...args:Array) => any}; +} + +declare module "alt/utils/chromeDebug" { + function chromeDebug(alt:AltJS.Alt):void; + export = chromeDebug; +} + +declare module "alt/AltContainer" { + + import React = require("react"); + + interface ContainerProps { + store?:AltJS.AltStore; + stores?:Array>; + inject?:{[key:string]:any}; + actions?:{[key:string]:Object}; + render?:(...props:Array) => React.ReactElement; + flux?:AltJS.Alt; + transform?:(store:AltJS.AltStore, actions:any) => any; + shouldComponentUpdate?:(props:any) => boolean; + component?:React.Component; + } + + type AltContainer = React.ReactElement; + var AltContainer:React.ComponentClass; + + export = AltContainer; +} + +declare module "alt" { + var alt:AltJS.AltFactory; + export = alt; +}