From 69edb71444358507318d154255879336dcc35978 Mon Sep 17 00:00:00 2001 From: Wouter de Vries Date: Sat, 18 Jul 2015 15:03:16 +0200 Subject: [PATCH 01/17] added file typing for callbacks --- multer/multer.d.ts | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/multer/multer.d.ts b/multer/multer.d.ts index fdde44b54..04754fa2a 100644 --- a/multer/multer.d.ts +++ b/multer/multer.d.ts @@ -40,6 +40,29 @@ declare module "multer" { function multer(options?: multer.Options): express.RequestHandler; module multer { + type MulterFile = { + /** Field name specified in the form */ + fieldname: string; + /** Name of the file on the user's computer */ + originalname: string; + /** Renamed file name */ + name: string; + /** Encoding type of the file */ + encoding: string; + /** Mime type of the file */ + mimetype: string; + /** Location of the uploaded file */ + path: string; + /** Extension of the file */ + extension: string; + /** Size of the file in bytes */ + size: number; + /** If the file was truncated due to size limitation */ + truncated: boolean; + /** Raw data (is null unless the inMemory option is true) */ + buffer: Buffer; + }; + type Options = { /** The destination directory for the uploaded files. */ dest?: string; @@ -69,11 +92,11 @@ declare module "multer" { /** Function to rename the directory in which to place uploaded files. The dest parameter is the default value originally assigned or passed into multer. The req and res parameters are also passed into the function because they may contain information (eg session data) needed to create the path (eg get userid from the session). */ changeDest?: (dest: string, req: Express.Request, res: Express.Response) => string; /** Event handler triggered when a file starts to be uploaded. A file object, with the following properties, is available to this function: fieldname, originalname, name, encoding, mimetype, path, and extension. */ - onFileUploadStart?: (file: string, req: Express.Request, res: Express.Response) => void; + onFileUploadStart?: (file: MulterFile, req: Express.Request, res: Express.Response) => void; /** Event handler triggered when a chunk of buffer is received. A buffer object along with a file object is available to the function. */ - onFileUploadData?: (file: string, data: Buffer, req: Express.Request, res: Express.Response) => void; + onFileUploadData?: (file: MulterFile, data: Buffer, req: Express.Request, res: Express.Response) => void; /** Event handler trigger when a file is completely uploaded. A file object is available to the function. */ - onFileUploadComplete?: (file: string, req: Express.Request, res: Express.Response) => void; + onFileUploadComplete?: (file: MulterFile, req: Express.Request, res: Express.Response) => void; /** Event handler triggered when the form parsing starts. */ onParseStart?: () => void; /** Event handler triggered when the form parsing completes. The request object and the next objects are are passed to the function. */ @@ -81,7 +104,7 @@ declare module "multer" { /** Event handler for any errors encountering while processing the form. The error object and the next object is available to the function. If you are handling errors yourself, make sure to terminate the request or call the next() function, else the request will be left hanging. */ onError?: () => void; /** Event handler triggered when a file size exceeds the specification in the limit object. No more files will be parsed after the limit is reached. */ - onFileSizeLimit?: (file: string) => void; + onFileSizeLimit?: (file: MulterFile) => void; /** Event handler triggered when the number of files exceed the specification in the limit object. No more files will be parsed after the limit is reached. */ onFilesLimit?: () => void; /** Event handler triggered when the number of fields exceed the specification in the limit object. No more fields will be parsed after the limit is reached. */ From 6581370a8bd7ce522c7dd7f02898753e046a456a Mon Sep 17 00:00:00 2001 From: Wouter de Vries Date: Sun, 19 Jul 2015 14:49:30 +0200 Subject: [PATCH 02/17] shared interface + updated File properties --- multer/multer.d.ts | 77 +++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/multer/multer.d.ts b/multer/multer.d.ts index 04754fa2a..06a9d4f7a 100644 --- a/multer/multer.d.ts +++ b/multer/multer.d.ts @@ -5,31 +5,34 @@ /// + declare module Express { export interface Request { files: { - [fieldname: string]: { - /** Field name specified in the form */ - fieldname: string; - /** Name of the file on the user's computer */ - originalname: string; - /** Renamed file name */ - name: string; - /** Encoding type of the file */ - encoding: string; - /** Mime type of the file */ - mimetype: string; - /** Location of the uploaded file */ - path: string; - /** Extension of the file */ - extension: string; - /** Size of the file in bytes */ - size: number; - /** If the file was truncated due to size limitation */ - truncated: boolean; - /** Raw data (is null unless the inMemory option is true) */ - buffer: Buffer; - } + [fieldname: string]: Multer.File + } + } + + module Multer { + export interface File { + /** Field name specified in the form */ + fieldname: string; + /** Name of the file on the user's computer */ + originalname: string; + /** Encoding type of the file */ + encoding: string; + /** Mime type of the file */ + mimetype: string; + /** Size of the file in bytes */ + size: number; + /** The folder to which the file has been saved (DiskStorage) */ + destination: string; + /** The name of the file within the destination (DiskStorage) */ + filename: string; + /** Location of the uploaded file (DiskStorage) */ + path: string; + /** A Buffer of the entire file (MemoryStorage) */ + buffer: Buffer; } } } @@ -40,28 +43,6 @@ declare module "multer" { function multer(options?: multer.Options): express.RequestHandler; module multer { - type MulterFile = { - /** Field name specified in the form */ - fieldname: string; - /** Name of the file on the user's computer */ - originalname: string; - /** Renamed file name */ - name: string; - /** Encoding type of the file */ - encoding: string; - /** Mime type of the file */ - mimetype: string; - /** Location of the uploaded file */ - path: string; - /** Extension of the file */ - extension: string; - /** Size of the file in bytes */ - size: number; - /** If the file was truncated due to size limitation */ - truncated: boolean; - /** Raw data (is null unless the inMemory option is true) */ - buffer: Buffer; - }; type Options = { /** The destination directory for the uploaded files. */ @@ -92,11 +73,11 @@ declare module "multer" { /** Function to rename the directory in which to place uploaded files. The dest parameter is the default value originally assigned or passed into multer. The req and res parameters are also passed into the function because they may contain information (eg session data) needed to create the path (eg get userid from the session). */ changeDest?: (dest: string, req: Express.Request, res: Express.Response) => string; /** Event handler triggered when a file starts to be uploaded. A file object, with the following properties, is available to this function: fieldname, originalname, name, encoding, mimetype, path, and extension. */ - onFileUploadStart?: (file: MulterFile, req: Express.Request, res: Express.Response) => void; + onFileUploadStart?: (file: Express.Multer.File, req: Express.Request, res: Express.Response) => void; /** Event handler triggered when a chunk of buffer is received. A buffer object along with a file object is available to the function. */ - onFileUploadData?: (file: MulterFile, data: Buffer, req: Express.Request, res: Express.Response) => void; + onFileUploadData?: (file: Express.Multer.File, data: Buffer, req: Express.Request, res: Express.Response) => void; /** Event handler trigger when a file is completely uploaded. A file object is available to the function. */ - onFileUploadComplete?: (file: MulterFile, req: Express.Request, res: Express.Response) => void; + onFileUploadComplete?: (file: Express.Multer.File, req: Express.Request, res: Express.Response) => void; /** Event handler triggered when the form parsing starts. */ onParseStart?: () => void; /** Event handler triggered when the form parsing completes. The request object and the next objects are are passed to the function. */ @@ -104,7 +85,7 @@ declare module "multer" { /** Event handler for any errors encountering while processing the form. The error object and the next object is available to the function. If you are handling errors yourself, make sure to terminate the request or call the next() function, else the request will be left hanging. */ onError?: () => void; /** Event handler triggered when a file size exceeds the specification in the limit object. No more files will be parsed after the limit is reached. */ - onFileSizeLimit?: (file: MulterFile) => void; + onFileSizeLimit?: (file: Express.Multer.File) => void; /** Event handler triggered when the number of files exceed the specification in the limit object. No more files will be parsed after the limit is reached. */ onFilesLimit?: () => void; /** Event handler triggered when the number of fields exceed the specification in the limit object. No more fields will be parsed after the limit is reached. */ From 5aef2837fefe67d260b28f24b3c8ac57d526951c Mon Sep 17 00:00:00 2001 From: Sam Saint-Pettersen Date: Sun, 19 Jul 2015 15:32:32 +0100 Subject: [PATCH 03/17] Type definitions and tests fro camel-case --- camel-case/camel-case-tests.ts | 10 ++++++++++ camel-case/camel-case.d.ts | 9 +++++++++ 2 files changed, 19 insertions(+) create mode 100644 camel-case/camel-case-tests.ts create mode 100644 camel-case/camel-case.d.ts diff --git a/camel-case/camel-case-tests.ts b/camel-case/camel-case-tests.ts new file mode 100644 index 000000000..4f40e11fb --- /dev/null +++ b/camel-case/camel-case-tests.ts @@ -0,0 +1,10 @@ +/// + +import camelCase = require('camel-case'); + +console.log(camelCase('string')); // => "string" +console.log(camelCase('dot.case')); // => "dotCase" +console.log(camelCase('PascalCase')); // => "pascalCase" +console.log(camelCase('version 1.2.10')); // => "version1_2_10" + +console.log(camelCase('STRING 1.2', 'tr')); // => "strıng1_2" diff --git a/camel-case/camel-case.d.ts b/camel-case/camel-case.d.ts new file mode 100644 index 000000000..9b2ec3fec --- /dev/null +++ b/camel-case/camel-case.d.ts @@ -0,0 +1,9 @@ +// Type definitions for camel-case +// Project: https://github.com/blakeembrey/camel-case +// Definitions by: Sam Saint-Pettersen +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "camel-case" { + function camelCase(string: string, locale?: string): string; + export = camelCase; +} From 7ad636e4f819d7a1e7f8a858b7093cff64267b3f Mon Sep 17 00:00:00 2001 From: Guillaume Mouron Date: Sun, 19 Jul 2015 19:14:43 +0200 Subject: [PATCH 04/17] [CHEERIO] The find function can also take a cheerio element as an argument cf. documentation : https://github.com/cheeriojs/cheerio#findnode --- cheerio/cheerio.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/cheerio/cheerio.d.ts b/cheerio/cheerio.d.ts index cd0be3593..af708cf0a 100644 --- a/cheerio/cheerio.d.ts +++ b/cheerio/cheerio.d.ts @@ -44,6 +44,7 @@ interface Cheerio { // Traversing find(selector: string): Cheerio; + find(element: Cheerio): Cheerio; parent(selector?: string): Cheerio; parents(selector?: string): Cheerio; From 57c60745dba8098462f20c28d1e1db848e8372a2 Mon Sep 17 00:00:00 2001 From: Graham Mendick Date: Sun, 19 Jul 2015 20:19:01 +0100 Subject: [PATCH 05/17] Updated typings and tests for Navigation 1.1.0 --- navigation/navigation-tests.ts | 251 ++++++++++++++++++--------------- navigation/navigation.d.ts | 152 ++++++++++++++++++-- 2 files changed, 279 insertions(+), 124 deletions(-) diff --git a/navigation/navigation-tests.ts b/navigation/navigation-tests.ts index e0871a267..758e0e53f 100644 --- a/navigation/navigation-tests.ts +++ b/navigation/navigation-tests.ts @@ -1,117 +1,138 @@ /// -// History Manager -class LogHistoryManager extends Navigation.HashHistoryManager { - addHistory(state: Navigation.State, url: string) { - console.log('add history'); - super.addHistory(state, url); - } -} - -// State Router -class LogStateRouter extends Navigation.StateRouter { - getData(route: string): { state: Navigation.State; data: any } { - console.log('get data'); - return super.getData(route); - } -} - -// Settings -Navigation.settings.router = new LogStateRouter(); -Navigation.settings.historyManager = new LogHistoryManager(); -Navigation.settings.stateIdKey = 'state'; - -// Configuration -Navigation.StateInfoConfig.build([ - { key: 'home', initial: 'page', states: [ - { key: 'page', route: '' } - ]}, - { key: 'person', initial: 'list', states: [ - { key: 'list', route: 'people/{page}', transitions: [ - { key: 'select', to: 'details' } - ], defaults: { page: 1 }, trackCrumbTrail: false }, - { key: 'details', route: 'person/{id}', defaultTypes: { id: 'number' } } - ]} -]); - -// StateInfo -var dialogs = Navigation.StateInfoConfig.dialogs; -var home = dialogs['home']; -var homePage = home.states['page']; -var homeKey = home.key; -var homePageKey = homePage.key; -homePage = home.initial; -var person = dialogs['person']; -var personList = person.states['list']; -var personDetails = person.states['details']; -var personListSelect = personList.transitions['select']; -personList = personListSelect.parent; -personDetails = personListSelect.to; -var pageDefault = personList.defaults.page; -var idDefaultType = personDetails.defaultTypes.id; - -// StateNavigator -personList.dispose = () => {}; -personList.navigating = (data, url, navigate) => { - navigate(); -}; -personList.navigated = (data) => {}; - -// State Handler -class LogStateHandler extends Navigation.StateHandler { - getNavigationData(state: Navigation.State, url: string): any { - console.log('get navigation data'); - super.getNavigationData(state, url); - } -} -homePage.stateHandler = new LogStateHandler(); -personList.stateHandler = new LogStateHandler(); -personDetails.stateHandler = new LogStateHandler(); - -// Navigation Event -var navigationListener = -(oldState: Navigation.State, state: Navigation.State, data: any) => { - Navigation.StateController.offNavigate(navigationListener); -}; -Navigation.StateController.onNavigate(navigationListener); - -// Navigation -Navigation.start('home'); -Navigation.StateController.navigate('person'); -Navigation.StateController.refresh(); -Navigation.StateController.refresh({ page: 2 }); -Navigation.StateController.navigate('select', { id: 10 }); -var canGoBack: boolean = Navigation.StateController.canNavigateBack(1); -Navigation.StateController.navigateBack(1); - -// Navigation Link -var link = Navigation.StateController.getNavigationLink('person'); -link = Navigation.StateController.getRefreshLink(); -link = Navigation.StateController.getRefreshLink({ page: 2 }); -link = Navigation.StateController.getNavigationLink('select', { id: 10 }); -var nextDialog = Navigation.StateController.getNextState('select').parent; -person = nextDialog; -Navigation.StateController.navigateLink(link); -link = Navigation.StateController.getNavigationBackLink(1); -var crumb = Navigation.StateController.crumbs[0]; -link = crumb.navigationLink; - -// StateContext -Navigation.StateController.navigate('home'); -Navigation.StateController.navigate('person'); -home = Navigation.StateContext.previousDialog; -homePage = Navigation.StateContext.previousState; -person === Navigation.StateContext.dialog; -personList === Navigation.StateContext.state; -var url: string = Navigation.StateContext.url; -var page: number = Navigation.StateContext.data.page; - -// Navigation Data -Navigation.StateController.refresh({ page: 2 }); -var data = Navigation.StateContext.includeCurrentData({ sort: 'name' }, ['page']); -Navigation.StateController.refresh(data); -Navigation.StateContext.clear('sort'); -var data = Navigation.StateContext.includeCurrentData({ pageSize: 10 }); -Navigation.StateController.refresh(data); -Navigation.StateContext.clear(); -Navigation.StateController.refresh(); +module NavigationTests { + // History Manager + class LogHistoryManager extends Navigation.HashHistoryManager { + addHistory(state: Navigation.State, url: string) { + console.log('add history'); + super.addHistory(state, url); + } + } + + // Crumb Trail Persister + class LogCrumbTrailPersister extends Navigation.CrumbTrailPersister { + load(crumbTrail: string): string { + console.log('load'); + return crumbTrail; + } + + save(crumbTrail: string): string { + console.log('save'); + return crumbTrail; + } + } + + // State Router + class LogStateRouter extends Navigation.StateRouter { + getData(route: string): { state: Navigation.State; data: any } { + console.log('get data'); + return super.getData(route); + } + } + + // Settings + Navigation.settings.router = new LogStateRouter(); + Navigation.settings.historyManager = new LogHistoryManager(); + Navigation.settings.crumbTrailPersister = new LogCrumbTrailPersister(); + Navigation.settings.stateIdKey = 'state'; + + // Configuration + Navigation.StateInfoConfig.build([ + { key: 'home', initial: 'page', states: [ + { key: 'page', route: '' } + ]}, + { key: 'person', initial: 'list', states: [ + { key: 'list', route: ['people/{page}', 'people/{page}/sort/{sort}'], transitions: [ + { key: 'select', to: 'details' } + ], defaults: { page: 1 }, trackCrumbTrail: false }, + { key: 'details', route: 'person/{id}', trackTypes: false, defaultTypes: { id: 'number' } } + ]} + ]); + + // StateInfo + var dialogs = Navigation.StateInfoConfig.dialogs; + var home = dialogs['home']; + var homePage = home.states['page']; + var homeKey = home.key; + var homePageKey = homePage.key; + homePage = home.initial; + var person = dialogs['person']; + var personList = person.states['list']; + var personDetails = person.states['details']; + var personListSelect = personList.transitions['select']; + personList = personListSelect.parent; + personDetails = personListSelect.to; + var pageDefault = personList.defaults.page; + var idDefaultType = personDetails.defaultTypes.id; + + // StateNavigator + personList.dispose = () => {}; + personList.navigating = (data, url, navigate) => { + navigate([]); + }; + personList.navigated = (data, asyncData) => {}; + personDetails.navigating = (data, url, navigate) => { + navigate(); + }; + personDetails.navigated = (data) => {}; + + // State Handler + class LogStateHandler extends Navigation.StateHandler { + getNavigationData(state: Navigation.State, url: string): any { + console.log('get navigation data'); + super.getNavigationData(state, url); + } + } + homePage.stateHandler = new LogStateHandler(); + personList.stateHandler = new LogStateHandler(); + personDetails.stateHandler = new LogStateHandler(); + + // Navigation Event + var navigationListener = + (oldState: Navigation.State, state: Navigation.State, data: any) => { + Navigation.StateController.offNavigate(navigationListener); + }; + Navigation.StateController.onNavigate(navigationListener); + + // Navigation + Navigation.start('home'); + Navigation.StateController.navigate('person'); + Navigation.StateController.refresh(); + Navigation.StateController.refresh({ page: 2 }); + Navigation.StateController.navigate('select', { id: 10 }); + var canGoBack: boolean = Navigation.StateController.canNavigateBack(1); + Navigation.StateController.navigateBack(1); + + // Navigation Link + var link = Navigation.StateController.getNavigationLink('person'); + link = Navigation.StateController.getRefreshLink(); + link = Navigation.StateController.getRefreshLink({ page: 2 }); + link = Navigation.StateController.getNavigationLink('select', { id: 10 }); + var nextDialog = Navigation.StateController.getNextState('select').parent; + person = nextDialog; + Navigation.StateController.navigateLink(link); + link = Navigation.StateController.getNavigationBackLink(1); + var crumb = Navigation.StateController.crumbs[0]; + link = crumb.navigationLink; + Navigation.StateController.navigateLink(link, true); + + // StateContext + Navigation.StateController.navigate('home'); + Navigation.StateController.navigate('person'); + home = Navigation.StateContext.previousDialog; + homePage = Navigation.StateContext.previousState; + person === Navigation.StateContext.dialog; + personList === Navigation.StateContext.state; + var url: string = Navigation.StateContext.url; + var page: number = Navigation.StateContext.data.page; + + // Navigation Data + Navigation.StateController.refresh({ page: 2 }); + var data = Navigation.StateContext.includeCurrentData({ sort: 'name' }, ['page']); + Navigation.StateController.refresh(data); + Navigation.StateContext.clear('sort'); + var data = Navigation.StateContext.includeCurrentData({ pageSize: 10 }); + Navigation.StateController.refresh(data); + Navigation.StateContext.clear(); + Navigation.StateController.refresh(); +} \ No newline at end of file diff --git a/navigation/navigation.d.ts b/navigation/navigation.d.ts index 7cb830897..59af79ca2 100644 --- a/navigation/navigation.d.ts +++ b/navigation/navigation.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Navigation 1.0 +// Type definitions for Navigation 1.1.0 // Project: http://grahammendick.github.io/navigation/ // Definitions by: Graham Mendick // Definitions: https://github.com/borisyankov/DefinitelyTyped @@ -61,15 +61,20 @@ declare module Navigation { */ title?: string; /** - * Gets the route Url pattern + * Gets the route Url patterns */ - route: string; + route: string | string[]; /** * Gets a value that indicates whether to maintain crumb trail * information e.g PreviousState. This can be used together with Route * to produce user friendly Urls */ trackCrumbTrail?: boolean; + /** + * Gets a value that indicates whether NavigationData Types are + * preserved when navigating + */ + trackTypes?: boolean; } /** @@ -175,20 +180,35 @@ declare module Navigation { */ title: string; /** - * Gets the route Url pattern + * Gets the route Url patterns */ - route: string; + route: string | string[]; /** * Gets a value that indicates whether to maintain crumb trail * information e.g PreviousState. This can be used together with Route * to produce user friendly Urls */ trackCrumbTrail: boolean; + /** + * Gets a value that indicates whether NavigationData Types are + * preserved when navigating + */ + trackTypes: boolean; /** * Gets or sets the IStateHandler responsible for building and parsing - * avigation links to this State + * navigation links to this State */ stateHandler: IStateHandler; + /** + * Called on the old State (this is not the same as the previous + * State) before navigating to a different State + * @param state The new State + * @param data The new NavigationData + * @param url The new target location + * @param unload The function to call to continue to navigate + * @param history A value indicating whether browser history was used + */ + unloading: (state: State, data: any, url: string, unload: () => void, history?: boolean) => void; /** * Called on the old State (this is not the same as the previous * State) after navigating to a different State @@ -197,15 +217,17 @@ declare module Navigation { /** * Called on the current State after navigating to it * @param data The current NavigationData + * @param asyncData The data passed asynchronously while navigating */ - navigated: (data: any) => void; + navigated: (data: any, asyncData?: any) => void; /** * Called on the new State before navigating to it * @param data The new NavigationData * @param url The new target location - * @param navigate The function to call to continue to navigate + * @param navigate The function to call to continue to navigate + * @param history A value indicating whether browser history was used */ - navigating: (data: any, url: string, navigate: () => void) => void; + navigating: (data: any, url: string, navigate: (asyncData?: any) => void, history?: boolean) => void; } /** @@ -366,6 +388,84 @@ declare module Navigation { */ getUrl(anchor: HTMLAnchorElement): string; } + + /** + * Provides the base functionality for crumb trail persistence mechanisms + */ + class CrumbTrailPersister { + /** + * Overridden by derived classes to return the persisted crumb trail + * @param crumbTrail The key, returned from the save function, to + * identify the persisted crumb trail + * @returns The crumb trail holding navigation and data information + */ + load(crumbTrail: string): string; + /** + * Overridden by derived classes to persist the crumb trail + * @param crumbTrail The crumb trail holding navigation and data + * information + * @returns The key to be passed to load function for crumb trail + * retrieval + */ + save(crumbTrail: string): string; + } + + /** + * Persists crumb trails, over a specified length, in localStorage. + * Prevents the creation of unmanageably long Urls. If used in a browser + * without localStorage or outside of a browser environment, then in memory + * storage is used + */ + class StorageCrumbTrailPersister extends CrumbTrailPersister { + /** + * Initializes a new instance of the StorageCrumbTrailPersister class + * with a maxLength of 500, historySize of 100 and localStorage as the + * storage mechanism + */ + constructor(); + /** + * Initializes a new instance of the StorageCrumbTrailPersister class + * with a historySize of 100 and localStorage as the storage mechanism + * @param maxLength The length above which any crumb trail will be + * stored in localStorage + */ + constructor(maxLength: number); + /** + * Initializes a new instance of the StorageCrumbTrailPersister class + * with localStorage as the storage mechanism + * @param maxLength The length above which any crumb trail will be + * stored in localStorage + * @param historySize The maximum number of crumb trails that will be + * held at any one time in localStorage + */ + constructor(maxLength: number, historySize: number); + /** + * Initializes a new instance of the StorageCrumbTrailPersister class + * @param maxLength The length above which any crumb trail will be + * stored in the storage + * @param historySize The maximum number of crumb trails that will be + * held at any one time in the storage + * @param storage The storage mechanism + */ + constructor(maxLength: number, historySize: number, storage: Storage); + /** + * Uses the crumbTrail parameter to determine whether to retrieve the + * crumb trail from storage. If retrieved from storage it may be null + * @param Key generated by the save function + * @returns Either the crumbTrail or the one retrieved value from + * storage; can be null if retrieved from storage + */ + load(crumbTrail: string): string; + /** + * If the crumbTrail is not over the maxLength it is returned. + * Otherwise the crumbTrail is stored in storage using a short key, + * unique within a given storage session. Also expunges old items from + * storage, if the historySize is breached when a new item is added + * @param crumbTrail The crumb trail to persist + * @returns crumbTrail or short, generated key pointing at crumbTrail + */ + save(crumbTrail: string): string; + } /** * Defines a contract a class must implement in order to build and parse @@ -434,6 +534,14 @@ declare module Navigation { navigationLink: string; /** * Initializes a new instance of the Crumb class + * @param data The Context Data held at the time of navigating away + * from this State + * @param state The configuration information associated with this + * navigation + * @param link The hyperlink navigation to return to the State and pass + * the associated Data + * @param last A value indicating whether the Crumb is the last in the + * crumb trail */ constructor(data: any, state: State, link: string, last: boolean); } @@ -442,8 +550,18 @@ declare module Navigation { * Provides access to the Navigation Settings configuration */ class NavigationSettings { + /** + * Gets or sets the builder and parser of State routes + */ router: IRouter; + /** + * Gets or sets the manager of the browser Url + */ historyManager: IHistoryManager; + /** + * Gets or sets the crumb trail persistence mechanism + */ + crumbTrailPersister: CrumbTrailPersister; /** * Gets or sets the key that identifies the StateId */ @@ -464,6 +582,11 @@ declare module Navigation { * Gets or sets the application path */ applicationPath: string; + /** + * Gets or sets a value indicating whether the PreviousStateId and + * ReturnData should be part of the CrumbTrail + */ + combineCrumbTrail: boolean; } /** @@ -650,6 +773,12 @@ declare module Navigation { * @param url The target location */ static navigateLink(url: string): void; + /** + * Navigates to the url + * @param url The target location + * @param history A value indicating whether browser history was used + */ + static navigateLink(url: string, history: boolean): void; /** * Gets the next State. Depending on the action will either return the * 'to' State of a Transition or the 'initial' State of a Dialog @@ -831,6 +960,11 @@ declare module Navigation { * @returns The matched route and data */ match(path: string): { route: Route; data: any; }; + /** + * Sorts the routes by the comparer + * @param compare The route comparer function + */ + sort(compare: (routeA: Route, routeB: Route) => number): void; } /** From 0a183cdfaf4ad480164696cd3d47e32650be8016 Mon Sep 17 00:00:00 2001 From: Ian Riley Date: Sun, 19 Jul 2015 13:22:22 -0700 Subject: [PATCH 06/17] Adds 'default' property to SchedulerStatic interface. **default** is an alias for the, now legacy, **timeout** property on Scheduler. --- rx/rx-lite.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/rx/rx-lite.d.ts b/rx/rx-lite.d.ts index 3ea8c6ed8..84f991449 100644 --- a/rx/rx-lite.d.ts +++ b/rx/rx-lite.d.ts @@ -150,6 +150,7 @@ declare module Rx { immediate: IScheduler; currentThread: ICurrentThreadScheduler; + default: IScheduler; // alias for Scheduler.timeout timeout: IScheduler; } From 1b5177dc28ba7ffe73ac9519f806870c21919995 Mon Sep 17 00:00:00 2001 From: Ilya Mochalov Date: Mon, 20 Jul 2015 02:01:19 +0500 Subject: [PATCH 07/17] lodash: changed _.values() method --- lodash/lodash-tests.ts | 12 +++++++++++- lodash/lodash.d.ts | 13 ++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lodash/lodash-tests.ts b/lodash/lodash-tests.ts index 985ef1efc..9b4548502 100644 --- a/lodash/lodash-tests.ts +++ b/lodash/lodash-tests.ts @@ -1092,7 +1092,17 @@ result = <{ a: number; b: number; c: number; }>_.transform(<{ [index: string]: n r[key] = num * 3; }); -result = _.values({ 'one': 1, 'two': 2, 'three': 3 }); +// _.values +class TestValues { + public a = 1; + public b = 2; + public c: string; +} +TestValues.prototype.c = 'a'; +result = _.values(new TestValues()); +// → [1, 2] (iteration order is not guaranteed) +result = _(new TestValues()).values().value(); +// → [1, 2] (iteration order is not guaranteed) // _.valueIn class TestValueIn { diff --git a/lodash/lodash.d.ts b/lodash/lodash.d.ts index 31625a16b..f02a4aa97 100644 --- a/lodash/lodash.d.ts +++ b/lodash/lodash.d.ts @@ -6301,11 +6301,18 @@ declare module _ { //_.values interface LoDashStatic { /** - * Creates an array composed of the own enumerable property values of object. - * @param object The object to inspect. + * Creates an array of the own enumerable property values of object. + * @param object The object to query. * @return Returns an array of property values. **/ - values(object?: any): any[]; + values(object?: any): T[]; + } + + interface LoDashObjectWrapper { + /** + * @see _.values + **/ + values(): LoDashObjectWrapper; } //_.valuesIn From c5063ebc9c3795b9a129b6f2e942f7c820ad50c4 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Sun, 19 Jul 2015 19:07:08 -0700 Subject: [PATCH 08/17] update for Maker.js 0.2.3 --- maker.js/makerjs-tests.ts | 3 ++- maker.js/makerjs.d.ts | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/maker.js/makerjs-tests.ts b/maker.js/makerjs-tests.ts index 33869213d..f42307f2c 100644 --- a/maker.js/makerjs-tests.ts +++ b/maker.js/makerjs-tests.ts @@ -75,7 +75,8 @@ function test() { ]; } - function testPath() { + function testPath() { + makerjs.path.breakAtPoint(paths.arc, [0,0]).type; makerjs.path.intersection(paths.circle, paths.arc).intersectionPoints; makerjs.path.mirror(paths.arc, true, true); makerjs.path.moveRelative(paths.circle, [0,0]); diff --git a/maker.js/makerjs.d.ts b/maker.js/makerjs.d.ts index acea3405b..4afdb455d 100644 --- a/maker.js/makerjs.d.ts +++ b/maker.js/makerjs.d.ts @@ -2,6 +2,7 @@ // Project: https://github.com/Microsoft/maker.js // Definitions by: Dan Marshall // Definitions: https://github.com/borisyankov/DefinitelyTyped + /** * Root module for Maker.js. * @@ -94,10 +95,6 @@ declare module MakerJs { * The main point of reference for this path. */ origin: IPoint; - /** - * Optional CSS style properties to be emitted into SVG. Useful for creating guidelines and debugging your model. - */ - cssStyle?: string; } /** * Test to see if an object implements the required properties of a path. @@ -425,6 +422,17 @@ declare module MakerJs.path { */ function scale(pathToScale: IPath, scaleValue: number): IPath; } +declare module MakerJs.path { + /** + * Breaks a path in two. The supplied path will end at the supplied pointOfBreak, + * a new path is returned which begins at the pointOfBreak and ends at the supplied path's initial end point. + * For Circle, the original path will be converted in place to an Arc, and null is returned. + * + * @param pathToBreak The path to break. + * @param pointOfBreak The point at which to break the path. + */ + function breakAtPoint(pathToBreak: IPath, pointOfBreak: IPoint): IPath; +} declare module MakerJs.paths { /** * Class for arc path. From 2ae5d73bec90ca4fad2fc2d2de2903ad074735e6 Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Sun, 19 Jul 2015 20:09:36 -0700 Subject: [PATCH 09/17] added @returns in jsdoc --- maker.js/makerjs.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maker.js/makerjs.d.ts b/maker.js/makerjs.d.ts index 4afdb455d..8e3eaf189 100644 --- a/maker.js/makerjs.d.ts +++ b/maker.js/makerjs.d.ts @@ -2,7 +2,6 @@ // Project: https://github.com/Microsoft/maker.js // Definitions by: Dan Marshall // Definitions: https://github.com/borisyankov/DefinitelyTyped - /** * Root module for Maker.js. * @@ -430,6 +429,7 @@ declare module MakerJs.path { * * @param pathToBreak The path to break. * @param pointOfBreak The point at which to break the path. + * @returns A new path of the same type, when path type is line or arc. Returns null for circle. */ function breakAtPoint(pathToBreak: IPath, pointOfBreak: IPoint): IPath; } @@ -669,7 +669,7 @@ declare module MakerJs.path { * * @param path1 First path to find intersection. * @param path2 Second path to find intersection. - * @result IPathIntersection object, with points(s) of intersection (and angles, when a path is an arc or circle); or null if the paths did not intersect. + * @returns IPathIntersection object, with points(s) of intersection (and angles, when a path is an arc or circle); or null if the paths did not intersect. */ function intersection(path1: IPath, path2: IPath): IPathIntersection; } From 754e75c033f5d9b6c928235af2850204eeb1f1bb Mon Sep 17 00:00:00 2001 From: matsievskyav Date: Mon, 20 Jul 2015 07:21:57 +0300 Subject: [PATCH 10/17] baconjs [http://baconjs.github.io/] definition --- baconjs/baconjs-tests.ts | 386 ++++++ baconjs/baconjs.d.ts | 2746 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 3132 insertions(+) create mode 100644 baconjs/baconjs-tests.ts create mode 100644 baconjs/baconjs.d.ts diff --git a/baconjs/baconjs-tests.ts b/baconjs/baconjs-tests.ts new file mode 100644 index 000000000..4b3e8869a --- /dev/null +++ b/baconjs/baconjs-tests.ts @@ -0,0 +1,386 @@ +/// + +function CreatingStreams() { + $("#my-div").asEventStream("click"); + $("#my-div").asEventStream("click", ".more-specific-selector"); + $("#my-div").asEventStream("click", (event, args) => args[0]); + $("#my-div").asEventStream("click", ".more-specific-selector", (event, args) => args[0]); + + Bacon.fromPromise($.ajax("https://baconjs.github.io/")); + Bacon.fromPromise(Promise.resolve(1)); + + Bacon.fromPromise($.ajax("https://baconjs.github.io/"), true); + Bacon.fromPromise(Promise.resolve(1), false); + + Bacon.fromPromise($.ajax("https://baconjs.github.io/"), true, (n:string) => { + return [new Bacon.Next(n), new Bacon.Next(() => n), new Bacon.End()]; + }); + Bacon.fromPromise(Promise.resolve(1), false, n => { + return [new Bacon.Next(n), new Bacon.Next(() => n), new Bacon.End()]; + }); + + Bacon.fromEvent(document.body, "click").onValue(() => { + alert("Bacon!"); + }); + Bacon.fromEvent(document.body, "click", (event:MouseEvent) => event.clientX).onValue(clientX => { + alert("Bacon!"); + }); + Bacon.fromEvent(process.stdin, "readable", () => { + alert("Bacon!"); + }); + + // This would create a stream that outputs a single value "Bacon!" and ends after that. The use of setTimeout causes the value to be delayed by 1 second. + Bacon.fromCallback(callback => { + setTimeout(() => { + callback("Bacon!"); + }, 1000); + }); + + // You can also give any number of arguments to `fromCallback`, which will be passed to the function. These arguments can be simple variables, Bacon EventStreams or Properties. For example the following will output "Bacon rules": + Bacon.fromCallback((a, b, callback) => { + callback(a + " " + b); + }, Bacon.constant("bacon"), "rules").log(); + + { + let fs = require("fs"), + read = Bacon.fromNodeCallback(fs.readFile, "input.txt"); + read.onError(error => { + console.log("Reading failed: " + error); + }); + read.onValue(value => { + console.log("Read contents: " + value); + }); + } + + Bacon.once(new Bacon.Error("fail")); + + // The following would lead to `1,2,3,1,2,3...` to be repeated indefinitely: + Bacon.fromArray([1, new Bacon.Error("")]); + + Bacon.repeatedly(10, [1, 2, 3]); + + // The following will produce values `0,1,2`. + Bacon.repeat(i => { + if (i < 3) { + return Bacon.once(i); + } else { + return false; + } + }).log(); + + { + let stream = Bacon.fromBinder(sink => { + sink("first value"); + sink([new Bacon.Next("2nd"), new Bacon.Next("3rd")]); + sink(new Bacon.Next(() => { + return "This one will be evaluated lazily" + })); + sink(new Bacon.Error("oops, an error")); + sink(new Bacon.End()); + return () => { + // unsub functionality here, this one's a no-op + }; + }); + stream.log(); + } + + new Bacon.Next("value"); + new Bacon.Next(() => "value"); +} + +function CommonMethodsInEventStreamsAndProperties() { + // Converting strings to integers, skipping empty values: + Bacon.once("").flatMap(text => { + return text != "" ? parseInt(text) : Bacon.never(); + }); + + Bacon.sequentially(1, [1, 2, 3]).scan(0, (a, b) => a + b); + + Bacon.sequentially(1, [1, 2, 3]).diff(0, (a, b) => Math.abs(b - a)); + + // If you have a EventStream `s` with a value sequence `1,2,3,4,5`, the respective values in `s.slidingWindow(2)` would be `[],[1],[1,2],[2,3],[3,4],[4,5]`: + Bacon.fromArray([1, 2, 3, 4, 5]).slidingWindow(2); + // The values of `s.slidingWindow(2,2)`would be `[1,2],[2,3],[3,4],[4,5]`: + Bacon.fromArray([1, 2, 3, 4, 5]).slidingWindow(2, 2); + + { + let x = Bacon.fromArray([1, 2]), y = Bacon.fromArray([3, 4]); + x.zip(y, (x, y) => x + y); + } + + { + let stream = Bacon.fromArray([1, 2]); + stream.log("New event in myStream"); + stream.log(); + } + + Bacon.fromArray([1, 2, 3]).withStateMachine(0, (sum, event) => { + if (event.hasValue()) { + // had to cast to `number` because event:Bacon.Next|Bacon.Error<{}> + return [sum + event.value(), []]; + } + else if (event.isEnd()) { + return [undefined, [new Bacon.Next(sum), event]]; + } + else { + return [sum, [event]]; + } + }); + + { + let property = Bacon.fromArray([1, 2, 3]).toProperty(), + who = Bacon.fromArray(["A", "B", "C"]).toProperty(); + property.decode({1: "mike", 2: who}); + + property.decode({1: {type: "mike"}, 2: {type: "other", whoThen: who}}); + } + + { + // This is handy for keeping track whether we are currently awaiting an AJAX response: + let ajaxRequest = >{}, + ajaxResponse = >{}, + showAjaxIndicator = ajaxRequest.awaiting(ajaxResponse); + } + + Bacon.fromArray([1, 2, -3, 3]).withHandler(function (event) { + if (event.hasValue() && event.value() < 0) { + this.push(new Bacon.Error("Value below zero")); + return this.push(new Bacon.End()); + } else { + return this.push(event); + } + }); + + { + let src = Bacon.once(1), + obs = src.map(x => -x); + console.log(obs.toString()); // > "Bacon.once(1).map(function)" + + obs.withDescription(src, "times", -1); + console.log(obs.toString()); // > "Bacon.once(1).times(-1)" + } + + { + // Calculator for grouped consecutive values until group is cancelled: + let events = [ + {id: 1, type: "add", val: 3}, + {id: 2, type: "add", val: -1}, + {id: 1, type: "add", val: 2}, + {id: 2, type: "cancel"}, + {id: 3, type: "add", val: 2}, + {id: 3, type: "cancel"}, + {id: 1, type: "add", val: 1}, + {id: 1, type: "add", val: 2}, + {id: 1, type: "cancel"} + ], + keyF = (event:{id:number}) => event.id, + limitF = (groupedStream:Bacon.EventStream) => { + let cancel = groupedStream.filter(x => x.type === "cancel").take(1), + adds = groupedStream.filter(x => x.type === "add"); + return adds.takeUntil(cancel).map(x => x.val); + }; + + Bacon.sequentially(2, events) + .groupBy(keyF, limitF) + .flatMap(groupedStream => groupedStream.fold(0, (acc, x) => acc + x)) + .onValue(sum => { + console.log(sum); // returns [-1, 2, 8] in an order + }); + } +} + +function EventStream() { + // This creates the stream which doesn't produce any events and never ends: + Bacon.interval(1e1, 0).last(); + + Bacon.fromArray([1, 2, 2, 1]) + .skipDuplicates().log(); // > returns [1, 2, 1] in an order + + // You might get two events containing [1,2,3,4] and [5,6,7] respectively, given that the flush occurs between numbers 4 and 5: + Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]).bufferWithTime(0); + + // Here's an equivalent to `stream.bufferWithTime(10)`: + { + let stream = Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]); + stream.bufferWithTime(f => { + setTimeout(f, 10); + }); + } + + // You will get output events with values `[1, 2]`, `[3, 4]` and `[5]`. + Bacon.fromArray([1, 2, 3, 4, 5]).bufferWithCount(2); +} + +function Property() { + // This creates the property which doesn't produce any events and never ends: + Bacon.interval(1e1, 0).toProperty().last(); + + { + let property = Bacon.fromArray([1, 2, 3, 4, 5]).toProperty(); + // If you want to assign your Property to the "disabled" attribute of a JQuery object, you can do this: + property.assign($("#my-button"), "attr", "disabled"); + + // A simpler example would be to toggle the visibility of an element based on a Property: + property.assign($("#my-button"), "toggle"); + } + + Bacon.fromArray([1, 2, 2, 1]).toProperty() + .skipDuplicates().log(); // > returns [1, 2, 1] in an order +} + +function CombiningMultipleStreamsAndProperties() { + { + let property = Bacon.constant(1), + stream = Bacon.once(2), + constant = 3; + Bacon.combineAsArray(property, stream, constant) + .log(); // > returns [1, 2, 3] + } + + { + // To calculate the current sum of three numeric Properties, you can do: + let property = Bacon.constant(1), + stream = Bacon.once(2), + constant = 3; + // NOTE: had to explicitly specify the typing for `x:number, y:number, z:number` + Bacon.combineWith((x:number, y:number, z:number) => x + y + z, property, stream, constant); + } + + { + // Assuming you've got streams or properties named `password`, `username`, `firstname` and `lastname`, you can do: + let password = Bacon.constant("easy"), + username = Bacon.constant("juha"), + firstname = Bacon.constant("juha"), + lastname = Bacon.constant("paananen"), + // NOTE: you should provide `combineTemplate` typing explicitly! + loginInfo = Bacon.combineTemplate({ + magicNumber: 3, + userid: username, + passwd: password, + name: {first: firstname, last: lastname} + }).onValue(loginInfo => { + // and your new `loginInfo` property will combine values from all these streams using that template, whenever any of the streams/properties get a new value. It would yield a value: + console.log("`loginInfo` expected", { + magicNumber: 3, + userid: "juha", + passwd: "easy", + name: {first: "juha", last: "paananen"} + }); + console.log("`loginInfo` actual", loginInfo); + }); + + // Note that all Bacon.combine* methods produce a `Property` instead of an `EventStream`. If you need the result as an `EventStream` you might want to use `property.changes()`: + Bacon.combineWith((firstname, lastname) => `${firstname} ${lastname}`, firstname, lastname).changes(); + } + + { + let x = Bacon.fromArray([1, 2, 3]), + y = Bacon.fromArray([10, 20, 30]), + z = Bacon.fromArray([100, 200, 300]); + Bacon.zipAsArray(x, y, z) + .log(); // > returns values `[1, 10, 100]`, `[2, 20, 200]` and `[3, 30, 300]` + } + + // The following example would log the number 3. + // NOTE: had to explicitly specify the typing for `a:number, b:number` + Bacon.onValues(Bacon.constant(1), Bacon.constant(2), (a:number, b:number) => { + console.log(a + b); + }); +} + +function $Event() { + new Bacon.Next("value"); + new Bacon.Next(() => "value"); +} + +function Errors() { + // In case you want to convert (some) value events into Error events, you may use `flatMap` like this: + // NOTE: had to explicitly specify the typing for `flatMap` + Bacon.fromArray([1, 2, 3, 4]).flatMap(x => { + return x > 2 ? new Bacon.Error("too big") : x; + }); + + // Conversely, if you want to convert some Error events into value events, you may use `flatMapError`: + Bacon.fromArray([1, 2, 3, 4]).flatMapError(error => { + let isNonCriticalError = (error:string) => Math.random() < .5, + handleNonCriticalError = (error:string) => 42; + return isNonCriticalError(error) ? handleNonCriticalError(error) : new Bacon.Error(error); + }); + + // Note also that Bacon.js combinators do not catch errors that are thrown. Especially `map` doesn't do so. If you want to map things and wrap caught errors into Error events, you can do the following: + Bacon.fromArray([1, 2, 3, 4]).flatMap(x => { + let dangerousFunction = (x:number) => { + throw new Error("dangerous function!"); + }; + try { + return dangerousFunction(x); + } catch (e) { + return new Bacon.Error(e); + } + }); + + Bacon.once("https://baconjs.github.io/").flatMap(url => { + // `ajaxCall` gives `Error`s on network or server `Error`s. + let ajaxCall = (url:string) => { + return Bacon.fromPromise($.ajax(url)); + }; + return Bacon.retry({ + source: () => ajaxCall(url), + retries: 5, + isRetryable: error => error.status !== 404, + delay: context => 100 // Just use the same delay always + }); + }); +} + +function JoinPatterns() { + { + // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: + let tick = Bacon.interval(1e2, 0), + keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), + handleTick = (_:number) => `timestamp: NONE`, + handleKeyEvent = (timestamp:number) => `timestamp: ${timestamp}`; + Bacon.when( + [tick, keyEvent], (_:number, timestamp:number) => handleKeyEvent(timestamp), + [tick], handleTick + ); + // Order is important here. If the [tick] patterns had been written first, this would have been tried first, and preferred at each tick. + } + + { + // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: + let a = Bacon.once("a"), + b = Bacon.once("b"), + c = Bacon.once("c"), + f = (a:string, b:string, c:string) => `a = ${a}; b = ${b}; c = ${c}.`; + Bacon.zipWith(f, a, b, c); + Bacon.when([a, b, c], f); + } + { + // The inputs to `Bacon.update` are defined like this: + let initial = 0, + x = Bacon.interval(1e3, 1), + y = Bacon.interval(2e3, 1), + z = Bacon.interval(1.5e3, 1); + // NOTE: had to explicitly specify the typing for `previous:number` + Bacon.update(initial, + [x, y, z], (previous:number, x:number, y:number, z:number) => previous + x + y + z, + [x, y], (previous:number, x:number, y:number) => previous + x + y + ); + // As input, each function above will get the previous value of the `result` Property, along with values from the listed Observables. The value returned by the function will be used as the next value of `result`. Just like in `Bacon.when`, only EventStreams will trigger an update, while Properties will be just sampled. So, if you list a single EventStream and several Properties, the value will be updated only when an event occurs in the EventStream. + } + { + // Here's a simple gaming example: + let scoreMultiplier = Bacon.constant(1), + hitUfo = new Bacon.Bus(), + hitMotherShip = new Bacon.Bus(), + score = Bacon.update(0, + [hitUfo, scoreMultiplier], (score:number, _:number, multiplier:number) => score + 100 * multiplier, + [hitMotherShip], (score:number, _:number) => score + 2000 + ); + // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. + } +} \ No newline at end of file diff --git a/baconjs/baconjs.d.ts b/baconjs/baconjs.d.ts new file mode 100644 index 000000000..49430f0bd --- /dev/null +++ b/baconjs/baconjs.d.ts @@ -0,0 +1,2746 @@ +// Type definitions for Bacon.js 0.7.0 +// Project: https://baconjs.github.io/ +// Definitions by: Alexander Matsievsky +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// +/// +/// + +interface JQuery { + /** + * @method + * @description Creates an [EventStream]{@link Bacon.EventStream} from events on a jQuery or Zepto.js object. + * @param {string} eventName + * @returns {EventStream} + * @example + * $("#my-div").asEventStream("click"); + */ + asEventStream(eventName:string):Bacon.EventStream; + + /** + * @method + * @description Creates an [EventStream]{@link Bacon.EventStream} from events on a jQuery or Zepto.js object. You can pass an argument to add a jQuery live `selector`. + * @param {string} eventName + * @param {string} selector + * @returns {EventStream} + * @example + * $("#my-div").asEventStream("click", ".more-specific-selector"); + */ + asEventStream(eventName:string, selector:string):Bacon.EventStream; + + /** + * @callback JQuery#asEventStream1~f + * @param {JQueryEventObject} event + * @param {*[]} args + * @returns {A} + */ + /** + * @method JQuery#asEventStream1 + * @description Creates an [EventStream]{@link Bacon.EventStream} from events on a jQuery or Zepto.js object. You can pass an argument to add a function `f` that processes the jQuery event and its parameters. + * @param {string} eventName + * @param {JQuery#asEventStream1~f} f + * @returns {EventStream} + * @example + * $("#my-div").asEventStream("click", (event, args) => args[0]); + */ + asEventStream(eventName:string, f:(event:JQueryEventObject, args:any[]) => A):Bacon.EventStream; + + /** + * @callback JQuery#asEventStream2~f + * @param {JQueryEventObject} event + * @param {*[]} args + * @returns {A} + */ + /** + * @method JQuery#asEventStream2 + * @description Creates an [EventStream]{@link Bacon.EventStream} from events on a jQuery or Zepto.js object. You can pass an argument to add a jQuery live `selector` and a function `f` that processes the jQuery event and its parameters. + * @param {string} eventName + * @param {string} selector + * @param {JQuery#asEventStream2~f} f + * @returns {Bacon.EventStream} + * @example + * $("#my-div").asEventStream("click", ".more-specific-selector", (event, args) => args[0]); + */ + asEventStream(eventName:string, selector:string, f:(event:JQueryEventObject, args:any[]) => A):Bacon.EventStream; +} + +/** @module Bacon */ +declare module Bacon { + /** + * @function + * @description Creates an [EventStream]{@link Bacon.EventStream} from a `promise` Promise object such as JQuery Ajax. This stream will contain a single value or an error, followed immediately by stream end. You can use the optional `abort` flag (i.e. ´Bacon.fromPromise(p, true)´ to have the `abort` method of the given promise be called when all subscribers have been removed from the created stream. + * @param {Promise|JQueryXHR} promise + * @param {boolean} [abort] + * @returns {EventStream} + * @example + * Bacon.fromPromise($.ajax("https://baconjs.github.io/")); + * Bacon.fromPromise(Promise.resolve(1)); + * Bacon.fromPromise($.ajax("https://baconjs.github.io/"), true); + * Bacon.fromPromise(Promise.resolve(1), false); + */ + function fromPromise(promise:Promise|JQueryXHR, abort?:boolean):EventStream; + + /** + * @callback Bacon.fromPromise~eventTransformer + * @param {A} value + * @returns {(Initial|Next|End|Error)[]} + */ + /** + * @function Bacon.fromPromise + * @description Creates an [EventStream]{@link Bacon.EventStream} from a `promise` Promise object such as JQuery Ajax. This stream will contain a single value or an error, followed immediately by stream end. You can use the `abort` flag (i.e. ´Bacon.fromPromise(p, true)´ to have the `abort` method of the given promise be called when all subscribers have been removed from the created stream, and also pass a function `eventTransformer` that transforms the promise value into Events. The default is to transform the value into `[new Bacon.Next(value), new Bacon.End()]`. + * @param {Promise|JQueryXHR} promise + * @param {boolean} abort + * @param {Bacon.fromPromise~eventTransformer} eventTransformer + * @returns {EventStream} + * @example + * Bacon.fromPromise($.ajax("https://baconjs.github.io/"), true, (n:string) => { + * return [new Bacon.Next(n), new Bacon.Next(() => n), new Bacon.End()]; + * }); + * Bacon.fromPromise(Promise.resolve(1), false, n => { + * return [new Bacon.Next(n), new Bacon.Next(() => n), new Bacon.End()]; + * }); + */ + function fromPromise(promise:Promise|JQueryXHR, abort:boolean, eventTransformer:(value:A) => (Initial|Next|End|Error)[]):EventStream; + + /** + * @function + * @description Creates an [EventStream]{@link Bacon.EventStream} from events on a DOM EventTarget or Node.JS EventEmitter object, or an object that supports event listeners using `on`/`off` methods. + * @param {EventTarget|NodeJS.EventEmitter} target + * @param {string} eventName + * @returns {EventStream} + * @example + * Bacon.fromEvent(document.body, "click").onValue(() => { + * alert("Bacon!"); + * }); + * Bacon.fromEvent(process.stdin, "readable", () => { + * alert("Bacon!"); + * }); + */ + function fromEvent(target:EventTarget|NodeJS.EventEmitter, eventName:string):EventStream; + + /** + * @callback Bacon.fromEvent~eventTransformer + * @param {A} event + * @returns {B} + */ + /** + * @function Bacon.fromEvent + * @description Creates an [EventStream]{@link Bacon.EventStream} from events on a DOM EventTarget or Node.JS EventEmitter object, or an object that supports event listeners using `on`/`off` methods. You can pass a function `eventTransformer` that transforms the emitted events' parameters. + * @param {EventTarget|NodeJS.EventEmitter} target + * @param {string} eventName + * @param {Bacon.fromEvent~eventTransformer} eventTransformer + * @returns {EventStream} + * @example + * Bacon.fromEvent(document.body, "click", (event:MouseEvent) => event.clientX).onValue(clientX => { + * alert("Bacon!"); + * }); + */ + function fromEvent(target:EventTarget|NodeJS.EventEmitter, eventName:string, eventTransformer:(event:A) => B):EventStream; + + /** + * @callback Bacon.fromCallback1~f + * @param {Bacon.fromCallback1~callback} callback + * @returns {void} + */ + /** + * @callback Bacon.fromCallback1~callback + * @param {...*} args + * @returns {void} + */ + /** + * @function Bacon.fromCallback1 + * @description Creates an [EventStream]{@link Bacon.EventStream} from a function `f` that accepts a `callback`. The function is supposed to call its callback just once. + * @param {Bacon.fromCallback1~f} f + * @returns {EventStream} + * @example + * // This would create a stream that outputs a single value "Bacon!" and ends after that. The use of setTimeout causes the value to be delayed by 1 second. + * Bacon.fromCallback(callback => { + * setTimeout(() => { + * callback("Bacon!"); + * }, 1000); + * }); + */ + function fromCallback(f:(callback:(...args:any[]) => void) => void):EventStream; + + /** + * @callback Bacon.fromCallback2~f + * @param {...*} args + * @returns {void} + */ + /** + * @function Bacon.fromCallback2 + * @description Creates an [EventStream]{@link Bacon.EventStream} from a function `f` that accepts a `callback`. The function is supposed to call its callback just once. + * @param {Bacon.fromCallback2~f} f + * @param {...*} args + * @returns {EventStream} + * @example + * // You can also give any number of arguments to `fromCallback`, which will be passed to the function. These arguments can be simple variables, Bacon EventStreams or Properties. For example the following will output "Bacon rules": + * Bacon.fromCallback((a, b, callback) => { + * callback(a + " " + b); + * }, Bacon.constant("bacon"), "rules").log(); + */ + function fromCallback(f:(...args:any[]) => void, ...args:any[]):EventStream; + + /** + * @function + * @description Creates an [EventStream]{@link Bacon.EventStream} from a `methodName` method of a given `object`. The function is supposed to call its callback just once. + * @param {Object} object + * @param {string} methodName + * @param {...*} args + * @returns {EventStream} + */ + function fromCallback(object:Object, methodName:string, ...args:any[]):EventStream; + + /** + * @callback Bacon.fromNodeCallback~f + * @param {Bacon.fromNodeCallback~callback} callback + * @returns {void} + */ + /** + * @callback Bacon.fromNodeCallback~callback + * @param {E} error + * @param {A} data + * @returns {void} + */ + /** + * @function Bacon.fromNodeCallback + * @description Creates an [EventStream]{@link Bacon.EventStream} from a function `f` that accepts a Node.js `callback`: callback(error, data), where error is `null` if everything is fine. The function is supposed to call its callback just once. + * @param {Bacon.fromNodeCallback~f} f + * @param {...*} args + * @returns {EventStream} + * @example + * { + * let fs = require("fs"), + * read = Bacon.fromNodeCallback(fs.readFile, "input.txt"); + * read.onError(error => { + * console.log("Reading failed: " + error); + * }); + * read.onValue(value => { + * console.log("Read contents: " + value); + * }); + * } + */ + function fromNodeCallback(f:(callback:(error:E, data:A) => void) => void, ...args:any[]):EventStream; + + /** + * @function + * @description Creates an [EventStream]{@link Bacon.EventStream} from a `methodName` method of a given `object`. + * @param {Object} object + * @param {string} methodName + * @param {...*} args + * @returns {EventStream} + */ + function fromNodeCallback(object:Object, methodName:string, ...args:any[]):EventStream; + + /** + * @callback Bacon.fromPoll~f + * @returns {Next|End} + */ + /** + * @function Bacon.fromPoll + * @description Polls given function `f` with given `interval`. Function should return events: either [Next]{@link Bacon.Next} or [End]{@link Bacon.End}. Polling occurs only when there are subscribers to the stream. Polling ends permanently when `f` returns [End]{@link Bacon.End}. + * @param {number} interval + * @param {Bacon.fromPoll~f} f + * @returns {EventStream} + */ + function fromPoll(interval:number, f:() => Next|End):EventStream; + + /** + * @function Bacon.once + * @description Creates an [EventStream]{@link Bacon.EventStream} that delivers the given single `value` for the first subscriber. The stream will end immediately after this value. You can also send an [Error]{@link Bacon.Error} event instead of a `value`. + * @param {A|Error} value + * @returns {EventStream} + * @example + * Bacon.once(new Bacon.Error("fail")); + */ + function once(value:A|Error):EventStream; + + /** + * @function + * @description Creates an [EventStream]{@link Bacon.EventStream} that delivers the given series of `values` (given as array) to the first subscriber. The stream ends after these values have been delivered. You can also send [Error]{@link Bacon.Error} events, or any combination of pure values and error events. + * @param {(A|Error)[]} values + * @returns {EventStream} + * @example + * Bacon.fromArray([1, new Bacon.Error("")]); + */ + function fromArray(values:(A|Error)[]):EventStream; + + /** + * @function + * @description Repeats the single `value` indefinitely with the given `interval` (in milliseconds). + * @param {number} interval + * @param {A} value + * @returns {EventStream} + */ + function interval(interval:number, value:A):EventStream; + + /** + * @function + * @description Creates a [EventStream]{@link Bacon.EventStream} containing given `values` (given as array) with the given `interval` (in milliseconds). + * @param {number} interval + * @param {A[]} values + * @returns {EventStream} + */ + function sequentially(interval:number, values:A[]):EventStream; + + /** + * @function + * @description Repeats given `values` indefinitely with then given `interval` (in milliseconds). + * @param {number} interval + * @param {A[]} values + * @returns {EventStream} + * @example + * // The following would lead to `1,2,3,1,2,3...` to be repeated indefinitely: + * Bacon.fromArray([1, new Bacon.Error("")]); + */ + function repeatedly(interval:number, values:A[]):EventStream; + + /** + * @callback Bacon.repeat~f + * @param {number} iteration + * @returns {boolean|Observable} + */ + /** + * @function Bacon.repeat + * @description Calls generator function `f` which is expected to return an [Observable]{@link Bacon.Observable}. The returned [EventStream]{@link Bacon.EventStream} contains values and errors from the spawned observable. When the spawned Observable ends, the generator `f` is called again to spawn a new Observable. This is repeated until the generator `f` returns a falsy value (such as `undefined` or `false`). The generator `f` is called with one argument — `iteration` number starting from `0`. + * @param {Bacon.repeat~f} f + * @returns {EventStream} + * @example + * // The following will produce values `0,1,2`. + * Bacon.repeat(i => { + * if (i < 3) { + * return Bacon.once(i); + * } else { + * return false; + * } + * }).log(); + */ + function repeat(f:(iteration:number) => boolean|Observable):EventStream; + + /** + * @function Bacon.never + * @description Creates an [EventStream]{@link Bacon.EventStream} that immediately ends. + * @returns {EventStream} + */ + function never():EventStream; + + /** + * @function + * @description Creates a single-element [EventStream]{@link Bacon.EventStream} that produces given `value` after a given `delay` (in milliseconds). + * @param {number} delay + * @param {A} value + * @returns {EventStream} + */ + function later(delay:number, value:A):EventStream; + + /** + * @function + * @description Creates a constant [Property]{@link Bacon.Property} with value `x`. + * @param {A} x + * @returns {Property} + */ + function constant(x:A):Property; + + /** + * @callback Bacon.fromBinder~subscribe + * @param {Bacon.fromBinder~sink} sink + * @returns {Bacon.fromBinder~unsubscribe} + */ + /** + * @callback Bacon.fromBinder~sink + * @param {More|NoMore|(A|Initial|Next|End|Error)|(A|Initial|Next|End|Error)[]} value + * @returns {void} + */ + /** + * @callback Bacon.fromBinder~unsubscribe + * @returns {void} + */ + /** + * @function Bacon.fromBinder + * @description Creates an [EventStream]{@link Bacon.EventStream} with the given [subscribe]{@link Bacon.fromBinder~subscribe} function. The parameter `subscribe` is a function that accepts a [sink]{@link Bacon.fromBinder~sink} which is a function that your `subscribe` function can "push" events to. You can push: a plain value, like `"first value"`; an [Event]{@link Bacon.Event} object including [Error]{@link Bacon.Error} (wraps an error) and [End]{@link Bacon.End} (indicates stream end); an array of event objects at once. The `subscribe` function must return a function. Let's call that function [unsubscribe]{@link Bacon.fromBinder~unsubscribe}. The returned function can be used by the subscriber (directly or indirectly) to unsubscribe from the EventStream. It should release all resources that the `subscribe` function reserved. The `sink` function may return [noMore]{@link Bacon.noMore} (as well as [more]{@link Bacon.more} or any other value). If it returns `noMore`, no further events will be consumed by the subscriber. The `subscribe` function may choose to clean up all resources at this point (e.g., by calling `unsubscribe`). This is usually not necessary, because further calls to `sink` are ignored, but doing so can increase performance in rare cases. The EventStream will wrap your `subscribe` function so that it will only be called when the first stream listener is added, and the `unsubscribe` function is called only after the last listener has been removed. The subscribe-unsubscribe cycle may of course be repeated indefinitely, so prepare for multiple calls to the `subscribe` function. + * @param {Bacon.fromBinder~subscribe} subscribe + * @returns {EventStream} + * @example + * let stream = Bacon.fromBinder(sink => { + * sink("first value"); + * sink([new Bacon.Next("2nd"), new Bacon.Next("3rd")]); + * sink(new Bacon.Next(() => { + * return "This one will be evaluated lazily" + * })); + * sink(new Bacon.Error("oops, an error")); + * sink(new Bacon.End()); + * return () => { + * // unsub functionality here, this one's a no-op + * }; + * }); + * stream.log(); + */ + function fromBinder(subscribe:(sink:(value:More|NoMore|(A|Initial|Next|End|Error)|(A|Initial|Next|End|Error)[]) => void) => (() => void)):EventStream; + + /** + * @interface + * @see Bacon.more + */ + interface More { + } + /** + * @property more + * @constant + * @description The opaque value `sink` function may return. See [Bacon.fromBinder]{@link Bacon.fromBinder}. + */ + const more:More; + + /** + * @interface + * @see Bacon.noMore + */ + interface NoMore { + } + /** + * @property noMore + * @constant + * @description The opaque value `sink` function may return. See [Bacon.fromBinder]{@link Bacon.fromBinder}. + */ + const noMore:NoMore; + + /** + * @class Observable + * @description A superclass for [EventStream]{@link Bacon.EventStream} and [Property]{@link Bacon.Property}. + * */ + interface Observable { + /** + * @callback Observable#onValue~f + * @param {A} value + * @returns {void} + */ + /** + * @callback Observable#onValue~unsubscribe + * @returns {void} + */ + /** + * @method Observable#onValue + * @description Subscribes a given handler function `f` to the [Observable]{@link Bacon.Observable}. Function will be called for each new value. This is the simplest way to assign a side-effect to an Observable. The difference to the [EventStream.subscribe]{@link Bacon.EventStream#subscribe} and [Property.subscribe]{@link Bacon.Property#subscribe} methods is that the actual stream `value`s are received, instead of [Event]{@link Bacon.Event} objects. [EventStream.onValue]{@link Bacon.EventStream#onValue} and [Property.onValue]{@link Bacon.Property#onValue} behave similarly, except that the latter also pushes the initial value of the Property, in case there is one. + * @param {Observable#onValue~f} f + * @returns {Observable#onValue~unsubscribe} + */ + onValue(f:(value:A) => void):() => void; + + /** + * @callback Observable#onError~f + * @param {E} error + * @returns {void} + */ + /** + * @callback Observable#onError~unsubscribe + * @returns {void} + */ + /** + * @method Observable#onError + * @description Subscribes a given handler function `f` to [Error]{@link Bacon.Error} events. The function `f` will be called for each error in the [Observable]{@link Bacon.Observable}. + * @param {Observable#onError~f} f + * @returns {Observable#onError~unsubscribe} + */ + onError(f:(error:E) => void):() => void; + + /** + * @callback Observable#onEnd~f + * @returns {void} + */ + /** + * @callback Observable#onEnd~unsubscribe + * @returns {void} + */ + /** + * @method Observable#onEnd + * @description Subscribes a given handler function `f` to [End]{@link Bacon.End} event. The function `f` will be called when the [Observable]{@link Bacon.Observable} ends. Just like [EventStream.subscribe]{@link Bacon.EventStream#subscribe} and [Property.subscribe]{@link Bacon.Property#subscribe}, this method returns a function for `unsubscribe`ing. + * @param {Observable#onEnd~f} f + * @returns {Observable#onEnd~unsubscribe} + */ + onEnd(f:() => void):() => void; + + /** + * @callback Observable#toPromise~promiseCtr + * @param {A} value + * @returns {Promise} + */ + /** + * @method Observable#toPromise + * @description Returns a Promise which will be resolved with the last event coming from an [Observable]{@link Bacon.Observable}. The global ES6 promise implementation will be used unless a promise constructor `promiseCtr` is given. Use a shim if you need to support legacy browsers or platforms. + * @param {Observable#toPromise~promiseCtr} [promiseCtr] + * @returns {Promise} + */ + toPromise(promiseCtr?:(value:A) => Promise):Promise; + + /** + * @callback Observable#firstToPromise~promiseCtr + * @param {A} value + * @returns {Promise} + */ + /** + * @method Observable#firstToPromise + * @description Returns a Promise which will be resolved with the first event coming from an [Observable]{@link Bacon.Observable}. Like [Observable.toPromise]{@link Bacon.Observable#toPromise}, the global ES6 promise implementation will be used unless a promise constructor `promiseCtr` is given. + * @param {Observable#firstToPromise~promiseCtr} [promiseCtr] + * @returns {Promise} + */ + firstToPromise(promiseCtr?:(value:A) => Promise):Promise; + + /** + * @method + * @description Throttles the [Observable]{@link Bacon.Observable} using a buffer so that at most one value event in `minimumInteval` is issued. Unlike [EventStream.throttle]{@link Bacon.EventStream#throttle} and [Property.throttle]{@link Bacon.Property#throttle}, it doesn't discard the excessive events but buffers them instead, outputting them with a rate of at most one value per `minimumInterval`. + * @param {number} minimumInterval + * @returns {EventStream} + */ + bufferingThrottle(minimumInterval:number):EventStream; + + /** + * @callback Observable#flatMap~f + * @param {A} value + * @returns {B|Initial|Next|End|Error|Observable} + */ + /** + * @method Observable#flatMap + * @description For each element in the source [Observable]{@link Bacon.Observable}, spawn a new stream using the function `f`, and collect events from each of the spawned streams into the result [EventStream]{@link Bacon.EventStream}. The return value of function `f` can be either an Observable (EventStream/[Property]{@link Bacon.Property}) or a constant value. The result of [flatMap]{@link Bacon.Observable#flatMap} is always an EventStream. The "Function Construction rules" apply here. `flatMap` can be used conveniently with [Bacon.once]{@link Bacon.once} and [Bacon.never]{@link Bacon.never} for converting and filtering at the same time, including only some of the results. + * @param {Observable#flatMap~f} f + * @returns {EventStream} + * @example + * // Converting strings to integers, skipping empty values: + * Bacon.once("").flatMap(text => { + * return text != "" ? parseInt(text) : Bacon.never(); + * }); + */ + flatMap(f:(value:A) => B|Initial|Next|End|Error|Observable):EventStream; + + /** + * @callback Observable#flatMapLatest~f + * @param {A} value + * @returns {B|Initial|Next|End|Error|Observable} + */ + /** + * @method Observable#flatMapLatest + * @description For each element in the source [Observable]{@link Bacon.Observable}, spawn a new stream using the function `f`, but instead of including events from all spawned streams, only includes them from the latest spawned stream into the result [EventStream]{@link Bacon.EventStream}. The return value of function `f` can be either an Observable (EventStream/[Property]{@link Bacon.Property}) or a constant value. The result of [flatMapLatest]{@link Bacon.Observable#flatMapLatest} is always an EventStream. + * @param {Observable#flatMapLatest~f} f + * @returns {EventStream} + */ + flatMapLatest(f:(value:A) => B|Initial|Next|End|Error|Observable):EventStream; + + /** + * @callback Observable#flatMapFirst~f + * @param {A} value + * @returns {B|Initial|Next|End|Error|Observable} + */ + /** + * @method Observable#flatMapFirst + * @description For each element in the source [Observable]{@link Bacon.Observable}, spawn a new stream using the function `f` only if the previously spawned stream has ended, and collect events from each of the spawned streams into the result [EventStream]{@link Bacon.EventStream}. The return value of function `f` can be either an Observable (EventStream/[Property]{@link Bacon.Property}) or a constant value. The result of [flatMapFirst]{@link Bacon.Observable#flatMapFirst} is always an EventStream. + * @param {Observable#flatMapFirst~f} f + * @returns {EventStream} + */ + flatMapFirst(f:(value:A) => B|Initial|Next|End|Error|Observable):EventStream; + + /** + * @callback Observable#flatMapError~f + * @param {E} error + * @returns {B|Initial|Next|End|Error|Observable} + */ + /** + * @method Observable#flatMapError + * @description For each [Error]{@link Bacon.Error} event in the source [Observable]{@link Bacon.Observable}, spawn a new stream using the function `f`, and collect events from each of the spawned streams into the result [EventStream]{@link Bacon.EventStream}. The return value of function `f` can be either an Observable (EventStream/[Property]{@link Bacon.Property}) or a constant value. The result of [flatMapError]{@link Bacon.Observable#flatMapError} is always an EventStream. + * @param {Observable#flatMapError~f} f + * @returns {EventStream} + */ + flatMapError(f:(error:E) => B|Initial|Next|End|Error|Observable):EventStream; + + /** + * @callback Observable#flatMapWithConcurrencyLimit~f + * @param {A} value + * @returns {B|Initial|Next|End|Error|Observable} + */ + /** + * @method Observable#flatMapWithConcurrencyLimit + * @description For each element in the source [Observable]{@link Bacon.Observable}, spawn a new stream using the function `f`, and collect events from each of the spawned streams into the result [EventStream]{@link Bacon.EventStream}, but limit the number of open spawned streams and buffers incoming events by `limit` amount. The return value of function `f` can be either an Observable (EventStream/[Property]{@link Bacon.Property}) or a constant value. [flatMapConcat]{@link Bacon.Observable#flatMapConcat} is [flatMapWithConcurrencyLimit]{@link Bacon.Observable#flatMapWithConcurrencyLimit}(1) (only one input active), and [flatMap]{@link Bacon.Observable#flatMap} is [flatMapWithConcurrencyLimit]{@link Bacon.Observable#flatMapWithConcurrencyLimit}(∞) (all inputs are piped to output). The result of `flatMapWithConcurrencyLimit` is always an EventStream. + * @param {number} limit + * @param {Observable#flatMapWithConcurrencyLimit~f} f + * @returns {EventStream} + */ + flatMapWithConcurrencyLimit(limit:number, f:(value:A) => B|Initial|Next|End|Error|Observable):EventStream; + + /** + * @callback Observable#flatMapConcat~f + * @param {A} value + * @returns {B|Initial|Next|End|Error|Observable} + */ + /** + * @method Observable#flatMapConcat + * @description For each element in the source [Observable]{@link Bacon.Observable}, spawn a new stream using the function `f`, and collect events from each of the spawned streams into the result [EventStream]{@link Bacon.EventStream}, but limit the number of open spawned streams and buffers incoming events to 1. The return value of function `f` can be either an Observable (EventStream/[Property]{@link Bacon.Property}) or a constant value. The result of `flatMapConcat` is always an EventStream. + * @param {Observable#flatMapConcat~f} f + * @returns {EventStream} + */ + flatMapConcat(f:(value:A) => B|Initial|Next|End|Error|Observable):EventStream; + + /** + * @callback Observable#scan~f + * @param {B} acc + * @param {A} next + * @returns {B} + */ + /** + * @method Observable#scan + * @description Scans [Observable]{@link Bacon.Observable} with given `seed` value and accumulator function `f`, resulting to a [Property]{@link Bacon.Property}. For example, you might use zero as `seed` and a "plus" function as the accumulator to create an "integral" Property. When applied to a Property as in `r = p.scan(seed, f)`, there's a (hopefully insignificant) catch: the starting value for `r` depends on whether `p` has an initial value when `scan` is applied. If there's no initial value, this works identically to `[EventStream]{@link Bacon.EventStream}.scan`: the `seed` will be the initial value of `r`. However, if `r` already has a current/initial value `x`, the seed won't be output as is. Instead, the initial value of `r` will be `f(seed, x)`. This makes sense, because there can only be 1 initial value for a Property at a time. + * @param {B} seed + * @param {Observable#scan~f} f + * @returns {Property} + * @example + * Bacon.sequentially(1, [1, 2, 3]).scan(0, (a, b) => a + b); + */ + scan(seed:B, f:(acc:B, next:A) => B):Property; + + /** + * @callback Observable#fold~f + * @param {B} acc + * @param {A} next + * @returns {B} + */ + /** + * @method Observable#fold + * @description Scans [Observable]{@link Bacon.Observable} with given `seed` value and accumulator function `f`, but only emits the final value, i.e. the value just before the Observable ends. Returns a [Property]{@link Bacon.Property}. + * @param {B} seed + * @param {Observable#fold~f} f + * @returns {Property} + */ + fold(seed:B, f:(acc:B, next:A) => B):Property; + + /** + * @callback Observable#reduce~f + * @param {B} acc + * @param {A} next + * @returns {B} + */ + /** + * @method Observable#reduce + * @description Scans [Observable]{@link Bacon.Observable} with given `seed` value and accumulator function `f`, but only emits the final value, i.e. the value just before the Observable ends. Returns a [Property]{@link Bacon.Property}. + * @param {B} seed + * @param {Observable#reduce~f} f + * @returns {Property} + */ + reduce(seed:B, f:(acc:B, next:A) => B):Property; + + /** + * @callback Observable#diff~f + * @param {A} a + * @param {B} b + * @returns {B} + */ + /** + * @method Observable#diff + * @description Returns a [Property]{@link Bacon.Property} that represents the result of a comparison `f` between the previous and current value of the [Observable]{@link Bacon.Observable}. For the initial value of the Observable, the previous value will be the given `start`. + * @param {A} start + * @param {Observable#diff~f} f + * @returns {Property} + * @example + * Bacon.sequentially(1, [1, 2, 3]).diff(0, (a, b) => Math.abs(b - a)); + */ + diff(start:A, f:(a:A, b:A) => B):Property; + + /** + * @callback Observable#zip~f + * @param {A} a + * @param {B} b + * @returns {C} + */ + /** + * @method Observable#zip + * @description Returns an [EventStream]{@link Bacon.EventStream} with elements pair-wise lined up with events from this and the `other` EventStream. A zipped EventStream will publish only when it has a value from each EventStream and will only produce values up to when any single EventStream ends. The given function `f` is used to create the result value from value in the two source EventStream. If no function `f` is given, the values are zipped into an array. Be careful not to have too much "drift" between streams. If one stream produces many more values than some other excessive buffering will occur inside the zipped observable. + * @param {EventStream} other + * @param {Observable#zip~f} f + * @returns {EventStream} + * @example + * { + * let x = Bacon.fromArray([1, 2]), + * y = Bacon.fromArray([3, 4]); + * x.zip(y, (x, y) => x + y); + * } + */ + zip(other:EventStream, f:(a:A, b:B) => C):EventStream; + + /** + * @method + * @description Returns a [Property]{@link Bacon.Property} that represents a "sliding window" into the history of the values of the [Observable]{@link Bacon.Observable}. The resulting Property will have a value that is an array containing the last `n` values of the original Observable, where `n` is at most the value of the `max` argument, and at least the value of the `min` argument. If the `min` argument is omitted, there's no lower limit of values. + * @param {number} max + * @param {number} [min] + * @returns {Property} + * @example + * // If you have a EventStream `s` with a value sequence `1,2,3,4,5`, the respective values in `s.slidingWindow(2)` would be `[],[1],[1,2],[2,3],[3,4],[4,5]`: + * Bacon.fromArray([1, 2, 3, 4, 5]).slidingWindow(2); + * // The values of `s.slidingWindow(2,2)`would be `[1,2],[2,3],[3,4],[4,5]`: + * Bacon.fromArray([1, 2, 3, 4, 5]).slidingWindow(2, 2); + */ + slidingWindow(max:number, min?:number):Property; + + /** + * @callback Observable#combine~f + * @param {A} a + * @param {B} b + * @returns {C} + */ + /** + * @method Observable#combine + * @description Combines the latest values of the two [EventStream]{@link Bacon.EventStream}s or [Property]{@link Bacon.Property}s using a two-arg function `f`. The result is a Property. + * @param {Property} property2 + * @param {Observable#combine~f} f + * @returns {Property} + */ + combine(property2:Property, f:(a:A, b:B) => C):Property; + + /** + * @callback Observable#withStateMachine~f + * @param {B} state + * @param {Initial|Next|End|Error} event + * @returns {[B, (Initial|Next|End|Error)[]]} + */ + /** + * @method Observable#withStateMachine + * @description Lets you run a state machine on an [Observable]{@link Bacon.Observable}. Give it an initial state `initState` object and a state transformation function `f` that processes each incoming [Event]{@link Bacon.Event} and returns and array containing the next `state` and an array of output Event's. + * @param {B} initState + * @param {Observable#withStateMachine~f} f + * @returns {EventStream} + * @example + * // Calculate the total sum of all numbers in the stream and output the value on stream end: + * Bacon.fromArray([1, 2, 3]).withStateMachine(0, (sum, event) => { + * if (event.hasValue()) { + * had to cast to `number` because event:Bacon.Next|Bacon.Error<{}> + * return [sum + event.value(), []]; + * } else if (event.isEnd()) { + * return [undefined, [new Bacon.Next(sum), event]]; + * } else { + * return [sum, [event]]; + * } + * }); + */ + withStateMachine(initState:B, f:(state:B, event:Initial|Next|End|Error) => [B, (Initial|Next|End|Error)[]]):EventStream; + + /** + * @method + * @description Decodes input [Observable]{@link Bacon.Observable} using the given `mapping`. Is a bit like a switch-case or the decode function in Oracle SQL. The return value of `decode` is always a [Property]{@link Bacon.Property}. + * @param {Object} mapping + * @returns {Property} + * @example + * let property = Bacon.fromArray([1, 2, 3]).toProperty(), + * who = Bacon.fromArray(["A", "B", "C"]).toProperty(); + * // The following would map the value 1 into the string "mike" and the value 2 into the value of the `who` property: + * property.decode({1: "mike", 2: who}); + * + * // You can compose static and dynamic data quite freely, as in: + * property.decode({1: {type: "mike"}, 2: {type: "other", whoThen: who}}); + */ + decode(mapping:Object):Property; + + /** + * @method + * @description Creates a [Property]{@link Bacon.Property} that indicates whether Observable is awaiting `otherObservable`, i.e. has produced a value after the latest value from `otherObservable`. + * @param {Observable} otherObservable + * @returns {Property} + * @example + * // This is handy for keeping track whether we are currently awaiting an AJAX response: + * let ajaxRequest = >{}, + * ajaxResponse = >{}, + * showAjaxIndicator = ajaxRequest.awaiting(ajaxResponse); + */ + awaiting(otherObservable:Observable):Property; + } + + /** + * @class EventStream + * @augments Bacon.Observable + * @description A stream of events. + * */ + interface EventStream extends Observable { + /** + * @callback EventStream#map~f + * @param {A} value + * @returns {B} + */ + /** + * @method EventStream#map + * @description Maps [EventStream]{@link Bacon.EventStream} values using given function `f`, returning a new EventStream. The `map` method, among many others, uses lazy evaluation. + * @param {EventStream#map~f} f + * @returns {EventStream} + * */ + map(f:(value:A) => B):EventStream; + + /** + * @method + * @description Maps [EventStream]{@link Bacon.EventStream} values using given `constant` value, returning a new EventStream. The `map` method, among many others, uses lazy evaluation. + * @param {B} constant + * @returns {EventStream} + * */ + map(constant:B):EventStream; + + /** + * @method + * @description Maps [EventStream]{@link Bacon.EventStream} values using given `propertyExtractor` string like ".keyCode", returning a new EventStream. So, if `propertyExtractor` is a string starting with a dot, the elements will be mapped to the corresponding field/function in the event value. For instance map(".keyCode") will pluck the keyCode field from the input values. If `keyCode` was a function, the result EventStream would contain the values returned by the function. The "Function Construction rules" apply here. The `map` method, among many others, uses lazy evaluation. + * @param {string} propertyExtractor + * @returns {EventStream} + * */ + map(propertyExtractor:string):EventStream; + + /** + * @method + * @description Maps [EventStream]{@link Bacon.EventStream} events to the current value of the given [Property]{@link Bacon.Property} `property`. This is equivalent to [Property.sampledBy]{@link Bacon.Property#sampledBy}. + * @param {Property} property + * @returns {EventStream} + */ + map(property:Property):EventStream; + + /** + * @callback EventStream#mapError~f + * @param {E} error + * @returns {B} + */ + /** + * @method EventStream#mapError + * @description Maps [EventStream]{@link Bacon.EventStream} [Error]{@link Bacon.Error}s using given function `f`. More specifically, feeds the "error" field of the Error event to the function and produces a [Next]{@link Bacon.Next} event based on the return value. The "Function Construction rules" apply here. + * @param {EventStream#mapError~f} f + * @returns {EventStream} + */ + mapError(f:(error:E) => B):EventStream; + + /** + * @method + * @description Returns an [EventStream]{@link Bacon.EventStream} containing [Error]{@link Bacon.Error} events only. Same as filtering with a function that always returns `false`. + * @returns {EventStream} + */ + errors():EventStream; + + /** + * @method + * @description Skips all [Error]{@link Bacon.Error}s. + * @returns {EventStream} + */ + skipErrors():EventStream; + + /** + * @callback EventStream#mapEnd~f + * @returns {A} + */ + /** + * @method EventStream#mapEnd + * @description Adds an extra [Next]{@link Bacon.Next} event just before [End]{@link Bacon.End} to [EventStream]{@link Bacon.EventStream}. The value is created by calling the given function `f` when the source [EventStream]{@link Bacon.EventStream} ends. + * @param {EventStream#mapEnd~f} f + * @returns {EventStream} + */ + mapEnd(f:() => A):EventStream; + + /** + * @method + * @description Adds an extra [Next]{@link Bacon.Next} event just before [End]{@link Bacon.End} to [EventStream]{@link Bacon.EventStream}. A static `value` is used. + * @param {A} value + * @returns {EventStream} + */ + mapEnd(value:A):EventStream; + + /** + * @callback EventStream#filter~f + * @param {A} value + * @returns {boolean} + */ + /** + * @method EventStream#filter + * @description Filters [EventStream]{@link Bacon.EventStream} `value`s using a given predicate function `f`. + * @param {EventStream#filter~f} f + * @returns {EventStream} + */ + filter(f:(value:A) => boolean):EventStream; + + /** + * @method + * @description Filters [EventStream]{@link Bacon.EventStream} values using a given `constant` value (`true` to include all, `false` to exclude all). + * @param {boolean} bool + * @returns {EventStream} + */ + filter(bool:boolean):EventStream; + + /** + * @method + * @description Filters [EventStream]{@link Bacon.EventStream} values using a given `propertyExtractor` string (like ".isValuable"). + * @param {string} propertyExtractor + * @returns {EventStream} + */ + filter(propertyExtractor:string):EventStream; + + /** + * @method + * @description Filters [EventStream]{@link Bacon.EventStream} values based on the value of a [Property]{@link Bacon.Property} `property`. [Event]{@link Bacon.Event} will be included in output IF AND ONLY IF the `property` holds `true` at the time of the event. + * @param {Property} property + * @returns {EventStream} + */ + filter(property:Property):EventStream; + + /** + * @callback EventStream#takeWhile~f + * @param {A} value + * @returns {boolean} + */ + /** + * @method EventStream#takeWhile + * @description Takes [EventStream]{@link Bacon.EventStream} values while given predicate function `f` holds `true`, and then ends. + * @param {EventStream#takeWhile} f + * @returns {EventStream} + */ + takeWhile(f:(value:A) => boolean):EventStream; + + /** + * @method + * @description Takes [EventStream]{@link Bacon.EventStream} values while the value of a `property` holds `true`, and then ends. + * @param {Property} property + * @returns {EventStream} + */ + takeWhile(property:Property):EventStream; + + /** + * @method + * @description Takes at most n elements from the [EventStream]{@link Bacon.EventStream}. Equal to `Bacon.never()` if `n <= 0`. + * @param {number} n + * @returns {EventStream} + */ + take(n:number):EventStream; + + /** + * @method + * @description Takes elements from [EventStream]{@link Bacon.EventStream} until a [Next]{@link Bacon.Next} event appears in the EventStream `stream`. If `stream` ends without value, it is ignored. + * @param {EventStream} stream + * @returns {EventStream} + */ + takeUntil(stream:EventStream):EventStream; + + /** + * @method + * @description Takes the first element from the [EventStream]{@link Bacon.EventStream}. Essentially [Observable.take]{@link Bacon.EventStream#take}(1). + * @returns {EventStream} + */ + first():EventStream; + + /** + * @method + * @description Takes the last element from the [EventStream]{@link Bacon.EventStream}. None, if EventStream is empty. + * @returns {EventStream} + * @example + * // This creates the stream which doesn't produce any events and never ends: + * Bacon.interval(1e1, 0).last(); + */ + last():EventStream; + + /** + * @method + * @description Skips the first `n` elements from the [EventStream]{@link Bacon.EventStream}. + * @param {number} n + * @returns {EventStream} + */ + skip(n:number):EventStream; + + /** + * @method + * @description Delays the [EventStream]{@link Bacon.EventStream} by given `delay` (in milliseconds). + * @param {number} delay + * @returns {EventStream} + */ + delay(delay:number):EventStream; + + /** + * @method EventStream#throttle + * @description Throttles the [EventStream]{@link Bacon.EventStream} by given `delay` (in milliseconds). Events are emitted with the minimum interval of `delay`. The implementation is based on [EventStream.bufferWithTime]{@link Bacon.EventStream#bufferWithTime}. + * @param {number} delay + * @returns {EventStream} + */ + throttle(delay:number):EventStream; + + /** + * @method EventStream#debounce + * @description Throttles the [EventStream]{@link Bacon.EventStream} by given `delay` (in milliseconds), but so that event is only emitted after the given "quiet period". The difference of [throttle]{@link Bacon.EventStream#throttle} and [debounce]{@link Bacon.EventStream#debounce} is the same as it is in the same methods in jQuery. + * @param {number} delay + * @returns {EventStream} + */ + debounce(delay:number):EventStream; + + /** + * @method + * @description Passes the first event in the [EventStream]{@link Bacon.EventStream} through, but after that, only passes events after a given `delay` (in milliseconds) have passed since previous output. + * @param {number} delay + * @returns {EventStream} + */ + debounceImmediate(delay:number):EventStream; + + /** + * @callback EventStream#doAction~f + * @param {A} value + * @returns {void} + */ + /** + * @method EventStream#doAction + * @description Returns an [EventStream]{@link Bacon.EventStream} where the function `f` is executed for each value, before dispatching to subscribers. This is useful for debugging, but also for stuff like calling the `preventDefault()` method for events. + * @param {EventStream#doAction~f} f + * @returns {EventStream} + */ + doAction(f:(value:A) => void):EventStream; + + /** + * @method + * @description Returns an [EventStream]{@link Bacon.EventStream} where the `propertyExtractor` string is applied to each value, before dispatching to subscribers. This is useful for debugging, but also for stuff like calling the `preventDefault()` method for events. + * @param {string} propertyExtractor + * @returns {EventStream} + */ + doAction(propertyExtractor:string):EventStream; + + /** + * @callback EventStream#doError~f + * @param {E} error + * @returns {void} + */ + /** + * @method EventStream#doError + * @description Returns an [EventStream]{@link Bacon.EventStream} where the function `f` is executed for each error, before dispatching to subscribers. That is, same as `doAction` but for errors. + * @param {EventStream#doError~f} f + * @returns {EventStream} + */ + doError(f:(error:E) => void):EventStream; + + /** + * @method + * @description Returns an [EventStream]{@link Bacon.EventStream} that inverts boolean values. + * @returns {EventStream} + */ + not():EventStream; + + /** + * @method EventStream#log + * @description Logs each value of the [EventStream]{@link Bacon.EventStream} to the console. It optionally takes a `label` argument to pass to `console.log()` alongside each value. To assist with chaining, it returns the original EventStream. Note that as a side-effect, the EventStream will have a constant listener and will not be garbage-collected. So, use this for debugging only and remove from production code. + * @param {string} [label] + * @returns {EventStream} + */ + log(label?:string):EventStream; + + /** + * @method EventStream#doLog + * @description Logs each value of the [EventStream]{@link Bacon.EventStream} to the console. [doLog]{@link Bacon.EventStream#doLog} behaves like [log]{@link Bacon.EventStream#log} but does not subscribe to the EventStream. You can think of `doLog` as a logger function that – unlike `log` – is safe to use in production. `doLog` is safe, because it does not cause the same surprising side-effects as `log` does. + * @returns {EventStream} + */ + doLog():EventStream; + + /** + * @method + * @description Ends the [EventStream]{@link Bacon.EventStream} on first [Error]{@link Bacon.Error} event. The error is included in the output of the returned EventStream. + * @returns {EventStream} + */ + endOnError():EventStream; + + /** + * @callback EventStream#endOnError~f + * @param {E} error + * @returns {boolean} + */ + /** + * @method EventStream#endOnError + * @description Ends the [EventStream]{@link Bacon.EventStream} on first [Error]{@link Bacon.Error} event for which the given predicate function `f` returns `true`. The error is included in the output of the returned EventStream. + * @param {EventStream#endOnError} f + * @returns {EventStream} + */ + endOnError(f:(error:E) => boolean):EventStream; + + /** + * @callback EventStream#withHandler~f + * @param {Initial|Next|End|Error} event + * @returns {*} + */ + /** + * @method EventStream#withHandler + * @description Lets you do more custom event handling on [EventStream]{@link Bacon.EventStream}: you get all events to your function `f` and you can output any number of events and end the stream if you choose. Note that it's important to return the value from `this.push` so that the connection to the underlying stream will be closed when no more events are needed. + * @param {EventStream#withHandler~f} f + * @returns {EventStream} + * @example + * // Send an error and end the stream in case a value is below zero: + * Bacon.fromArray([1, 2, -3, 3]).withHandler(function (event) { + * if (event.hasValue() && event.value() < 0) { + * this.push(new Bacon.Error("Value below zero")); + * return this.push(new Bacon.End()); + * } else { + * return this.push(event); + * } + * }); + */ + withHandler(f:(event:Initial|Next|End|Error) => any):EventStream; + + /** + * @method + * @description Sets the name of the [EventStream]{@link Bacon.EventStream}. Overrides the default implementation of `toString` and `inspect`. Returns itself. + * @param {string} newName + * @returns {EventStream} + */ + name(newName:string):EventStream; + + /** + * @method + * @description Sets the structured description of the [EventStream]{@link Bacon.EventStream}. The `toString` and `inspect` methods use this data recursively to create a string representation for the `EventStream`. This method is probably useful for Bacon core/library/plugin development only. + * @param {...*} param + * @returns {EventStream} + * @example + * let src = Bacon.once(1), + * obs = src.map(x => -x); + * + * console.log(obs.toString()); + * // Bacon.once(1).map(function) + * + * obs.withDescription(src, "times", -1); + * console.log(obs.toString()); + * // Bacon.once(1).times(-1) + */ + withDescription(...param:any[]):EventStream; + + /** + * @callback EventStream#groupBy1~keyF + * @param {A} value + * @returns {B} + */ + /** + * @method EventStream#groupBy1 + * @description Groups [EventStream]{@link Bacon.EventStream} events to new EventStream's by `keyF`. + * @param {EventStream#groupBy1~keyF} keyF + * @returns {EventStream>} + */ + groupBy(keyF:(value:A) => B):EventStream>; + + /** + * @callback keyF + * @param {A} value + * @returns {B} + */ + /** + * @callback limitF + * @param {EventStream} groupedStream + * @param {Initial|Next|End|Error} groupStartingEvent + * @returns {EventStream} + */ + /** + * @description Groups [EventStream]{@link Bacon.EventStream} events to new EventStream's by `keyF`. `limitF` is provided to limit grouped stream life. EventStream transformed by `limitF` is passed on if provided. `limitF` gets grouped stream and the original [Event]{@link Bacon.Event} causing the EventStream to start as parameters. + * @param {keyF} keyF + * @param {limitF} limitF + * @returns {EventStream>} Grouped streams. + */ + groupBy(keyF:(value:A) => B, limitF:(groupedStream:EventStream, groupStartingEvent:Initial|Next|End|Error) => EventStream):EventStream>; + + /** + * @callback EventStream#subscribe~f + * @param {Event} event + * @returns {void|NoMore} + */ + /** + * @callback EventStream#subscribe~unsubscribe + * @returns {void} + */ + /** + * @method EventStream#subscribe + * @description Subscribes a given handler function `f` to [EventStream]{@link Bacon.EventStream}. Function will receive [Event]{@link Bacon.Event} objects. The [subscribe]{@link EventStream#subscribe} call returns an [unsubscribe function]{@link EventStream#subscribe~unsubscribe} that you can call to unsubscribe. You can also unsubscribe by returning [Bacon.noMore]{@link Bacon.noMore} from the handler function as a reply to an Event. + * @param {EventStream#subscribe~f} f + * @returns {EventStream#subscribe~unsubscribe} + */ + subscribe(f:(event:Event) => void|NoMore):() => void; + + /** + * @callback EventStream#onValue~f + * @param {A} value + * @returns {void} + */ + /** + * @callback EventStream#onValue~unsubscribe + * @returns {void} + */ + /** + * @method EventStream#onValue + * @description Subscribes a given handler function `f` to [EventStream]{@link Bacon.EventStream}. Function will be called for each new value in the EventStream. This is the simplest way to assign a side-effect to a EventStream. The difference to the [subscribe]{@link Bacon.EventStream#subscribe} method is that the actual EventStream values are received, instead of [Event]{@link Bacon.Event} objects. Just like `subscribe`, this method returns a function for `unsubscribe`ing. + * @param {EventStream#onValue~f} f + * @returns {EventStream#onValue~unsubscribe} + */ + onValue(f:(value:A) => void):() => void; + + /** + * @callback EventStream#onValues~f + * @param {*[]} args + * @returns {void} + */ + /** + * @callback EventStream#onValues~unsubscribe + * @returns {void} + */ + /** + * @method EventStream#onValues + * @description Subscribes a given handler function `f` to [EventStream]{@link Bacon.EventStream}. Like [EventStream.onValue]{@link Bacon.EventStream#onValue}, but splits the value (assuming its an array) as function arguments to `f`. + * @param {EventStream#onValues~f} f + * @returns {EventStream#onValues~unsubscribe} + */ + onValues(f:(...args:any[]) => void):() => void; + + /** + * @callback EventStream#skipDuplicates~isEqual + * @param {A} oldValue + * @param {A} newValue + * @returns {boolean} + */ + /** + * @method EventStream#skipDuplicates + * @description Drops consecutive equal elements of the [EventStream]{@link Bacon.EventStream}. Uses the === operator for equality checking by default. If the `isEqual` argument is supplied, checks by calling [isEqual]{@link EventStream#skipDuplicates~isEqual}. For instance, to do a deep comparison, you can use the `isEqual` function from underscore.js like `stream.skipDuplicates(_.isEqual)`. + * @param {EventStream#skipDuplicates~isEqual} [isEqual] + * @returns {EventStream} + * @example + * Bacon.fromArray([1, 2, 2, 1]).skipDuplicates().log(); + * // > returns [1, 2, 1] in an order + */ + skipDuplicates(isEqual?:(oldValue:A, newValue:A) => boolean):EventStream; + + /** + * @method + * @description Concatenates two [EventStream]{@link Bacon.EventStream}s into one so that it will deliver events from EventStream until it ends and then deliver events from `otherStream`. This means too that events from `otherStream`, occurring before the end of EventStream will not be included in the result EventStream. + * @param {EventStream} otherStream + * @returns {EventStream} + */ + concat(otherStream:EventStream):EventStream; + + /** + * @method + * @description Merges two [EventStream]{@link Bacon.EventStream}s into one that delivers events from both. + * @param {EventStream} otherStream + * @returns {EventStream} + */ + merge(otherStream:EventStream):EventStream; + + /** + * @method + * @description Pauses and buffers the [EventStream]{@link Bacon.EventStream} if last event in `valve` is truthy. All buffered events are released when `valve` becomes falsy. + * @param {Observable} valve + * @returns {EventStream} + */ + holdWhen(valve:Observable):EventStream; + + /** + * @method + * @description Adds a starting `value` to the [EventStream]{@link Bacon.EventStream}, i.e. concats a EventStream containing a single `value` with this EventStream. + * @param {A} value + * @returns {EventStream} + */ + startWith(value:A):EventStream; + + /** + * @callback EventStream#skipWhile~f + * @param {A} value + * @returns {boolean} + */ + /** + * @method EventStream#skipWhile + * @description Skips elements in the [EventStream]{@link Bacon.EventStream} until the given predicate function `f` returns falsy once, and then lets all events pass through. + * @param {EventStream#skipWhile~f} f + * @returns {EventStream} + */ + skipWhile(f:(value:A) => boolean):EventStream; + + /** + * @method + * @description Skips elements in the [EventStream]{@link Bacon.EventStream} until the value of the given [Property]{@link Bacon.Property} `property` is falsy once, and then lets all events pass through. + * @param {Property} property + * @returns {EventStream} + */ + skipWhile(property:Property):EventStream; + + /** + * @method + * @description Skips elements from the [EventStream]{@link Bacon.EventStream} until a [Next]{@link Bacon.Next} event appears in `stream2`. In other words, starts delivering values from `stream` after first event appears in `stream2`. + * @param {EventStream} stream2 + * @returns {EventStream} + */ + skipUntil(stream2:EventStream):EventStream; + + /** + * @method + * @description Buffers the [EventStream]{@link Bacon.EventStream} with given `delay` (in milliseconds). The buffer is flushed at most once in the given `delay`. + * @param {number} delay + * @returns {EventStream} + * @example + * // You might get two events containing [1,2,3,4] and [5,6,7] respectively, given that the flush occurs between numbers 4 and 5: + * Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]).bufferWithTime(0); + */ + bufferWithTime(delay:number):EventStream; + + /** + * @callback EventStream#bufferWithTime~f + * @param {EventStream#bufferWithTime~defer} defer + * @returns {void} + */ + /** + * @callback EventStream#bufferWithTime~defer + * @param {...*} args + * @returns {void} + */ + /** + * @method EventStream#bufferWithTime + * @description Buffers the [EventStream]{@link Bacon.EventStream} with given "defer-function" `f`. + * @param {EventStream#bufferWithTime~f} f + * @returns {EventStream} + * @example + * // Here's an equivalent to `stream.bufferWithTime(10)`: + * let stream = Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]); + * stream.bufferWithTime(f => { setTimeout(f, 10); }); } + */ + bufferWithTime(f:(defer:(...args:any[]) => void) => void):EventStream; + + /** + * @method + * @description Buffers the [EventStream]{@link Bacon.EventStream} events with given `count`. The buffer is flushed when it contains the given `count` of elements. + * @param {number} count + * @returns {EventStream} + * @example + * // You will get output events with values `[1, 2]`, `[3, 4]` and `[5]`. + * Bacon.fromArray([1, 2, 3, 4, 5]).bufferWithCount(2); + */ + bufferWithCount(count:number):EventStream; + + /** + * @method + * @description Buffers the [EventStream]{@link Bacon.EventStream} events and flushes when either the buffer contains the given `count` of elements or the given `delay` (in milliseconds) has passed since last buffered event. + * @param {number} delay + * @param {number} count + * @returns {EventStream} + */ + bufferWithTimeOrCount(delay:number, count:number):EventStream; + + /** + * @method EventStream#toProperty + * @description Creates a [Property]{@link Bacon.Property} based on the [EventStream]{@link Bacon.EventStream}. Without arguments, you'll get a Property without an initial value and will get its first actual value from the EventStream, and after that it'll always have a current value. Given `initialValue` will be used as the current value until the first value comes from the EventStream. + * @param {A} [initialValue] + * @returns {Property} + */ + toProperty(initialValue?:A):Property; + } + + var EventStream:{ + /** + * @callback EventStream#new~subscribe + * @param {EventStream#new~sink} sink + * @returns {EventStream#new~unsubscribe} + */ + /** + * @callback EventStream#new~sink + * @param {More|NoMore|(A|Initial|Next|End|Error)|(A|Initial|Next|End|Error)[]} value + * @returns {void} + */ + /** + * @callback EventStream#new~unsubscribe + * @returns {void} + */ + /** + * @constructor EventStream#new + * @constructs Bacon.EventStream + * @description Creates an [EventStream]{@link Bacon.EventStream} with the given `subscribe` function. + * @param {EventStream#new~subscribe} subscribe + * @returns {EventStream} + */ + new(subscribe:(sink:(value:More|NoMore|(A|Initial|Next|End|Error)|(A|Initial|Next|End|Error)[]) => void) => (() => void)):EventStream; + }; + + /** + * @class Property + * @augments Bacon.Observable + * @description A reactive property. Has the concept of "current value". You can create a Property from an [EventStream]{@link Bacon.EventStream} by using either [EventStream.toProperty]{@link Bacon.EventStream#toProperty} or [Observable.scan]{@link Bacon.Observable#scan} method. Note: depending on how a Property is created, it may or may not have an initial value. The current value stays as its last value after the EventStream has ended. + * */ + interface Property extends Observable { + /** + * @callback Property#map~f + * @param {A} value + * @returns {B} + */ + /** + * @method Property#map + * @description Maps the [Property]{@link Bacon.Property} values using given function `f`, returning a new Property. This method, among many others, uses lazy evaluation. + * @param {Property#map~f} f + * @returns {Property} + * */ + map(f:(value:A) => B):Property; + + /** + * @method + * @description Maps the [Property]{@link Bacon.Property} values using given `constant` value, returning a new Property. This method, among many others, uses lazy evaluation. + * @param {B} constant + * @returns {Property} + * */ + map(constant:B):Property; + + /** + * @method + * @description Maps the [Property]{@link Bacon.Property} values using given `propertyExtractor` string like ".keyCode", returning a new Property. So, if f is a string starting with a dot, the elements will be mapped to the corresponding field/function in the event value. For instance map(".keyCode") will pluck the keyCode field from the input values. If "keyCode" was a function, the resulting Property would contain the values returned by the function. This method, among many others, uses lazy evaluation. + * @param {string} propertyExtractor + * @returns {Property} + * */ + map(propertyExtractor:string):Property; + + /** + * @callback Property#mapError~f + * @param {E} error + * @returns {B} + */ + /** + * @method Property#mapError + * @description Maps the [Property]{@link Bacon.Property} errors using given function `f`. More specifically, feeds the "error" field of the [Error]{@link Bacon.Error} event to the function `f` and produces a [Next]{@link Bacon.Next} event based on the return value. + * @param {Property#mapError~f} f + * @returns {Property} + */ + mapError(f:(error:E) => B):Property; + + /** + * @method + * @description Returns a [Property]{@link Bacon.Property} containing [Error]{@link Bacon.Error} events only. Same as filtering with a function that always returns false. + * @returns {Property} + */ + errors():Property; + + /** + * @method + * @description Skips all [Error]{@link Bacon.Error}s. + * @returns {Property} + */ + skipErrors():Property; + + /** + * @callback Property#mapEnd~f + * @returns {A} + */ + /** + * @method Property#mapEnd + * @description Adds an extra [Next]{@link Bacon.Next} event just before [End]{@link Bacon.End} of the [Property]{@link Bacon.Property}. The value is created by calling the given function `f` when the source Property ends. + * @param {Property#mapEnd~f} f + * @returns {Property} + */ + mapEnd(f:() => A):Property; + + /** + * @method + * @description Adds an extra [Next]{@link Bacon.Next} event just before [End]{@link Bacon.End} of the [Property]{@link Bacon.Property}. A static `value` is used. + * @param {A} value + * @returns {Property} + */ + mapEnd(value:A):Property; + + /** + * @callback Property#filter~f + * @param {A} value + * @returns {boolean} + */ + /** + * @method Property#filter + * @description Filters the [Property]{@link Bacon.Property} values using a given predicate function `f`. + * @param {Property#filter~f} f + * @returns {Property} + */ + filter(f:(value:A) => boolean):Property; + + /** + * @method + * @description Filters the [Property]{@link Bacon.Property} values using a given constant `bool` value (`true` to include all, `false` to exclude all). + * @param {boolean} bool + * @returns {Property} + */ + filter(bool:boolean):Property; + + /** + * @method + * @description Filters the [Property]{@link Bacon.Property} values using a given `propertyExtractor` string (like ".isValuable"). + * @param {string} propertyExtractor + * @returns {Property} + */ + filter(propertyExtractor:string):Property; + + /** + * @method + * @description Filters the [Property]{@link Bacon.Property} values based on the value of the Property `property`. Event will be included in output IF AND ONLY IF the `property` holds `true` at the time of the event. + * @param {Property} property + * @returns {Property} + */ + filter(property:Property):Property; + + /** + * @callback Property#takeWhile~f + * @param {A} value + * @returns {boolean} + */ + /** + * @method Property#takeWhile + * @description Takes the [Property]{@link Bacon.Property} values while given predicate function `f` holds `true`, and then ends. + * @param {Property#takeWhile~f} f + * @returns {Property} + */ + takeWhile(f:(value:A) => boolean):Property; + + /** + * @method + * @description Takes the [Property]{@link Bacon.Property} values while the value of a `property` holds `true`, and then ends. + * @param {Property} property + * @returns {Property} + */ + takeWhile(property:Property):Property; + + /** + * @method Property#take + * @description Takes at most `n` elements from the [Property]{@link Bacon.Property}. Equal to `Bacon.never()` if `n <= 0`. + * @param {number} n + * @returns {Property} + */ + take(n:number):Property; + + /** + * @method + * @description Takes elements from the [Property]{@link Bacon.Property} until a [Next]{@link Bacon.Next} event appears in the `stream`. If `stream` ends without value, it is ignored. + * @param {EventStream} stream + * @returns {Property} + */ + takeUntil(stream:EventStream):Property; + + /** + * @method + * @description Takes the first element from the [Property]{@link Bacon.Property}. Essentially [Property.take]{@link Bacon.Property#take}(1). + * @returns {Property} + */ + first():Property; + + /** + * @method + * @description Takes the last element from the [Property]{@link Bacon.Property}. None, if Property is empty. + * @returns {Property} + * @example + * // This creates the property which doesn't produce any events and never ends: + * Bacon.interval(1e1, 0).toProperty().last(); + */ + last():Property; + + /** + * @method + * @description Skips the first `n` elements from the [Property]{@link Bacon.Property}. + * @param {number} n + * @returns {Property} + */ + skip(n:number):Property; + + /** + * @method + * @description Delays the [Property]{@link Bacon.Property} by given `delay` (in milliseconds). Does not delay the initial value of a Property. + * @param {number} delay + * @returns {Property} + */ + delay(delay:number):Property; + + /** + * @method Property#throttle + * @description Throttles the [Property]{@link Bacon.Property} by given `delay` (in milliseconds). Events are emitted with the minimum interval of `delay`. The implementation is based on [EventStream.bufferWithTime]{@link Bacon.EventStream#bufferWithTime}. Does not affect emitting the initial value of a Property. + * @param {number} delay + * @returns {Property} + */ + throttle(delay:number):Property; + + /** + * @method Property#debounce + * @description Throttles the [Property]{@link Bacon.Property} by given `delay` (in milliseconds), but so that event is only emitted after the given "quiet period". Does not affect emitting the initial value of a Property. The difference of [throttle]{@link Bacon.Property#throttle} and [debounce]{@link Bacon.Property#debounce} is the same as it is in the same methods in jQuery. + * @param {number} delay + * @returns {Property} + */ + debounce(delay:number):Property; + + /** + * @method + * @description Passes the first event in the [Property]{@link Bacon.Property} through, but after that, only passes events after a given `delay` (in milliseconds) have passed since previous output. + * @param {number} delay + * @returns {Property} + */ + debounceImmediate(delay:number):Property; + + /** + * @callback Property#doAction~f + * @param {A} value + * @returns {void} + */ + /** + * @method Property#doAction + * @description Returns a [Property]{@link Bacon.Property} where the function `f` is executed for each value, before dispatching to subscribers. This is useful for debugging, but also for stuff like calling the `preventDefault()` method for events. + * @param {Property#doAction~f} f + * @returns {Property} + */ + doAction(f:(value:A) => void):Property; + + /** + * @method + * @description Returns a [Property]{@link Bacon.Property} where the `propertyExtractor` string is applied to each value, before dispatching to subscribers. This is useful for debugging, but also for stuff like calling the `preventDefault()` method for events. + * @param {string} propertyExtractor + * @returns {Property} + */ + doAction(propertyExtractor:string):Property; + + /** + * @callback Property#doError~f + * @param {E} error + * @returns {void} + */ + /** + * @method Property#doError + * @description Returns a [Property]{@link Bacon.Property} where the function `f` is executed for each error, before dispatching to subscribers. That is, same as [doAction]{@link Bacon.Property#doAction} but for [Error]{@link Bacon.Error}s. + * @param {Property#doError~f} f + * @returns {Property} + */ + doError(f:(error:E) => void):Property; + + /** + * @method + * @description Returns a [Property]{@link Bacon.Property} that inverts boolean values. + * @returns {Property} + */ + not():Property; + + /** + * @method Property#log + * @description Logs each value of the [Property]{@link Bacon.Property} to the console. It optionally takes a `label` argument to pass to `console.log()` alongside each value. To assist with chaining, it returns the original Property. Note that as a side-effect, the Property will have a constant listener and will not be garbage-collected. So, use this for debugging only and remove from production code. + * @param {string} [label] + * @returns {Property} + */ + log(label?:string):Property; + + /** + * @method Property#doLog + * @description Logs each value of the [Property]{@link Bacon.Property} to the console. [doLog]{@link Bacon.Property#doLog} behaves like [log]{@link Bacon.Property#log} but does not subscribe to the Property. You can think of `doLog` as a logger function that – unlike `log` – is safe to use in production. `doLog` is safe, because it does not cause the same surprising side-effects as `log` does. + * @returns {Property} + */ + doLog():Property; + + /** + * @method + * @description Ends the [Property]{@link Bacon.Property} on first [Error]{@link Bacon.Error} event. The error is included in the output of the returned Property. + * @returns {Property} + */ + endOnError():Property; + + /** + * @callback Property#endOnError~f + * @param {E} error + * @returns {boolean} + */ + /** + * @method Property#endOnError + * @description Ends the [Property]{@link Bacon.Property} on first [Error]{@link Bacon.Error} event for which the given predicate function `f` returns `true`. The error is included in the output of the returned Property. + * @param {Property#endOnError~f} f + * @returns {Property} + */ + endOnError(f:(error:E) => boolean):Property; + + /** + * @callback Property#withHandler~f + * @param {Initial|Next|End|Error} event + * @returns {*} + */ + /** + * @method Property#withHandler + * @description Lets you do more custom event handling on the [Property]{@link Bacon.Property}: you get all events to your function `f` and you can output any number of [Event]{@link Bacon.Event}s and end the Property if you choose. Note that it's important to return the value from `this.push` so that the connection to the underlying stream will be closed when no more events are needed. + * @param {Property#withHandler~f} f + * @returns {Property} + * @example + * // Send an error and end the stream in case a value is below zero: + * Bacon.fromArray([1, 2, -3, 3]).withHandler(function (event) { + * if (event.hasValue() && event.value() < 0) { + * this.push(new Bacon.Error("Value below zero")); + * return this.push(new Bacon.End()); + * } else { + * return this.push(event); + * } + * }); + */ + withHandler(f:(event:Initial|Next|End|Error) => any):Property; + + /** + * @method + * @description Sets the `newName` of the [Property]{@link Bacon.Property}. Overrides the default implementation of `toString` and `inspect`. Returns itself. + * @param {string} newName + * @returns {Property} + */ + name(newName:string):Property; + + /** + * @method + * @description Sets the structured description of the [Property]{@link Bacon.Property}. The `toString` and `inspect` methods use this data recursively to create a string representation for the Property. This method is probably useful for Bacon core/library/plugin development only. + * @param {...*} param + * @returns {Property} + * @example + * let src = Bacon.once(1), + * obs = src.map(x => -x); + * + * console.log(obs.toString()); + * // Bacon.once(1).map(function) + * + * obs.withDescription(src, "times", -1); + * console.log(obs.toString()); + * // Bacon.once(1).times(-1) + */ + withDescription(...param:any[]):Property; + + /** + * @method + * @description Creates an [EventStream]{@link Bacon.EventStream} based on this [Property]{@link Bacon.Property}. The EventStream contains also an event for the current value of this Property at the time this method was called. + * @returns {EventStream} + */ + toEventStream():EventStream; + + /** + * @callback Property#subscribe~f + * @param {Event} event + * @returns {void} + */ + /** + * @callback Property#subscribe~unsubscribe + * @returns {void} + */ + /** + * @method Property#subscribe + * @description Subscribes a handler function `f` to [Property]{@link Bacon.Property}. If there's a current value, an [Initial]{@link Bacon.Initial} event will be pushed immediately. [Next]{@link Bacon.Next} event will be pushed on updates and an [End]{@link Bacon.End} event in case the source Property ends. Returns a function that you call to `unsubscribe`. + * @param {Property#subscribe~f} f + * @returns {Property#subscribe~unsubscribe} + */ + subscribe(f:(event:Event) => void):() => void; + + /** + * @callback Property#onValue~f + * @param {A} value + * @returns {void} + */ + /** + * @callback Property#onValue~unsubscribe + * @returns {void} + */ + /** + * @method Property#onValue + * @description Subscribes a handler function `f` to [Property]{@link Bacon.Property}. Similar to [EventStream.onValue]{@link Bacon.EventStream#onValue}, except that also pushes the initial value of the Property, in case there is one. Just like [subscribe]{@link Bacon.Property#subscribe}, this method returns a function for `unsubscribe`ing. + * @param {Property#onValue~f} f + * @returns {Property#onValue~unsubscribe} + */ + onValue(f:(value:A) => void):() => void; + + /** + * @callback Property#onValues~f + * @param {*[]} args + * @returns {void} + */ + /** + * @callback Property#onValues~unsubscribe + * @returns {void} + */ + /** + * @method Property#onValues + * @description Subscribes a handler function `f` to [Property]{@link Bacon.Property}. Like [onValue]{@link Bacon.Property#onValue}, but splits the value (assuming its an array) as function arguments to `f`. + * @param {Property#onValues~f} f + * @returns {Property#onValues~unsubscribe} + */ + onValues(f:(...args:any[]) => void):() => void; + + /** + * @method Property#assign + * @description Calls the `method` of the given `object` with each value of this [Property]{@link Bacon.Property}. You can optionally supply `params` which will be used as the first arguments of the `method` call. Note that the [assign]{@link Bacon.Property#assign} method is actually just a synonym for [onValue]{@link Bacon.Property#onValue}. + * @param {Object} obj + * @param {string} method + * @param {...*} params + * @returns {void} + * @example + * let property = Bacon.fromArray([1, 2, 3, 4, 5]).toProperty(); + * // If you want to assign your Property to the "disabled" attribute of a JQuery object, you can do this: + * property.assign($("#my-button"), "attr", "disabled"); + * // A simpler example would be to toggle the visibility of an element based on a Property: + * property.assign($("#my-button"), "toggle"); + */ + assign(obj:Object, method:string, ...params:any[]):void; + + /** + * @method + * @description Creates an [EventStream]{@link Bacon.EventStream} by sampling the [Property]{@link Bacon.Property} value at given `interval` (in milliseconds). + * @param {number} interval + * @returns {EventStream} + */ + sample(interval:number):EventStream; + + /** + * @method Property#sampledBy + * @description Creates an [EventStream]{@link Bacon.EventStream} by sampling the [Property]{@link Bacon.Property} value at each event from the given `stream`. The result EventStream will contain the value at each event in the source Property. + * @param {EventStream} stream + * @returns {EventStream} + */ + sampledBy(stream:EventStream):EventStream; + + /** + * @method + * @description Creates a [Property]{@link Bacon.Property} by sampling the value at each event from the given [Property]{@link Bacon.Property} `property`. The result Property will contain the value at each event in the source Property. + * @param {Property} property + * @returns {Property} + */ + sampledBy(property:Property):Property; + + /** + * @callback Property#sampledBy~f + * @param {A} propertyValue + * @param {B} samplerValue + * @returns {C} + */ + /** + * @method Property#sampledBy + * @description Samples the [Property]{@link Bacon.Property} on `streamOrProperty` events. The result values will be formed using the given function `f`. + * @param {Observable} streamOrProperty + * @param {Property#sampledBy~f} f + * @returns {EventStream} + */ + sampledBy(streamOrProperty:Observable, f:(propertyValue:A, samplerValue:B) => C):EventStream; + + /** + * @callback Property#skipDuplicates~isEqual + * @param {A} oldValue + * @param {A} newValue + * @returns {boolean} + */ + /** + * @method Property#skipDuplicates + * @description Drops consecutive equal elements. Uses the `===` operator for equality checking by default. If the `isEqual` argument is supplied, checks by calling `isEqual(oldValue, newValue)`. The old name for this method was `distinctUntilChanged`. + * @param {Property#skipDuplicates~isEqual} [isEqual] + * @returns {Property} + */ + skipDuplicates(isEqual?:(oldValue:A, newValue:A) => boolean):Property; + + /** + * @method Property#changes + * @description Returns an [EventStream]{@link Bacon.EventStream} of [Property]{@link Bacon.Property} value changes. Returns exactly the same events as the Property itself, except any [Initial]{@link Bacon.Initial} events (the stream DOES NOT include an event for the current value of the Property at the time this method was called). Note that [Property.changes]{@link Bacon.Property#changes} DOES NOT skip duplicate values, use [Property.skipDuplicates]{@link Bacon.Property#skipDuplicates} for that. + * @returns {EventStream} + */ + changes():EventStream; + + /** + * @method + * @description Combines [Property]{@link Bacon.Property}s with the && operator. + * @param {Property} other + * @returns {Property} + */ + and(other:Property):Property; + + /** + * @method + * @description Combines [Property]{@link Bacon.Property}s with the || operator. + * @param {Property} other + * @returns {Property} + */ + or(other:Property):Property; + + /** + * @method + * @description Adds an initial "default" value for the [Property]{@link Bacon.Property}. If the Property doesn't have an initial value of it's own, the given `value` will be used as the initial value. If the property has an initial value of its own, the given `value` will be ignored. + * @param {A} value + * @returns {Property} + */ + startWith(value:A):Property; + } + + /** + * @function Bacon.combineAsArray + * @description Combines [Property]{@link Bacon.Property}s, [EventStream]{@link Bacon.EventStream}s and constant values so that the result Property will have an array of all property values as its value. The input array may contain both Properties and EventStreams. In the latter case, the stream is first converted into a Property and then combined with the other Property's. + * @param {(A|Observable)[]} streams + * @returns {Property} + */ + function combineAsArray(streams:(A|Observable)[]):Property; + + /** + * @function + * @description Combines [Property]{@link Bacon.Property}s, [EventStream]{@link Bacon.EventStream}s and constant values so that the result Property will have an array of all property values as its value. Like [Bacon.combineAsArray]{@link Bacon.combineAsArray}, but `streams` are provided as a list of arguments as opposed to a single array. + * @param {...(A|Observable)} streams + * @returns {Property} + */ + function combineAsArray(...streams:(A|Observable)[]):Property; + + /** + * @callback Property#combineWith~f + * @param {...A} args + * @returns {B} + */ + /** + * @function Property#combineWith + * @description Combines given n [Property]{@link Bacon.Property}s, [EventStream]{@link Bacon.EventStream}s and constant values using the given n-ary function `f`. + * @param {Property#combineWith~f} f + * @param {...(A|Observable)} streams + * @returns {Property} + */ + function combineWith(f:(...args:A[]) => B, ...streams:(A|Observable)[]):Property; + + /** + * @function + * @description Combines [Property]{@link Bacon.Property}s, [EventStream]{@link Bacon.EventStream}s and constant values using a `template` object. + * @param {{string:number|boolean|string|Object|Observable}} template + * @returns {Property} + */ + function combineTemplate(template:{[label:string]:number|boolean|string|Object|Observable}):Property; + + /** + * @function + * @description Merges given array of [EventStream]{@link Bacon.EventStream}s. + * @param {EventStream[]} streams + * @returns {EventStream} + */ + function mergeAll(streams:EventStream[]):EventStream; + + /** + * @function + * @description Merges given array of [EventStream]{@link Bacon.EventStream}s. + * @param {...EventStream} streams + * @returns {EventStream} + */ + function mergeAll(...streams:EventStream[]):EventStream; + + /** + * @function + * @description Zips the array of `streams` in to a new [EventStream]{@link Bacon.EventStream} that will have an array of values from each source EventStream as its value. Zipping means that events from each EventStream are combine pairwise so that the 1st event from each EventStream is published first, then the 2nd event from each. The results will be published as soon as there is a value from each source EventStream. Be careful not to have too much "drift" between EventStream's. If one EventStream produces many more values than some other excessive buffering will occur inside the zipped [Observable]{@link Bacon.Observable}. + * @param {EventStream[]} streams + * @returns {EventStream} + */ + function zipAsArray(streams:EventStream[]):EventStream; + + /** + * @function + * @description Zips the `streams` in to a new [EventStream]{@link Bacon.EventStream} that will have an array of values from each source EventStream as its value. Zipping means that events from each EventStream are combine pairwise so that the 1st event from each EventStream is published first, then the 2nd event from each. The results will be published as soon as there is a value from each source EventStream. EventStream's are provided as a list of arguments as opposed to a single array. Be careful not to have too much "drift" between EventStream's. If one EventStream produces many more values than some other excessive buffering will occur inside the zipped [Observable]{@link Bacon.Observable}. + * @param {...EventStream} streams + * @returns {EventStream} + */ + function zipAsArray(...streams:EventStream[]):EventStream; + + /** + * @callback Bacon.zipWith1~f + * @param {...A} args + * @returns {B} + */ + /** + * @function Bacon.zipWith1 + * @description Zips the array of `streams` in to a new [EventStream]{@link Bacon.EventStream} that will combine the n values from EventStream's with n-ary function `f`. Zipping means that events from each EventStream are combine pairwise so that the 1st event from each EventStream is published first, then the 2nd event from each. The results will be published as soon as there is a value from each source EventStream. Be careful not to have too much "drift" between EventStream's. If one EventStream produces many more values than some other excessive buffering will occur inside the zipped [Observable]{@link Bacon.Observable}. + * @param {EventStream[]} streams + * @param {Bacon.zipWith1~f} f + * @returns {EventStream} + */ + function zipWith(streams:EventStream[], f:(...args:A[]) => B):EventStream; + + /** + * @callback Bacon.zipWith2~f + * @param {...A} args + * @returns {B} + */ + /** + * @function Bacon.zipWith2 + * @description Zips the `streams` in to a new [EventStream]{@link Bacon.EventStream} that will combine the n values from EventStream's with n-ary function `f`. Zipping means that events from each EventStream are combine pairwise so that the 1st event from each EventStream is published first, then the 2nd event from each. The results will be published as soon as there is a value from each source EventStream. Streams are provided as a list of arguments as opposed to a single array. Be careful not to have too much "drift" between EventStream's. If one EventStream produces many more values than some other excessive buffering will occur inside the zipped [Observable]{@link Bacon.Observable}. + * @param {Bacon.zipWith2~f} f + * @param {...EventStream} streams + * @returns {EventStream} + */ + function zipWith(f:(...args:A[]) => B, ...streams:EventStream[]):EventStream; + + /** + * @function + * @description Is a shorthand for combining multiple sources ([EventStream]{@link Bacon.EventStream}s, [Property]{@link Bacon.Property}s, constants) as array and assigning the side-effect function `f` for the values. + * @param {...*} args + * @returns {void} + */ + function onValues(...args:any[]):void; + + /** + * @class Bus + * @augments Bacon.EventStream + * @description An [EventStream]{@link Bacon.EventStream} that allows you to [push]{@link Bacon.Bus#push} values into the EventStream. It also allows [plug]{@link Bacon.Bus#plug}ging other EventStream's into the Bus. The Bus practically merges all plugged-in streams and the values pushed using the [push]{@link Bacon.Bus#push} method. + */ + interface Bus extends EventStream { + /** + * @method Bus#push + * @description Pushes the given `value` to the [Bus]{@link Bacon.Bus}. + * @param {A} value + * @returns {void} + */ + push(value:A):void; + + /** + * @method + * @description Ends the [Bus]{@link Bacon.Bus}. Sends an [End]{@link Bacon.End} event to all subscribers. After this call, there'll be no more events to the subscribers. Also, the [Bus.push]{@link Bacon.Bus#push} and [Bus.plug]{@link Bacon.Bus#plug} methods have no effect. + * @returns {void} + */ + end():void; + + /** + * @method + * @description Sends an [Error]{@link Bacon.Error} with given `error` message to all subscribers. + * @param {Error} error + * @returns {void} + */ + error(error:Error):void; + + /** + * @callback Bus#plug~unplug + * @returns {void} + */ + /** + * @method Bus#plug + * @description Plugs the given [EventStream]{@link Bacon.EventStream} to the [Bus]{@link Bacon.Bus}. All events from the given `stream` will be delivered to the subscribers of the Bus. Returns a function `unplug` that can be used to unplug the same stream. The [plug]{@link Bacon.Bus#plug} method practically allows you to merge in other EventStream's after the creation of the Bus. + * @param {EventStream} stream + * @returns {Bus#plug~unplug} + */ + plug(stream:EventStream):() => void; + } + + var Bus:{ + /** + * @constructor + * @constructs Bacon.Bus + * @description Returns a new [Bus]{@link Bacon.Bus}. + * @returns {Bus} + */ + new():Bus; + }; + + /** + * @class Event + * @description Has subclasses [Initial]{@link Bacon.Initial}, [Next]{@link Bacon.Next}, [End]{@link Bacon.End} and [Error]{@link Bacon.Error}. + * */ + class Event { + /** + * @method + * @description Returns the value associated with a [Initial]{@link Bacon.Initial} or [Next]{@link Bacon.Next} event. + * @returns {A} + */ + value():A; + + /** + * @method + * @description Returns `true` for events of type [Initial]{@link Bacon.Initial} or [Next]{@link Bacon.Next}. + * @returns {boolean} + */ + hasValue():boolean; + + /** + * @method Error#isInitial + * @description Returns `true` for events of type [Initial]{@link Bacon.Initial}. + * @returns {boolean} + */ + isInitial():boolean; + + /** + * @method Error#isNext + * @description Returns `true` for events of type [Next]{@link Bacon.Next}. + * @returns {boolean} + */ + isNext():boolean; + + /** + * @method Error#isError + * @description Returns `true` for events of type [Error]{@link Bacon.Error}. + * @returns {boolean} + */ + isError():boolean; + + /** + * @method Error#isEnd + * @description Returns `true` for events of type [End]{@link Bacon.End}. + * @returns {boolean} + */ + isEnd():boolean; + } + + /** + * @class Error + * @augments Bacon.Event + * @description An error event. Call [Event.isError]{@link Bacon.Event#isError} to distinguish these events in your subscriber, or use [onError]{@link Bacon.Observable#onError} to react to error events only. [Error.error]{@link Bacon.Error#error} returns the associated error object (usually string). [Error]{@link Bacon.Error} events are always passed through all stream combinators. So, even if you filter all values out, the error events will pass through. If you use [Observable.flatMap]{@link Bacon.Observable#flatMap}, the result stream will contain Error events from the source as well as all the spawned stream. You can take action on errors by using the [Observable.onError]{@link Bacon.Observable#onError}. See documentation on [Observable.onError]{@link Bacon.Observable#onError}, [EventStream.mapError]{@link Bacon.EventStream#mapError}, [Property.mapError]{@link Bacon.Property#mapError}, [EventStream.errors]{@link Bacon.EventStream#errors}, [Property.errors]{@link Bacon.Property#errors}, [EventStream.skipErrors]{@link Bacon.EventStream#skipErrors}, [Property.skipErrors]{@link Bacon.Property#skipErrors}, [Bacon.retry]{@link Bacon.retry} and [Observable.flatMapError]{@link Bacon.Observable#flatMapError}. An Error does not terminate the stream. The methods [EventStream.endOnError]{@link Bacon.EventStream#endOnError} and [EventStream.endOnError]{@link Bacon.EventStream#endOnError} returns a stream/property that ends immediately after first error. Bacon.js doesn't currently generate any Error events itself (except when converting errors using [Bacon.fromPromise]{@link Bacon.fromPromise}). Error events definitely would be generated by streams derived from IO sources such as AJAX calls. + * @example + * // In case you want to convert (some) value events into Error events, you may use `flatMap` like this: + * Bacon.fromArray([1, 2, 3, 4]).flatMap(x => { + * NOTE: had to explicitly specify the `` typing for `flatMap`. + * return x > 2 ? new Bacon.Error("too big") : x; + * }); + * + * // Conversely, if you want to convert some Error events into value events, you may use `flatMapError`: + * Bacon.fromArray([1, 2, 3, 4]).flatMapError(error => { + * let isNonCriticalError = error => Math.random() < .5, + * handleNonCriticalError = error => 42; + * return isNonCriticalError(error) ? handleNonCriticalError(error) : new Bacon.Error(error); + * }); + * + * // Note also that Bacon.js combinators do not catch errors that are thrown. Especially `map` doesn't do so. If you want to map things and wrap caught errors into Error events, you can do the following: + * Bacon.fromArray([1, 2, 3, 4]).flatMap(x => { + * let dangerousFunction = x => { + * throw new Error("dangerous function!"); + * }; + * try { + * return dangerousFunction(x); + * } catch (e) { + * return new Bacon.Error(e); + * } + * }); + */ + class Error extends Event { + /** + * @constructor + * @constructs Error + * @param {E} error + * */ + constructor(error:E); + + /** + * @property Error#error + * @description Returns the `error` associated with an [Error]{@link Bacon.Error} event. + * @returns {E} + */ + error:E; + } + + /** + * @class End + * @augments Bacon.Event + * @description An end-of-stream event of [EventStream]{@link Bacon.EventStream} or [Property]{@link Bacon.Property}. Call [Event.isEnd]{@link Bacon.Event#isEnd} to distinguish an End from other events. + * */ + class End extends Event { + /** + * @constructor + * @constructs Bacon.End + * */ + constructor(); + } + + /** + * @class Initial + * @augments Bacon.Event + * @description The initial (current) value of a [Property]{@link Bacon.Property}. Call [Event.isInitial]{@link Bacon.Event#isInitial} to distinguish from other events. Only sent immediately after subscription to a Property. + * */ + class Initial extends Event { + /** + * @constructor + * @constructs Bacon.Initial + * @param {A} value + * */ + constructor(value:A); + } + + /** + * @class Next + * @augments Bacon.Event + * @description Next value in an [EventStream]{@link Bacon.EventStream} or a [Property]{@link Bacon.Property}. Call [Event.isNext]{@link Bacon.Event#isNext} to distinguish a Next event from other events. + * */ + class Next extends Event { + /** + * @constructor + * @constructs Bacon.Next + * @param {A} value + * @example + * new Bacon.Next("value"); + * */ + constructor(value:A); + + /** + * @callback Next#constructor + * @returns {A} + */ + /** + * @constructor Next#constructor + * @constructs Bacon.Next + * @description This version is safe only when you know that the actual value in the stream is not a function. The idea in using a function `f` instead of a plain value is that the internals on Bacon.js take advantage of lazy evaluation by deferring the evaluations of values created by `map`, `combine`. + * @param {Next#constructor} f + * @example + * new Bacon.Next(() => "value"); + * */ + constructor(f:() => A); + } + + /** + * @callback Bacon.retry1~source + * @description Function that produces an [EventStream]{@link Bacon.EventStream}. + * @returns {EventStream} + */ + /** + * @callback Bacon.retry1~isRetryable + * @description Function returning `true` to continue retrying, `false` to stop. Defaults to `true`. The [Error]{@link Bacon.Error} that occurred is given as a parameter. For example, there is usually no reason to retry a 404 HTTP error, whereas a 500 or a timeout might work on the next attempt. + * @param {E} error + * @returns {boolean} + */ + /** + * @callback Bacon.retry1~delay + * @description Function that returns the time in milliseconds to wait before retrying. Defaults to `0`. The function is given a `context` object with the keys `error` (the [Error]{@link Bacon.Error} that occurred) and `retriesDone` (the number of retries already performed) to help determine the appropriate delay, e.g. for an incremental backoff. + * @param {Object} context + * @param {E} context.error [Error]{@link Bacon.Error} that occurred + * @param {number} context.retriesDone number of retries already performed + * @returns {number} + */ + /** + * @function Bacon.retry1 + * @description Is used to retry the call when there is an [Error]{@link Bacon.Error} event in the [EventStream]{@link Bacon.EventStream} produced by the `source` function. + * @param {Object} options + * @param {Bacon.retry1~source} options.source function that produces an [EventStream]{@link Bacon.EventStream} + * @param {number} options.retries number of times to retry the `source` function in addition to the initial attempt + * @param {Bacon.retry1~isRetryable} [options.isRetryable] function returning `true` to continue retrying, `false` to stop. Defaults to `true`. + * @param {Bacon.retry1~delay} [options.delay] - function that returns the time in milliseconds to wait before retrying. Defaults to `0`. + * @returns {EventStream} + */ + function retry(options:{ + source:() => EventStream; + retries:number; + isRetryable?:(error:E) => boolean; + delay?:(context:{error:E; retriesDone:number}) => number; + }):EventStream; + + /** + * @callback Bacon.retry1~source + * @description Function that produces an [Property]{@link Bacon.Property}. + * @returns {Property} + */ + /** + * @callback Bacon.retry1~isRetryable + * @description Function returning `true` to continue retrying, `false` to stop. Defaults to `true`. The [Error]{@link Bacon.Error} that occurred is given as a parameter. For example, there is usually no reason to retry a 404 HTTP error, whereas a 500 or a timeout might work on the next attempt. + * @param {E} error + * @returns {boolean} + */ + /** + * @callback Bacon.retry1~delay + * @description Function that returns the time in milliseconds to wait before retrying. Defaults to `0`. The function is given a `context` object with the keys `error` (the [Error]{@link Bacon.Error} that occurred) and `retriesDone` (the number of retries already performed) to help determine the appropriate delay, e.g. for an incremental backoff. + * @param {Object} context + * @param {E} context.error [Error]{@link Bacon.Error} that occurred + * @param {number} context.retriesDone number of retries already performed + * @returns {number} + */ + /** + * @function Bacon.retry1 + * @description Is used to retry the call when there is an [Error]{@link Bacon.Error} event in the [Property]{@link Bacon.Property} produced by the `source` function. + * @param {Object} options + * @param {Bacon.retry1~source} options.source function that produces an [Property]{@link Bacon.Property} + * @param {number} options.retries number of times to retry the `source` function in addition to the initial attempt + * @param {Bacon.retry1~isRetryable} [options.isRetryable] function returning `true` to continue retrying, `false` to stop. Defaults to `true`. + * @param {Bacon.retry1~delay} [options.delay] - function that returns the time in milliseconds to wait before retrying. Defaults to `0`. + * @returns {Property} + */ + function retry(options:{ + source:() => Property; + retries:number; + isRetryable?:(error:E) => boolean; + delay?:(context:{error:E; retriesDone:number}) => number; + }):Property; + + /** + * @callback Bacon.when1~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @method Bacon.when1 + * @description Creates an [EventStream]{@link Bacon.EventStream} from join-pattern system. + * @param {Observable[]} pattern1 + * @param {Bacon.when1~f1} f1 + * @returns {EventStream} + * @example + * { + * // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: + * let tick = Bacon.interval(1e2, 0), + * keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), + * handleTick = _ => `timestamp: NONE`, + * handleKeyEvent = timestamp => `timestamp: ${timestamp}`; + * Bacon.when( + * [tick, keyEvent], (_, timestamp) => handleKeyEvent(timestamp), + * [tick], handleTick + * ); + * // Order is important here. If the [tick] patterns had been written first, this would have been tried first, and preferred at each tick. + * } + * { + * // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: + * let a = Bacon.once("a"), + * b = Bacon.once("b"), + * c = Bacon.once("c"), + * f = (a, b, c) => `a = ${a}; b = ${b}; c = ${c}.`; + * Bacon.zipWith(f, a, b, c); + * Bacon.when([a, b, c], f); + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B):EventStream; + + /** + * @callback Bacon.when2~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.when2~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @method Bacon.when2 + * @description Creates an [EventStream]{@link Bacon.EventStream} from join-pattern system. + * @param {Observable[]} pattern1 + * @param {Bacon.when2~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.when2~f2} f2 + * @returns {EventStream} + * @example + * { + * // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: + * let tick = Bacon.interval(1e2, 0), + * keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), + * handleTick = _ => `timestamp: NONE`, + * handleKeyEvent = timestamp => `timestamp: ${timestamp}`; + * Bacon.when( + * [tick, keyEvent], (_, timestamp) => handleKeyEvent(timestamp), + * [tick], handleTick + * ); + * // Order is important here. If the [tick] patterns had been written first, this would have been tried first, and preferred at each tick. + * } + * { + * // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: + * let a = Bacon.once("a"), + * b = Bacon.once("b"), + * c = Bacon.once("c"), + * f = (a, b, c) => `a = ${a}; b = ${b}; c = ${c}.`; + * Bacon.zipWith(f, a, b, c); + * Bacon.when([a, b, c], f); + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B, pattern2:Observable[], f2:(...args:A2[]) => B):EventStream; + + /** + * @callback Bacon.when3~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.when3~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.when3~f3 + * @param {...A3} args + * @returns {B} + */ + /** + * @method Bacon.when3 + * @description Creates an [EventStream]{@link Bacon.EventStream} from join-pattern system. + * @param {Observable[]} pattern1 + * @param {Bacon.when3~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.when3~f2} f2 + * @param {Observable[]} pattern3 + * @param {Bacon.when3~f3} f3 + * @returns {EventStream} + * @example + * { + * // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: + * let tick = Bacon.interval(1e2, 0), + * keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), + * handleTick = _ => `timestamp: NONE`, + * handleKeyEvent = timestamp => `timestamp: ${timestamp}`; + * Bacon.when( + * [tick, keyEvent], (_, timestamp) => handleKeyEvent(timestamp), + * [tick], handleTick + * ); + * // Order is important here. If the [tick] patterns had been written first, this would have been tried first, and preferred at each tick. + * } + * { + * // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: + * let a = Bacon.once("a"), + * b = Bacon.once("b"), + * c = Bacon.once("c"), + * f = (a, b, c) => `a = ${a}; b = ${b}; c = ${c}.`; + * Bacon.zipWith(f, a, b, c); + * Bacon.when([a, b, c], f); + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B, pattern2:Observable[], f2:(...args:A2[]) => B, pattern3:Observable[], f3:(...args:A3[]) => B):EventStream; + + /** + * @callback Bacon.when4~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.when4~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.when4~f3 + * @param {...A3} args + * @returns {B} + */ + /** + * @callback Bacon.when4~f4 + * @param {...A4} args + * @returns {B} + */ + /** + * @method Bacon.when4 + * @description Creates an [EventStream]{@link Bacon.EventStream} from join-pattern system. + * @param {Observable[]} pattern1 + * @param {Bacon.when4~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.when4~f2} f2 + * @param {Observable[]} pattern3 + * @param {Bacon.when4~f3} f3 + * @param {Observable[]} pattern4 + * @param {Bacon.when4~f4} f4 + * @returns {EventStream} + * @example + * { + * // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: + * let tick = Bacon.interval(1e2, 0), + * keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), + * handleTick = _ => `timestamp: NONE`, + * handleKeyEvent = timestamp => `timestamp: ${timestamp}`; + * Bacon.when( + * [tick, keyEvent], (_, timestamp) => handleKeyEvent(timestamp), + * [tick], handleTick + * ); + * // Order is important here. If the [tick] patterns had been written first, this would have been tried first, and preferred at each tick. + * } + * { + * // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: + * let a = Bacon.once("a"), + * b = Bacon.once("b"), + * c = Bacon.once("c"), + * f = (a, b, c) => `a = ${a}; b = ${b}; c = ${c}.`; + * Bacon.zipWith(f, a, b, c); + * Bacon.when([a, b, c], f); + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B, pattern2:Observable[], f2:(...args:A2[]) => B, pattern3:Observable[], f3:(...args:A3[]) => B, pattern4:Observable[], f4:(...args:A4[]) => B):EventStream; + + /** + * @callback Bacon.when5~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.when5~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.when5~f3 + * @param {...A3} args + * @returns {B} + */ + /** + * @callback Bacon.when5~f4 + * @param {...A4} args + * @returns {B} + */ + /** + * @callback Bacon.when5~f5 + * @param {...A5} args + * @returns {B} + */ + /** + * @method Bacon.when5 + * @description Creates an [EventStream]{@link Bacon.EventStream} from join-pattern system. + * @param {Observable[]} pattern1 + * @param {Bacon.when5~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.when5~f2} f2 + * @param {Observable[]} pattern3 + * @param {Bacon.when5~f3} f3 + * @param {Observable[]} pattern4 + * @param {Bacon.when5~f4} f4 + * @param {Observable[]} pattern5 + * @param {Bacon.when5~f5} f5 + * @returns {EventStream} + * @example + * { + * // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: + * let tick = Bacon.interval(1e2, 0), + * keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), + * handleTick = _ => `timestamp: NONE`, + * handleKeyEvent = timestamp => `timestamp: ${timestamp}`; + * Bacon.when( + * [tick, keyEvent], (_, timestamp) => handleKeyEvent(timestamp), + * [tick], handleTick + * ); + * // Order is important here. If the [tick] patterns had been written first, this would have been tried first, and preferred at each tick. + * } + * { + * // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: + * let a = Bacon.once("a"), + * b = Bacon.once("b"), + * c = Bacon.once("c"), + * f = (a, b, c) => `a = ${a}; b = ${b}; c = ${c}.`; + * Bacon.zipWith(f, a, b, c); + * Bacon.when([a, b, c], f); + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B, pattern2:Observable[], f2:(...args:A2[]) => B, pattern3:Observable[], f3:(...args:A3[]) => B, pattern4:Observable[], f4:(...args:A4[]) => B, pattern5:Observable[], f5:(...args:A5[]) => B):EventStream; + + /** + * @callback Bacon.update1~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @method Bacon.update1 + * @description Creates an [Property]{@link Bacon.EventStream} from an `initial` value and a join-pattern system. + * @param {B} initial + * @param {Observable[]} pattern1 + * @param {Bacon.update1~f1} f1 + * @returns {EventStream} + * @example + * { + * // The inputs to `Bacon.update` are defined like this: + * let initial = 0, + * x = Bacon.interval(1e3, 1), + * y = Bacon.interval(2e3, 1), + * z = Bacon.interval(1.5e3, 1); + * // NOTE: had to explicitly specify the typing for `previous:number` + * Bacon.update(initial, + * [x, y, z], (previous:number, x, y, z) => previous + x + y + z, + * [x, y], (previous:number, x, y) => previous + x + y + z + * ); + * // As input, each function above will get the previous value of the `result` Property, along with values from the listed Observables. The value returned by the function will be used as the next value of `result`. Just like in `Bacon.when`, only EventStreams will trigger an update, while Properties will be just sampled. So, if you list a single EventStream and several Properties, the value will be updated only when an event occurs in the EventStream. + * } + * { + * // Here's a simple gaming example: + * let scoreMultiplier = Bacon.constant(1), + * hitUfo = new Bacon.Bus(), + * hitMotherShip = new Bacon.Bus(), + * score = Bacon.update(0, + * [hitUfo, scoreMultiplier], (score, _, multiplier:number) => score + 100 * multiplier, + * [hitMotherShip], (score, _) => score + 2000 + * ); + * // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. + * } + */ + function update(initial:B, pattern1:Observable[], f1:(initial:B, ...args:A1[]) => C):Property; + + /** + * @callback Bacon.update2~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update2~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @method Bacon.update2 + * @description Creates an [Property]{@link Bacon.EventStream} from an `initial` value and a join-pattern system. + * @param {B} initial + * @param {Observable[]} pattern1 + * @param {Bacon.update2~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.update2~f2} f2 + * @returns {EventStream} + * @example + * { + * // The inputs to `Bacon.update` are defined like this: + * let initial = 0, + * x = Bacon.interval(1e3, 1), + * y = Bacon.interval(2e3, 1), + * z = Bacon.interval(1.5e3, 1); + * // NOTE: had to explicitly specify the typing for `previous:number` + * Bacon.update(initial, + * [x, y, z], (previous:number, x, y, z) => previous + x + y + z, + * [x, y], (previous:number, x, y) => previous + x + y + z + * ); + * // As input, each function above will get the previous value of the `result` Property, along with values from the listed Observables. The value returned by the function will be used as the next value of `result`. Just like in `Bacon.when`, only EventStreams will trigger an update, while Properties will be just sampled. So, if you list a single EventStream and several Properties, the value will be updated only when an event occurs in the EventStream. + * } + * { + * // Here's a simple gaming example: + * let scoreMultiplier = Bacon.constant(1), + * hitUfo = new Bacon.Bus(), + * hitMotherShip = new Bacon.Bus(), + * score = Bacon.update(0, + * [hitUfo, scoreMultiplier], (score, _, multiplier:number) => score + 100 * multiplier, + * [hitMotherShip], (score, _) => score + 2000 + * ); + * // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. + * } + */ + function update(initial:B, pattern1:Observable[], f1:(initial:B, ...args:A1[]) => C, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => C):Property; + + /** + * @callback Bacon.update3~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update3~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.update3~f3 + * @param {...A3} args + * @returns {B} + */ + /** + * @method Bacon.update3 + * @description Creates an [Property]{@link Bacon.EventStream} from an `initial` value and a join-pattern system. + * @param {B} initial + * @param {Observable[]} pattern1 + * @param {Bacon.update3~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.update3~f2} f2 + * @param {Observable[]} pattern3 + * @param {Bacon.update3~f3} f3 + * @returns {EventStream} + * @example + * { + * // The inputs to `Bacon.update` are defined like this: + * let initial = 0, + * x = Bacon.interval(1e3, 1), + * y = Bacon.interval(2e3, 1), + * z = Bacon.interval(1.5e3, 1); + * // NOTE: had to explicitly specify the typing for `previous:number` + * Bacon.update(initial, + * [x, y, z], (previous:number, x, y, z) => previous + x + y + z, + * [x, y], (previous:number, x, y) => previous + x + y + z + * ); + * // As input, each function above will get the previous value of the `result` Property, along with values from the listed Observables. The value returned by the function will be used as the next value of `result`. Just like in `Bacon.when`, only EventStreams will trigger an update, while Properties will be just sampled. So, if you list a single EventStream and several Properties, the value will be updated only when an event occurs in the EventStream. + * } + * { + * // Here's a simple gaming example: + * let scoreMultiplier = Bacon.constant(1), + * hitUfo = new Bacon.Bus(), + * hitMotherShip = new Bacon.Bus(), + * score = Bacon.update(0, + * [hitUfo, scoreMultiplier], (score, _, multiplier:number) => score + 100 * multiplier, + * [hitMotherShip], (score, _) => score + 2000 + * ); + * // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. + * } + */ + function update(initial:B, pattern1:Observable[], f1:(initial:B, ...args:A1[]) => C, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => C, pattern3:Observable[], f3:(initial:B, ...args:A3[]) => C):Property; + + /** + * @callback Bacon.update4~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update4~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.update4~f3 + * @param {...A3} args + * @returns {B} + */ + /** + * @callback Bacon.update4~f4 + * @param {...A4} args + * @returns {B} + */ + /** + * @method Bacon.update4 + * @description Creates an [Property]{@link Bacon.EventStream} from an `initial` value and a join-pattern system. + * @param {B} initial + * @param {Observable[]} pattern1 + * @param {Bacon.update4~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.update4~f2} f2 + * @param {Observable[]} pattern3 + * @param {Bacon.update4~f3} f3 + * @param {Observable[]} pattern4 + * @param {Bacon.update4~f4} f4 + * @returns {EventStream} + * @example + * { + * // The inputs to `Bacon.update` are defined like this: + * let initial = 0, + * x = Bacon.interval(1e3, 1), + * y = Bacon.interval(2e3, 1), + * z = Bacon.interval(1.5e3, 1); + * // NOTE: had to explicitly specify the typing for `previous:number` + * Bacon.update(initial, + * [x, y, z], (previous:number, x, y, z) => previous + x + y + z, + * [x, y], (previous:number, x, y) => previous + x + y + z + * ); + * // As input, each function above will get the previous value of the `result` Property, along with values from the listed Observables. The value returned by the function will be used as the next value of `result`. Just like in `Bacon.when`, only EventStreams will trigger an update, while Properties will be just sampled. So, if you list a single EventStream and several Properties, the value will be updated only when an event occurs in the EventStream. + * } + * { + * // Here's a simple gaming example: + * let scoreMultiplier = Bacon.constant(1), + * hitUfo = new Bacon.Bus(), + * hitMotherShip = new Bacon.Bus(), + * score = Bacon.update(0, + * [hitUfo, scoreMultiplier], (score, _, multiplier:number) => score + 100 * multiplier, + * [hitMotherShip], (score, _) => score + 2000 + * ); + * // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. + * } + */ + function update(initial:B, pattern1:Observable[], f1:(initial:B, ...args:A1[]) => C, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => C, pattern3:Observable[], f3:(initial:B, ...args:A3[]) => C, pattern4:Observable[], f4:(initial:B, ...args:A4[]) => C):Property; + + /** + * @callback Bacon.update5~f1 + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f2 + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f3 + * @param {...A3} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f4 + * @param {...A4} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f5 + * @param {...A5} args + * @returns {B} + */ + /** + * @method Bacon.update5 + * @description Creates an [Property]{@link Bacon.Property} from an `initial` value and a join-pattern system. + * @param {B} initial + * @param {Observable[]} pattern1 + * @param {Bacon.update5~f1} f1 + * @param {Observable[]} pattern2 + * @param {Bacon.update5~f2} f2 + * @param {Observable[]} pattern3 + * @param {Bacon.update5~f3} f3 + * @param {Observable[]} pattern4 + * @param {Bacon.update5~f4} f4 + * @param {Observable[]} pattern5 + * @param {Bacon.update5~f5} f5 + * @returns {EventStream} + * @example + * { + * // The inputs to `Bacon.update` are defined like this: + * let initial = 0, + * x = Bacon.interval(1e3, 1), + * y = Bacon.interval(2e3, 1), + * z = Bacon.interval(1.5e3, 1); + * // NOTE: had to explicitly specify the typing for `previous:number` + * Bacon.update(initial, + * [x, y, z], (previous:number, x, y, z) => previous + x + y + z, + * [x, y], (previous:number, x, y) => previous + x + y + z + * ); + * // As input, each function above will get the previous value of the `result` Property, along with values from the listed Observables. The value returned by the function will be used as the next value of `result`. Just like in `Bacon.when`, only EventStreams will trigger an update, while Properties will be just sampled. So, if you list a single EventStream and several Properties, the value will be updated only when an event occurs in the EventStream. + * } + * { + * // Here's a simple gaming example: + * let scoreMultiplier = Bacon.constant(1), + * hitUfo = new Bacon.Bus(), + * hitMotherShip = new Bacon.Bus(), + * score = Bacon.update(0, + * [hitUfo, scoreMultiplier], (score, _, multiplier:number) => score + 100 * multiplier, + * [hitMotherShip], (score, _) => score + 2000 + * ); + * // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. + * } + */ + function update(initial:B, pattern1:Observable[], f1:(initial:B, ...args:A1[]) => C, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => C, pattern3:Observable[], f3:(initial:B, ...args:A3[]) => C, pattern4:Observable[], f4:(initial:B, ...args:A4[]) => C, pattern5:Observable[], f5:(initial:B, ...args:A5[]) => C):Property; +} + +declare module "baconjs" { + export = Bacon; +} \ No newline at end of file From cd2ff6b40edecb426cc17b55636fa379fc3f05c0 Mon Sep 17 00:00:00 2001 From: matsievskyav Date: Mon, 20 Jul 2015 07:33:53 +0300 Subject: [PATCH 11/17] baconjs [http://baconjs.github.io/] definition --- baconjs/baconjs-tests.ts | 46 ++++++++++++++++++++-------------------- baconjs/baconjs.d.ts | 6 +++--- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/baconjs/baconjs-tests.ts b/baconjs/baconjs-tests.ts index 4b3e8869a..79eef483c 100644 --- a/baconjs/baconjs-tests.ts +++ b/baconjs/baconjs-tests.ts @@ -42,7 +42,7 @@ function CreatingStreams() { }, Bacon.constant("bacon"), "rules").log(); { - let fs = require("fs"), + var fs = require("fs"), read = Bacon.fromNodeCallback(fs.readFile, "input.txt"); read.onError(error => { console.log("Reading failed: " + error); @@ -69,7 +69,7 @@ function CreatingStreams() { }).log(); { - let stream = Bacon.fromBinder(sink => { + var stream = Bacon.fromBinder(sink => { sink("first value"); sink([new Bacon.Next("2nd"), new Bacon.Next("3rd")]); sink(new Bacon.Next(() => { @@ -104,12 +104,12 @@ function CommonMethodsInEventStreamsAndProperties() { Bacon.fromArray([1, 2, 3, 4, 5]).slidingWindow(2, 2); { - let x = Bacon.fromArray([1, 2]), y = Bacon.fromArray([3, 4]); + var x = Bacon.fromArray([1, 2]), y = Bacon.fromArray([3, 4]); x.zip(y, (x, y) => x + y); } { - let stream = Bacon.fromArray([1, 2]); + var stream = Bacon.fromArray([1, 2]); stream.log("New event in myStream"); stream.log(); } @@ -128,7 +128,7 @@ function CommonMethodsInEventStreamsAndProperties() { }); { - let property = Bacon.fromArray([1, 2, 3]).toProperty(), + var property = Bacon.fromArray([1, 2, 3]).toProperty(), who = Bacon.fromArray(["A", "B", "C"]).toProperty(); property.decode({1: "mike", 2: who}); @@ -137,7 +137,7 @@ function CommonMethodsInEventStreamsAndProperties() { { // This is handy for keeping track whether we are currently awaiting an AJAX response: - let ajaxRequest = >{}, + var ajaxRequest = >{}, ajaxResponse = >{}, showAjaxIndicator = ajaxRequest.awaiting(ajaxResponse); } @@ -152,7 +152,7 @@ function CommonMethodsInEventStreamsAndProperties() { }); { - let src = Bacon.once(1), + var src = Bacon.once(1), obs = src.map(x => -x); console.log(obs.toString()); // > "Bacon.once(1).map(function)" @@ -162,7 +162,7 @@ function CommonMethodsInEventStreamsAndProperties() { { // Calculator for grouped consecutive values until group is cancelled: - let events = [ + var events = [ {id: 1, type: "add", val: 3}, {id: 2, type: "add", val: -1}, {id: 1, type: "add", val: 2}, @@ -175,7 +175,7 @@ function CommonMethodsInEventStreamsAndProperties() { ], keyF = (event:{id:number}) => event.id, limitF = (groupedStream:Bacon.EventStream) => { - let cancel = groupedStream.filter(x => x.type === "cancel").take(1), + var cancel = groupedStream.filter(x => x.type === "cancel").take(1), adds = groupedStream.filter(x => x.type === "add"); return adds.takeUntil(cancel).map(x => x.val); }; @@ -201,7 +201,7 @@ function EventStream() { // Here's an equivalent to `stream.bufferWithTime(10)`: { - let stream = Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]); + var stream = Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]); stream.bufferWithTime(f => { setTimeout(f, 10); }); @@ -216,7 +216,7 @@ function Property() { Bacon.interval(1e1, 0).toProperty().last(); { - let property = Bacon.fromArray([1, 2, 3, 4, 5]).toProperty(); + var property = Bacon.fromArray([1, 2, 3, 4, 5]).toProperty(); // If you want to assign your Property to the "disabled" attribute of a JQuery object, you can do this: property.assign($("#my-button"), "attr", "disabled"); @@ -230,7 +230,7 @@ function Property() { function CombiningMultipleStreamsAndProperties() { { - let property = Bacon.constant(1), + var property = Bacon.constant(1), stream = Bacon.once(2), constant = 3; Bacon.combineAsArray(property, stream, constant) @@ -239,7 +239,7 @@ function CombiningMultipleStreamsAndProperties() { { // To calculate the current sum of three numeric Properties, you can do: - let property = Bacon.constant(1), + var property = Bacon.constant(1), stream = Bacon.once(2), constant = 3; // NOTE: had to explicitly specify the typing for `x:number, y:number, z:number` @@ -248,7 +248,7 @@ function CombiningMultipleStreamsAndProperties() { { // Assuming you've got streams or properties named `password`, `username`, `firstname` and `lastname`, you can do: - let password = Bacon.constant("easy"), + var password = Bacon.constant("easy"), username = Bacon.constant("juha"), firstname = Bacon.constant("juha"), lastname = Bacon.constant("paananen"), @@ -277,7 +277,7 @@ function CombiningMultipleStreamsAndProperties() { } { - let x = Bacon.fromArray([1, 2, 3]), + var x = Bacon.fromArray([1, 2, 3]), y = Bacon.fromArray([10, 20, 30]), z = Bacon.fromArray([100, 200, 300]); Bacon.zipAsArray(x, y, z) @@ -305,14 +305,14 @@ function Errors() { // Conversely, if you want to convert some Error events into value events, you may use `flatMapError`: Bacon.fromArray([1, 2, 3, 4]).flatMapError(error => { - let isNonCriticalError = (error:string) => Math.random() < .5, + var isNonCriticalError = (error:string) => Math.random() < .5, handleNonCriticalError = (error:string) => 42; return isNonCriticalError(error) ? handleNonCriticalError(error) : new Bacon.Error(error); }); // Note also that Bacon.js combinators do not catch errors that are thrown. Especially `map` doesn't do so. If you want to map things and wrap caught errors into Error events, you can do the following: Bacon.fromArray([1, 2, 3, 4]).flatMap(x => { - let dangerousFunction = (x:number) => { + var dangerousFunction = (x:number) => { throw new Error("dangerous function!"); }; try { @@ -324,7 +324,7 @@ function Errors() { Bacon.once("https://baconjs.github.io/").flatMap(url => { // `ajaxCall` gives `Error`s on network or server `Error`s. - let ajaxCall = (url:string) => { + var ajaxCall = (url:string) => { return Bacon.fromPromise($.ajax(url)); }; return Bacon.retry({ @@ -339,7 +339,7 @@ function Errors() { function JoinPatterns() { { // Consider implementing a game with discrete time ticks. We want to handle key-events synchronized on tick-events, with at most one key event handled per tick. If there are no key events, we want to just process a tick: - let tick = Bacon.interval(1e2, 0), + var tick = Bacon.interval(1e2, 0), keyEvent = Bacon.fromEvent(document.body, "click", _ => Date.now()), handleTick = (_:number) => `timestamp: NONE`, handleKeyEvent = (timestamp:number) => `timestamp: ${timestamp}`; @@ -352,7 +352,7 @@ function JoinPatterns() { { // Join patterns are indeed a generalization of `zip`, and `zip` is equivalent to a single-rule join pattern. The following `Observable`s have the same output: - let a = Bacon.once("a"), + var a = Bacon.once("a"), b = Bacon.once("b"), c = Bacon.once("c"), f = (a:string, b:string, c:string) => `a = ${a}; b = ${b}; c = ${c}.`; @@ -361,7 +361,7 @@ function JoinPatterns() { } { // The inputs to `Bacon.update` are defined like this: - let initial = 0, + var initial = 0, x = Bacon.interval(1e3, 1), y = Bacon.interval(2e3, 1), z = Bacon.interval(1.5e3, 1); @@ -374,7 +374,7 @@ function JoinPatterns() { } { // Here's a simple gaming example: - let scoreMultiplier = Bacon.constant(1), + var scoreMultiplier = Bacon.constant(1), hitUfo = new Bacon.Bus(), hitMotherShip = new Bacon.Bus(), score = Bacon.update(0, @@ -383,4 +383,4 @@ function JoinPatterns() { ); // In the example, the `score` property is updated when either `hitUfo` or `hitMotherShip` occur. The `scoreMultiplier` Property is sampled to take multiplier into account when `hitUfo` occurs. } -} \ No newline at end of file +} diff --git a/baconjs/baconjs.d.ts b/baconjs/baconjs.d.ts index 49430f0bd..0e3f77c12 100644 --- a/baconjs/baconjs.d.ts +++ b/baconjs/baconjs.d.ts @@ -389,7 +389,7 @@ declare module Bacon { * @constant * @description The opaque value `sink` function may return. See [Bacon.fromBinder]{@link Bacon.fromBinder}. */ - const more:More; + var more:More; /** * @interface @@ -402,7 +402,7 @@ declare module Bacon { * @constant * @description The opaque value `sink` function may return. See [Bacon.fromBinder]{@link Bacon.fromBinder}. */ - const noMore:NoMore; + var noMore:NoMore; /** * @class Observable @@ -2743,4 +2743,4 @@ declare module Bacon { declare module "baconjs" { export = Bacon; -} \ No newline at end of file +} From bde9f6cbdc8ec26e543412ed226d5620ed4f5974 Mon Sep 17 00:00:00 2001 From: matsievskyav Date: Mon, 20 Jul 2015 07:41:18 +0300 Subject: [PATCH 12/17] baconjs [http://baconjs.github.io/] definition --- baconjs/baconjs-tests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baconjs/baconjs-tests.ts b/baconjs/baconjs-tests.ts index 79eef483c..e542ef1c9 100644 --- a/baconjs/baconjs-tests.ts +++ b/baconjs/baconjs-tests.ts @@ -330,7 +330,7 @@ function Errors() { return Bacon.retry({ source: () => ajaxCall(url), retries: 5, - isRetryable: error => error.status !== 404, + isRetryable: (error:JQueryXHR) => error.status !== 404, delay: context => 100 // Just use the same delay always }); }); From 523447e2fa27f4611b718aa4c240bf39ed51ebec Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 20 Jul 2015 17:07:03 +0800 Subject: [PATCH 13/17] Adds connect-modrewrite library --- connect-modrewrite/connect-modrewrite.d.ts | 8 ++++++++ connect-modrewrite/connect-modrewrite.ts | 14 ++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 connect-modrewrite/connect-modrewrite.d.ts create mode 100644 connect-modrewrite/connect-modrewrite.ts diff --git a/connect-modrewrite/connect-modrewrite.d.ts b/connect-modrewrite/connect-modrewrite.d.ts new file mode 100644 index 000000000..0ae3e7175 --- /dev/null +++ b/connect-modrewrite/connect-modrewrite.d.ts @@ -0,0 +1,8 @@ + +/// + +declare module 'connect-modrewrite' { + import express = require('express'); + function modrewrite(rewrites: string[]): express.RequestHandler; + export = modrewrite; +} \ No newline at end of file diff --git a/connect-modrewrite/connect-modrewrite.ts b/connect-modrewrite/connect-modrewrite.ts new file mode 100644 index 000000000..7cdea4a7f --- /dev/null +++ b/connect-modrewrite/connect-modrewrite.ts @@ -0,0 +1,14 @@ + +/// +/// + +import modRewrite = require('connect-modrewrite'); +import express = require('express'); + +var app = express(); + +app.use(modRewrite([ + '^/test$ /index.html', + '^/test/\\d*$ /index.html [L]', + '^/test/\\d*/\\d*$ /flag.html [L]', +])); \ No newline at end of file From 609e1adfca6e777989ef18357fbc5754001f72ee Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 20 Jul 2015 17:34:47 +0800 Subject: [PATCH 14/17] Fixes file header issue --- .../{connect-modrewrite.ts => connect-modrewrite-test.ts} | 1 - connect-modrewrite/connect-modrewrite.d.ts | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) rename connect-modrewrite/{connect-modrewrite.ts => connect-modrewrite-test.ts} (99%) diff --git a/connect-modrewrite/connect-modrewrite.ts b/connect-modrewrite/connect-modrewrite-test.ts similarity index 99% rename from connect-modrewrite/connect-modrewrite.ts rename to connect-modrewrite/connect-modrewrite-test.ts index 7cdea4a7f..177cea497 100644 --- a/connect-modrewrite/connect-modrewrite.ts +++ b/connect-modrewrite/connect-modrewrite-test.ts @@ -1,4 +1,3 @@ - /// /// diff --git a/connect-modrewrite/connect-modrewrite.d.ts b/connect-modrewrite/connect-modrewrite.d.ts index 0ae3e7175..56011c6df 100644 --- a/connect-modrewrite/connect-modrewrite.d.ts +++ b/connect-modrewrite/connect-modrewrite.d.ts @@ -1,5 +1,9 @@ +// Type definitions for connect-modrewrite +// Project: https://github.com/tinganho/connect-modrewrite +// Definitions by: Tingan Ho +// Definitions: https://github.com/borisyankov/DefinitelyTyped -/// +/// declare module 'connect-modrewrite' { import express = require('express'); From 2387f99fe9949b0fe2b9d43fceccf237afa63888 Mon Sep 17 00:00:00 2001 From: Tingan Ho Date: Mon, 20 Jul 2015 17:49:23 +0800 Subject: [PATCH 15/17] Renamed test file --- .../{connect-modrewrite-test.ts => connect-modrewrite-tests.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename connect-modrewrite/{connect-modrewrite-test.ts => connect-modrewrite-tests.ts} (100%) diff --git a/connect-modrewrite/connect-modrewrite-test.ts b/connect-modrewrite/connect-modrewrite-tests.ts similarity index 100% rename from connect-modrewrite/connect-modrewrite-test.ts rename to connect-modrewrite/connect-modrewrite-tests.ts From dd9bc1f12e528198e5bbebb104cf77b006aba956 Mon Sep 17 00:00:00 2001 From: Sam Saint-Pettersen Date: Mon, 20 Jul 2015 11:11:19 +0100 Subject: [PATCH 16/17] Type definitions and tests for git-config --- git-config/git-config-async-tests.ts | 11 +++++++++++ git-config/git-config-async.d.ts | 9 +++++++++ git-config/git-config-tests.ts | 9 +++++++++ git-config/git-config.d.ts | 8 ++++++++ 4 files changed, 37 insertions(+) create mode 100644 git-config/git-config-async-tests.ts create mode 100644 git-config/git-config-async.d.ts create mode 100644 git-config/git-config-tests.ts create mode 100644 git-config/git-config.d.ts diff --git a/git-config/git-config-async-tests.ts b/git-config/git-config-async-tests.ts new file mode 100644 index 000000000..66b77fbe0 --- /dev/null +++ b/git-config/git-config-async-tests.ts @@ -0,0 +1,11 @@ +/// + +import gitConfig = require('git-config'); + +gitConfig(function(err: any, config: Object) { + console.log(JSON.stringify(config)); +}); + +gitConfig('gitconfig', function(err: any, config: Object) { + console.log(JSON.stringify(config)); +}); diff --git a/git-config/git-config-async.d.ts b/git-config/git-config-async.d.ts new file mode 100644 index 000000000..34ef3a17d --- /dev/null +++ b/git-config/git-config-async.d.ts @@ -0,0 +1,9 @@ +// Type definitions for git-config +// Project: https://github.com/eugeneware/git-config +// Definitions by: Sam Saint-Pettersen +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "git-config" { + function gitConfig(gitFile_or_cb: any, cb?: any): void; // Asynchronous version. + export = gitConfig; +} diff --git a/git-config/git-config-tests.ts b/git-config/git-config-tests.ts new file mode 100644 index 000000000..9d46c5139 --- /dev/null +++ b/git-config/git-config-tests.ts @@ -0,0 +1,9 @@ +/// + +import gitConfig = require('git-config'); + +var config: Object = gitConfig.sync(); // => Object if .gitconfig exists. +console.log(JSON.stringify(config)); + +config = gitConfig.sync('gitconfig'); // => Object as gitconfig definitely exists. +console.log(JSON.stringify(config)); diff --git a/git-config/git-config.d.ts b/git-config/git-config.d.ts new file mode 100644 index 000000000..0db2f294b --- /dev/null +++ b/git-config/git-config.d.ts @@ -0,0 +1,8 @@ +// Type definitions for git-config +// Project: https://github.com/eugeneware/git-config +// Definitions by: Sam Saint-Pettersen +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "git-config" { + export function sync(gitFile?: string): Object; // Synchronous version. +} From 3ac0cbdf5dcc527bcd78ef44a83b05a40ead4527 Mon Sep 17 00:00:00 2001 From: Sam Saint-Pettersen Date: Mon, 20 Jul 2015 11:22:39 +0100 Subject: [PATCH 17/17] Type definitions and tests for git-config --- git-config/git-config-async-tests.ts | 11 ----------- git-config/git-config-async.d.ts | 9 --------- git-config/git-config-tests.ts | 4 ++-- git-config/gitconfig | 5 +++++ 4 files changed, 7 insertions(+), 22 deletions(-) delete mode 100644 git-config/git-config-async-tests.ts delete mode 100644 git-config/git-config-async.d.ts create mode 100644 git-config/gitconfig diff --git a/git-config/git-config-async-tests.ts b/git-config/git-config-async-tests.ts deleted file mode 100644 index 66b77fbe0..000000000 --- a/git-config/git-config-async-tests.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -import gitConfig = require('git-config'); - -gitConfig(function(err: any, config: Object) { - console.log(JSON.stringify(config)); -}); - -gitConfig('gitconfig', function(err: any, config: Object) { - console.log(JSON.stringify(config)); -}); diff --git a/git-config/git-config-async.d.ts b/git-config/git-config-async.d.ts deleted file mode 100644 index 34ef3a17d..000000000 --- a/git-config/git-config-async.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Type definitions for git-config -// Project: https://github.com/eugeneware/git-config -// Definitions by: Sam Saint-Pettersen -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module "git-config" { - function gitConfig(gitFile_or_cb: any, cb?: any): void; // Asynchronous version. - export = gitConfig; -} diff --git a/git-config/git-config-tests.ts b/git-config/git-config-tests.ts index 9d46c5139..800597a5a 100644 --- a/git-config/git-config-tests.ts +++ b/git-config/git-config-tests.ts @@ -2,8 +2,8 @@ import gitConfig = require('git-config'); -var config: Object = gitConfig.sync(); // => Object if .gitconfig exists. +var config: Object = gitConfig.sync(); console.log(JSON.stringify(config)); -config = gitConfig.sync('gitconfig'); // => Object as gitconfig definitely exists. +config = gitConfig.sync('gitconfig'); console.log(JSON.stringify(config)); diff --git a/git-config/gitconfig b/git-config/gitconfig new file mode 100644 index 000000000..0ee61d5b1 --- /dev/null +++ b/git-config/gitconfig @@ -0,0 +1,5 @@ +[user] + name = A Git User + email = git.user@domain.xyz +[push] + default = simple