diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1df2749f4d..938c816189 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -34,6 +34,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](angular-wizard/angular-wizard.d.ts) [Angular Wizard](https://github.com/mgonto/angular-wizard) by [Marko Jurisic](https://github.com/mjurisic) * [:link:](angular-bootstrap-lightbox/angular-bootstrap-lightbox.d.ts) [angular-bootstrap-lightbox](https://github.com/compact/angular-bootstrap-lightbox) by [Roland Zwaga](https://github.com/rolandzwaga) * [:link:](angular-dynamic-locale/angular-dynamic-locale.d.ts) [angular-dynamic-locale](https://github.com/lgalfaso/angular-dynamic-locale) by [Stephen Lautier](https://github.com/stephenlautier) +* [:link:](angular-formly/angular-formly.d.ts) [angular-formly](https://github.com/formly-js/angular-formly) by [Scott Hatcher](https://github.com/scatcher) * [:link:](angular-hotkeys/angular-hotkeys.d.ts) [angular-hotkeys](https://github.com/chieffancypants/angular-hotkeys) by [Jason Zhao](https://github.com/jlz27), [Stefan Steinhart](https://github.com/reppners) * [:link:](angular-http-auth/angular-http-auth.d.ts) [angular-http-auth](https://github.com/witoldsz/angular-http-auth) by [vvakame](https://github.com/vvakame) * [:link:](angular-jwt/angular-jwt.d.ts) [angular-jwt](https://github.com/auth0/angular-jwt) by [Reto Rezzonico](https://github.com/rerezz) @@ -50,6 +51,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](rx-angular/rx.angular.d.ts) [angularjs extensions to rxjs](http://reactivex.io) by [Mick Delaney](https://github.com/mickdelaney) * [:link:](angularjs-toaster/angularjs-toaster.d.ts) [angularjs-toaster](https://github.com/jirikavi/AngularJS-Toaster) by [Ben Tesser](https://github.com/btesser) * [:link:](angularLocalStorage/angularLocalStorage.d.ts) [AngularLocalStorage](https://github.com/agrublev/angularLocalStorage) by [Horiuchi_H](https://github.com/horiuchi) +* [:link:](angulartics/angulartics.d.ts) [Angulartics](http://luisfarzati.github.io/angulartics) by [Steven Fan](https://github.com/stevenfan) * [:link:](animation-frame/animation-frame.d.ts) [animation-frame](https://github.com/kof/animation-frame) by [Qinfeng Chen](https://github.com/qinfchen) * [:link:](ansi-styles/ansi-styles.d.ts) [ansi-styles](https://github.com/sindresorhus/ansi-styles) by [bryn austin bellomy](https://github.com/brynbellomy) * [:link:](ansicolors/ansicolors.d.ts) [ansicolors](https://github.com/thlorenz/ansicolors) by [rogierschouten](https://github.com/rogierschouten) @@ -89,7 +91,9 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](backbone.paginator/backbone.paginator.d.ts) [backbone.paginator](https://github.com/backbone-paginator/backbone.paginator) by [Nyamazing](https://github.com/Nyamazing) * [:link:](backbone.radio/backbone.radio.d.ts) [Backbone.Radio](https://github.com/marionettejs/backbone.radio) by [Peter Palotas](https://github.com/alphaleonis) * [:link:](backgrid/backgrid.d.ts) [Backgrid](http://backgridjs.com) by [Jeremy Lujan](https://github.com/jlujan) +* [:link:](baconjs/baconjs.d.ts) [Bacon.js](https://baconjs.github.io) by [Alexander Matsievsky](https://github.com/alexander-matsievsky) * [:link:](bardjs/bardjs.d.ts) [bardjs](https://github.com/wardbell/bardjs) by [Andrew Archibald](https://github.com/TepigMC) +* [:link:](batch-stream/batch-stream.d.ts) [batch-stream](https://github.com/segmentio/batch-stream) by [Nicholas Penree](http://github.com/drudge) * [:link:](bcrypt/bcrypt.d.ts) [bcrypt](https://www.npmjs.org/package/bcrypt) by [Peter Harris](https://github.com/codeanimal) * [:link:](bgiframe/typescript.bgiframe.d.ts) [bgiframe](https://github.com/sumegizoltan/BgiFrame) by [Zoltan Sumegi](https://github.com/sumegizoltan) * [:link:](big.js/big.js.d.ts) [big.js](https://github.com/MikeMcl/big.js) by [Steve Ognibene](https://github.com/nycdotnet) @@ -110,8 +114,8 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](bootstrap-slider/bootstrap-slider.d.ts) [bootstrap-slider.js](https://github.com/seiyria/bootstrap-slider) by [Daniel Beckwith](https://github.com/dbeckwith) * [:link:](bootstrap.datepicker/bootstrap.datepicker.d.ts) [bootstrap.datepicker](https://github.com/eternicode/bootstrap-datepicker) by [Boris Yankov](https://github.com/borisyankov) * [:link:](bootstrap.paginator/bootstrap.paginator.d.ts) [bootstrap.paginator](https://github.com/lyonlai/bootstrap-paginator) by [derikwhittaker](https://github.com/derikwhittaker) -* [:link:](bootstrap.timepicker/bootstrap.timepicker.d.ts) [bootstrap.timepicker](https://github.com/jdewit/bootstrap-timepicker) by [derikwhittaker](https://github.com/derikwhittaker) * [:link:](box2d/box2dweb.d.ts) [bootstrap.timepicker](http://code.google.com/p/box2dweb) by [jbaldwin](https://github.com/jbaldwin) +* [:link:](bootstrap.timepicker/bootstrap.timepicker.d.ts) [bootstrap.timepicker](https://github.com/jdewit/bootstrap-timepicker) by [derikwhittaker](https://github.com/derikwhittaker) * [:link:](breeze/breeze.d.ts) [Breeze 1.5.x](http://www.breezejs.com) by [Boris Yankov](https://github.com/borisyankov), [IdeaBlade](https://github.com/IdeaBlade/Breeze) * [:link:](browser-harness/browser-harness.d.ts) [Browser Harness](https://github.com/scriby/browser-harness) by [Chris Scribner](https://github.com/scriby) * [:link:](browser-sync/browser-sync.d.ts) [browser-sync](http://www.browsersync.io) by [Asana](https://asana.com) @@ -125,6 +129,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](business-rules-engine/business-rules-engine.d.ts) [business-rules-engine](https://github.com/rsamec/form) by [Roman Samec](https://github.com/rsamec) * [:link:](byline/byline.d.ts) [byline](https://github.com/jahewson/node-byline) by [Stefan Steinhart](https://github.com/reppners) * [:link:](calq/calq.d.ts) [calq](https://calq.io/docs/client/javascript/reference) by [Eirik Hoem](https://github.com/eirikhm) +* [:link:](camel-case/camel-case.d.ts) [camel-case](https://github.com/blakeembrey/camel-case) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](camljs/camljs.d.ts) [camljs](http://camljs.codeplex.com) by [Andrey Markeev](http://markeev.com) * [:link:](canvasjs/canvasjs.d.ts) [CanvasJS](http://canvasjs.com) by [Mark Overholt](https://github.com/mover5) * [:link:](casperjs/casperjs.d.ts) [CasperJS](http://casperjs.org) by [Jed Mao](https://github.com/jedmao) @@ -163,8 +168,10 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](compression/compression.d.ts) [compression](https://github.com/expressjs/compression) by [Santi Albo](https://github.com/santialbo) * [:link:](configstore/configstore.d.ts) [configstore](https://github.com/yeoman/configstore) by [Bart van der Schoor](https://github.com/Bartvds) * [:link:](connect-flash/connect-flash.d.ts) [connect-flash](https://github.com/jaredhanson/connect-flash) by [Andreas Gassmann](https://github.com/AndreasGassmann) +* [:link:](connect-modrewrite/connect-modrewrite.d.ts) [connect-modrewrite](https://github.com/tinganho/connect-modrewrite) by [Tingan Ho](https://github.com/tinganho) * [:link:](connect-slashes/connect-slashes.d.ts) [connect-slashes](https://github.com/avinoamr/connect-slashes) by [Sam Herrmann](https://github.com/samherrmann) * [:link:](consolidate/consolidate.d.ts) [consolidate](https://github.com/visionmedia/consolidate.js) by [Carlos Ballesteros Velasco](https://github.com/soywiz) +* [:link:](constant-case/constant-case.d.ts) [constant-case](https://github.com/blakeembrey/constant-case) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](content-type/content-type.d.ts) [content-type](https://github.com/deoxxa/content-type) by [Pine Mizune](https://github.com/pine613) * [:link:](contextjs/contextjs.d.ts) [contextjs](https://github.com/jakiestfu/Context.js) by [Kern Handa](https://github.com/kernhanda) * [:link:](convert-source-map/convert-source-map.d.ts) [convert-source-map](https://github.com/thlorenz/convert-source-map) by [Andrew Gaspar](https://github.com/AndrewGaspar) @@ -173,6 +180,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](cookiejs/cookiejs.d.ts) [cookie.js](https://github.com/js-coder/cookie.js) by [Boltmade](https://github.com/Boltmade) * [:link:](cordova-ionic/plugins/keyboard.d.ts) [Cordova Keyboard plugin](https://github.com/driftyco/ionic-plugins-keyboard) by [Hendrik Maus](https://github.com/hendrikmaus) * [:link:](cordovarduino/cordovarduino.d.ts) [Cordovarduino plugin](https://github.com/stereolux/cordovarduino) by [Hendrik Maus](https://github.com/hendrikmaus) +* [:link:](core-js/core-js.d.ts) [core-js](https://github.com/zloirock/core-js) by [Ron Buckton](http://github.com/rbuckton) * [:link:](couchbase/couchbase.d.ts) [Couchbase Couchnode](https://github.com/couchbase/couchnode) by [Basarat Ali Syed](https://github.com/basarat) * [:link:](createjs/createjs.d.ts) [CreateJS](http://www.createjs.com) by [Pedro Ferreira](https://bitbucket.org/drk4), [Chris Smith](https://github.com/evilangelist), [Satoru Kimura](https://github.com/gyohk) * [:link:](cron/cron.d.ts) [cron](https://www.npmjs.com/package/cron) by [Hiroki Horiuchi](https://github.com/horiuchi) @@ -218,6 +226,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](domready/domready.d.ts) [domready](https://github.com/ded/domready) by [Christian Holm Nielsen](https://github.com/dotnetnerd) * [:link:](donna/donna.d.ts) [donna](https://github.com/atom/donna) by [vvakame](https://github.com/vvakame) * [:link:](dot/dot.d.ts) [doT](https://github.com/olado/doT) by [ZombieHunter](https://github.com/ZombieHunter) +* [:link:](dot-case/dot-case.d.ts) [dot-case](https://github.com/blakeembrey/dot-case) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](dotdotdot/dotdotdot.d.ts) [dotdotdot](http://dotdotdot.frebsite.nl) by [Milan Jaros](https://github.com/milanjaros) * [:link:](doublearray/doublearray.d.ts) [doublearray](https://github.com/takuyaa/doublearray) by [MIZUSHIMA Junki](https://github.com/mzsm) * [:link:](drop/drop.d.ts) [Drop](http://github.hubspot.com/drop) by [Adi Dahiya](https://github.com/adidahiya) @@ -249,7 +258,9 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](epiceditor/epiceditor.d.ts) [EpicEditor](http://epiceditor.com) by [Boris Yankov](https://github.com/borisyankov) * [:link:](eq.js/eq.js.d.ts) [eq.js](https://github.com/Snugug/eq.js) by [Stephen Lautier](https://github.com/stephenlautier) * [:link:](errorhandler/errorhandler.d.ts) [errorhandler](https://github.com/expressjs/errorhandler) by [Santi Albo](https://github.com/santialbo) +* [:link:](es6-collections/es6-collections.d.ts) [es6-collections](https://github.com/WebReflection/es6-collections) by [Ron Buckton](http://github.com/rbuckton) * [:link:](es6-promise/es6-promise.d.ts) [es6-promise](https://github.com/jakearchibald/ES6-Promise) by [François de Campredon](https://github.com/fdecampredon), [vvakame](https://github.com/vvakame) +* [:link:](es6-shim/es6-shim.d.ts) [es6-shim](https://github.com/paulmillr/es6-shim) by [Ron Buckton](http://github.com/rbuckton) * [:link:](escape-latex/escape-latex.d.ts) [escape-latex](https://github.com/dangmai/escape-latex) by [Oliver Schneider](https://github.com/olsio) * [:link:](esprima/esprima.d.ts) [Esprima](http://esprima.org) by [teppeis](https://github.com/teppeis), [RReverser](https://github.com/RReverser) * [:link:](estree/estree.d.ts) [ESTree AST specification](https://github.com/estree/estree) by [RReverser](https://github.com/RReverser) @@ -318,6 +329,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](geojson/geojson.d.ts) [GeoJSON Format Specification](http://geojson.org) by [Jacob Bruun](https://github.com/cobster) * [:link:](geometry-dom/geometry-dom.d.ts) [Geometry Format Specification](http://www.w3.org/TR/geometry-1) by [Toshiya Nakakura](https://github.com/nakakura) * [:link:](giraffe/giraffe.d.ts) [Giraffe](https://github.com/barc/backbone.giraffe) by [Matt McCray](https://github.com/darthapo) +* [:link:](git-config/git-config.d.ts) [git-config](https://github.com/eugeneware/git-config) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](gl-matrix/gl-matrix.d.ts) [gl-matrix](https://github.com/toji/gl-matrix) by [Tat](https://github.com/tatchx) * [:link:](gldatepicker/gldatepicker.d.ts) [glDatePicker](http://glad.github.com/glDatePicker) by [Dániel Tar](https://github.com/qcz) * [:link:](glidejs/glidejs.d.ts) [Glide.js](http://glide.jedrzejchalubek.com) by [Milan Jaros](https://github.com/milanjaros) @@ -345,14 +357,14 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](greensock/greensock.d.ts) [GreenSock Animation Platform](http://www.greensock.com/get-started-js) by [Robert S](https://github.com/codebelt) * [:link:](gridfs-stream/gridfs-stream.d.ts) [gridfs-stream](https://github.com/aheckmann/gridfs-stream) by [Lior Mualem](https://github.com/liorm) * [:link:](gruntjs/gruntjs.d.ts) [Grunt 0.4.x](http://gruntjs.com) by [Jeff May](https://github.com/jeffmay), [Basarat Ali Syed](https://github.com/basarat) -* [:link:](gsap/TweenLite.d.ts) [GSAP](http://greensock.com) by [VILIC VANE](https://vilic.github.io) * [:link:](gsap/Ease.d.ts) [GSAP](http://greensock.com) by [VILIC VANE](https://vilic.github.io) * [:link:](gsap/Core.d.ts) [GSAP](http://greensock.com) by [VILIC VANE](https://vilic.github.io) +* [:link:](gsap/TweenLite.d.ts) [GSAP](http://greensock.com) by [VILIC VANE](https://vilic.github.io) * [:link:](gulp/gulp.d.ts) [Gulp v3.8.x](http://gulpjs.com) by [Drew Noakes](https://drewnoakes.com) * [:link:](gulp-autoprefixer/gulp-autoprefixer.d.ts) [gulp-autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer) by [Asana](https://asana.com) * [:link:](gulp-concat/gulp-concat.d.ts) [gulp-concat](http://github.com/wearefractal/gulp-concat) by [Keita Kagurazaka](https://github.com/k-kagurazaka) -* [:link:](gulp-rev/gulp-rev.d.ts) [gulp-csso](https://github.com/sindresorhus/gulp-rev) by [Tanguy Krotoff](https://github.com/tkrotoff) * [:link:](gulp-csso/gulp-csso.d.ts) [gulp-csso](https://github.com/ben-eb/gulp-csso) by [Tanguy Krotoff](https://github.com/tkrotoff) +* [:link:](gulp-rev/gulp-rev.d.ts) [gulp-csso](https://github.com/sindresorhus/gulp-rev) by [Tanguy Krotoff](https://github.com/tkrotoff) * [:link:](gulp-debug/gulp-debug.d.ts) [gulp-debug](https://github.com/sindresorhus/gulp-debug) by [Tanguy Krotoff](https://github.com/tkrotoff) * [:link:](gulp-flatten/gulp-flatten.d.ts) [gulp-flatten](https://github.com/armed/gulp-flatten) by [Keita Kagurazaka](https://github.com/k-kagurazaka) * [:link:](gulp-gh-pages/gulp-gh-pages.d.ts) [gulp-gh-pages](https://github.com/rowoot/gulp-gh-pages) by [Asana](https://asana.com) @@ -407,8 +419,8 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](humane/humane.d.ts) [Humane](http://wavded.github.com/humane-js) by [jmvrbanac](https://github.com/jmvrbanac) * [:link:](hypertext-application-language/hypertext-application-language.d.ts) [Hypertext Application Language Draft 6](https://tools.ietf.org/html/draft-kelly-json-hal-06) by [Maks3w](https://github.com/maks3w) * [:link:](i18n-node/i18n-node.d.ts) [i18n-node](https://github.com/mashpie/i18n-node) by [Maxime LUCE](https://github.com/SomaticIT) -* [:link:](i18next/i18next.d.ts) [i18next](http://i18next.com) by [Maarten Docter](https://github.com/mdocter) * [:link:](ng-i18next/ng-i18next.d.ts) [i18next](https://github.com/i18next/ng-i18next) by [Cyril Schumacher](https://github.com/cyrilschumacher) +* [:link:](i18next/i18next.d.ts) [i18next](http://i18next.com) by [Maarten Docter](https://github.com/mdocter) * [:link:](iban/iban.d.ts) [iban.js](https://github.com/arhs/iban.js) by [Cyril Schumacher](https://github.com/cyrilschumacher) * [:link:](icheck/icheck.d.ts) [iCheck](http://damirfoy.com/iCheck) by [Dániel Tar](https://github.com/qcz) * [:link:](imagemagick/imagemagick.d.ts) [imagemagick](http://github.com/rsms/node-imagemagick) by [Carlos Ballesteros Velasco](https://github.com/soywiz) @@ -425,11 +437,13 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](inversify/inversify.d.ts) [inversify](https://github.com/inversify/InversifyJS) by [inversify](https://github.com/inversify) * [:link:](cordova-ionic/cordova-ionic.d.ts) [Ionic Cordova plugins](https://github.com/driftyco) by [Hendrik Maus](https://github.com/hendrikmaus) * [:link:](irc/irc.d.ts) [irc](https://github.com/martynsmith/node-irc) by [phillips1012](https://github.com/phillips1012) +* [:link:](is-lower-case/is-lower-case.d.ts) [is-lower-case](https://github.com/blakeembrey/is-lower-case) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](is_js/is_js.d.ts) [is.js](http://arasatasaygin.github.io/is.js) by [Rodrigo Cabral](https://github.com/cabralRodrigo) * [:link:](iscroll/iscroll.d.ts) [iScroll](http://cubiq.org/iscroll-4) by [Boris Yankov](https://github.com/borisyankov), [Christiaan Rakowski](https://github.com/csrakowski) * [:link:](iscroll/iscroll-5.d.ts) [iScroll 5](http://cubiq.org/iscroll-5-ready-for-beta-test) by [Christiaan Rakowski](https://github.com/csrakowski) * [:link:](iscroll/iscroll-lite.d.ts) [iScroll Lite](http://cubiq.org/iscroll-4) by [Boris Yankov](https://github.com/borisyankov), [Christiaan Rakowski](https://github.com/csrakowski) * [:link:](iscroll/iscroll-5-lite.d.ts) [iScroll Lite 5](http://cubiq.org/iscroll-5-ready-for-beta-test) by [Christiaan Rakowski](https://github.com/csrakowski) +* [:link:](iso8601-localizer/iso8601-localizer.d.ts) [ISO8601-Localizer](https://github.com/avielfedida/ISO8601-Localizer) by [Aviel Fedida](https://github.com/avielfedida) * [:link:](ix.js/ix.d.ts) [IxJS 1.0.6 / ix.js](https://github.com/Reactive-Extensions/IxJS) by [Igor Oleinikov](https://github.com/Igorbek) * [:link:](ix.js/l2o.d.ts) [IxJS 1.0.6 / l2o.js](https://github.com/Reactive-Extensions/IxJS) by [Igor Oleinikov](https://github.com/Igorbek) * [:link:](jake/jake.d.ts) [jake](https://github.com/mde/jake) by [Kon](http://phyzkit.net) @@ -464,6 +478,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](jquery.fileupload/jquery.fileupload.d.ts) [jQuery File Upload Plugin](https://github.com/blueimp/jQuery-File-Upload) by [Rob Alarcon](https://github.com/rob-alarcon) * [:link:](jquery.joyride/jquery.joyride.d.ts) [jQuery JoyRide Plugin](https://github.com/zurb/joyride) by [Vincent Bortone](https://github.com/vbortone) * [:link:](jqgrid/jqgrid.d.ts) [jQuery jqgrid Plugin](https://github.com/tonytomov/jqGrid) by [Lokesh Peta](https://github.com/lokeshpeta) +* [:link:](jquery-knob/jquery-knob.d.ts) [jQuery Knob](http://anthonyterrien.com/knob) by [Iain Buchanan](https://github.com/iain8) * [:link:](jquerymobile/jquerymobile.d.ts) [jQuery Mobile](http://jquerymobile.com) by [Boris Yankov](https://github.com/borisyankov) * [:link:](jquery.notifyBar/jquery.notifyBar.d.ts) [jQuery Notify Bar](http://www.whoop.ee/posts/2013-04-05-the-resurrection-of-jquery-notify-bar) by [Shunsuke Ohtani](https://github.com/zaneli) * [:link:](jquery.base64/jquery.base64.d.ts) [jQuery Plugin - base64 codec](https://github.com/yatt/jquery.base64) by [Shinya Mochizuki](https://github.com/enrapt-mochizuki) @@ -623,6 +638,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](luaparse/luaparse.d.ts) [luaparse](https://github.com/oxyc/luaparse) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](lunr/lunr.d.ts) [lunr.js](https://github.com/olivernn/lunr.js) by [Sebastian Lenz](https://github.com/sebastian-lenz) * [:link:](lz-string/lz-string.d.ts) [lz-string](https://github.com/pieroxy/lz-string) by [Roman Nikitin](https://github.com/M0ns1gn0r) +* [:link:](magic-number/magic-number.d.ts) [magic-number](https://github.com/stpettersens/node-magic-number) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](magicsuggest/magicsuggest.d.ts) [MagicSuggest](http://nicolasbize.com/magicsuggest) by [Leonardo Chaia](http://github.com/leonardochaia) * [:link:](mailcheck/mailcheck.d.ts) [Mailcheck](https://github.com/mailcheck/mailcheck) by [Paulo Cesar](http://github.com/pocesar) * [:link:](main-bower-files/main-bower-files.d.ts) [main-bower-files](https://github.com/ck86/main-bower-files) by [Keita Kagurazaka](https://github.com/k-kagurazaka) @@ -672,8 +688,8 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](mkdirp/mkdirp.d.ts) [mkdirp](http://github.com/substack/node-mkdirp) by [Bart van der Schoor](https://github.com/Bartvds) * [:link:](mkpath/mkpath.d.ts) [mkpath](https://www.npmjs.com/package/mkpath) by [Jared Klopper](https://github.com/optical) * [:link:](mobile-detect/mobile-detect.d.ts) [mobile-detect](http://hgoebl.github.io/mobile-detect.js) by [Martin McWhorter](https://github.com/martinmcwhorter) -* [:link:](mocha/mocha.d.ts) [mocha](http://mochajs.org) by [Kazi Manzur Rashid](https://github.com/kazimanzurrashid), [otiai10](https://github.com/otiai10), [jt000](https://github.com/jt000), [Vadim Macagon](https://github.com/enlight) * [:link:](mocha/mocha-node.d.ts) [mocha](http://mochajs.org) by [Vadim Macagon](https://github.com/enlight), [vvakame](https://github.com/vvakame) +* [:link:](mocha/mocha.d.ts) [mocha](http://mochajs.org) by [Kazi Manzur Rashid](https://github.com/kazimanzurrashid), [otiai10](https://github.com/otiai10), [jt000](https://github.com/jt000), [Vadim Macagon](https://github.com/enlight) * [:link:](mocha-phantomjs/mocha-phantomjs.d.ts) [mocha-phantomjs](http://metaskills.net/mocha-phantomjs) by [Erik Schierboom](https://github.com/ErikSchierboom) * [:link:](mock-fs/mock-fs.d.ts) [mock-fs](https://github.com/tschaub/mock-fs) by [Wim Looman](https://github.com/Nemo157) * [:link:](mockery/mockery.d.ts) [mockery](https://github.com/mfncooper/mockery) by [jt000](https://github.com/jt000) @@ -705,6 +721,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](nedb/nedb.d.ts) [NeDB](https://github.com/louischatriot/nedb) by [Stefan Steinhart](https://github.com/reppners) * [:link:](needle/needle.d.ts) [needle](https://github.com/tomas/needle) by [San Chen](https://github.com/bigsan) * [:link:](nexpect/nexpect.d.ts) [nexpect](https://github.com/nodejitsu/nexpect) by [vvakame](http://github.com/vvakame) +* [:link:](ng-command/ng-command.d.ts) [ng-command](https://github.com/stephenlautier/ng-command) by [Stephen Lautier](https://github.com/stephenlautier) * [:link:](ng-grid/ng-grid.d.ts) [ng-grid](http://angular-ui.github.io/ng-grid) by [Ken Smith](https://github.com/smithkl42), [Roland Zwaga](https://github.com/rolandzwaga), [Kent Cooper](https://github.com/kentcooper) * [:link:](angular-idle/angular-idle.d.ts) [ng-idle](http://hackedbychinese.github.io/ng-idle) by [mthamil](https://github.com/mthamil) * [:link:](ngprogress/ngprogress.d.ts) [ngProgress](http://victorbjelkholm.github.io/ngProgress) by [Martin McWhorter](https://github.com/martinmcwhorter) @@ -722,6 +739,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](node-fibers/node-fibers.d.ts) [node-fibers](https://github.com/laverdet/node-fibers) by [Cary Haynie](https://github.com/caryhaynie) * [:link:](node-form/node-form.d.ts) [node-form](https://github.com/rsamec/form) by [Roman Samec](https://github.com/rsamec) * [:link:](node-gcm/node-gcm.d.ts) [node-gcm](https://www.npmjs.org/package/node-gcm) by [Hiroki Horiuchi](https://github.com/horiuchi) +* [:link:](node-getopt/node-getopt.d.ts) [node-getopt](https://github.com/jiangmiao/node-getopt) by [Karl.M.Cauchy](https://github.com/kcauchy) * [:link:](node-git/node-git.d.ts) [node-git](https://github.com/christkv/node-git) by [vvakame](https://github.com/vvakame) * [:link:](ip/ip.d.ts) [node-ip](https://github.com/indutny/node-ip) by [Peter Harris](https://github.com/codeanimal) * [:link:](multiparty/multiparty.d.ts) [node-multiparty](https://github.com/andrewrk/node-multiparty) by [Ken Fukuyama](https://github.com/kenfdev) @@ -735,25 +753,24 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](node-webkit/node-webkit.d.ts) [node-webkit](https://github.com/rogerwang/node-webkit) by [Pedro Casaubon](https://github.com/xperiments) * [:link:](xml2js/xml2js.d.ts) [node-xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) by [Michel Salib](https://github.com/michelsalib), [Jason McNeil](https://github.com/jasonrm) * [:link:](node/node.d.ts) [Node.js](http://nodejs.org) by [Microsoft TypeScript](http://typescriptlang.org), [DefinitelyTyped](https://github.com/borisyankov/DefinitelyTyped) +* [:link:](_debugger/_debugger.d.ts) [Node.js debugger API](http://nodejs.org) by [Basarat Ali Syed](https://github.com/basarat) * [:link:](restify/restify.d.ts) [node.js REST framework](https://github.com/mcavage/node-restify) by [Bret Little](https://github.com/blittle) -* [:link:](acl/acl-redisBackend.d.ts) [node_acl](https://github.com/optimalbits/node_acl) by [Qubo](https://github.com/tkQubo) -* [:link:](acl/acl-mongodbBackend.d.ts) [node_acl](https://github.com/optimalbits/node_acl) by [Qubo](https://github.com/tkQubo) * [:link:](acl/acl.d.ts) [node_acl](https://github.com/optimalbits/node_acl) by [Qubo](https://github.com/tkQubo) * [:link:](mdns/mdns.d.ts) [node_mdns](https://github.com/agnat/node_mdns) by [Stefan Steinhart](https://github.com/reppners) * [:link:](node_redis/node_redis.d.ts) [node_redis](https://github.com/mranney/node_redis) by [Boris Yankov](https://github.com/borisyankov) * [:link:](each/each.d.ts) [NodeEach](http://www.adaltas.com/projects/node-each) by [Michael Zabka](https://github.com/misak113) -* [:link:](nodemailer/nodemailer-types.d.ts) [Nodemailer](https://github.com/andris9/Nodemailer) by [Rogier Schouten](https://github.com/rogierschouten) * [:link:](nodemailer/nodemailer.d.ts) [Nodemailer](https://github.com/andris9/Nodemailer) by [Rogier Schouten](https://github.com/rogierschouten) +* [:link:](nodemailer/nodemailer-types.d.ts) [Nodemailer](https://github.com/andris9/Nodemailer) by [Rogier Schouten](https://github.com/rogierschouten) * [:link:](nodemailer-direct-transport/nodemailer-direct-transport.d.ts) [nodemailer-direct-transport](https://github.com/andris9/nodemailer-direct-transport) by [Rogier Schouten](https://github.com/rogierschouten) * [:link:](nodemailer-smtp-pool/nodemailer-smtp-pool.d.ts) [nodemailer-smtp-pool](https://github.com/andris9/nodemailer-smtp-pool) by [Rogier Schouten](https://github.com/rogierschouten) * [:link:](nodemailer-smtp-transport/nodemailer-smtp-transport.d.ts) [nodemailer-smtp-transport](https://github.com/andris9/nodemailer-smtp-transport) by [Rogier Schouten](https://github.com/rogierschouten) * [:link:](nodeunit/nodeunit.d.ts) [nodeunit](https://github.com/caolan/nodeunit) by [Jeff Goddard](https://github.com/jedigo) * [:link:](nomnom/nomnom.d.ts) [nomnom](https://github.com/harthur/nomnom) by [Paul Vick](https://github.com/panopticoncentral) * [:link:](nopt/nopt.d.ts) [nopt](https://github.com/npm/nopt) by [jbondc](https://github.com/jbondc) -* [:link:](notify/notify.d.ts) [Notify.js](https://github.com/jpillora/notifyjs) by [Xiaohan Zhang](https://github.com/hellochar) * [:link:](notifyjs/notifyjs.d.ts) [notify.js](https://github.com/alexgibson/notify.js) by [soundTricker](https://github.com/soundTricker) -* [:link:](nouislider/nouislider.d.ts) [nouislider](https://github.com/leongersen/noUiSlider) by [Corey Jepperson](https://github.com/acoreyj) +* [:link:](notify/notify.d.ts) [Notify.js](https://github.com/jpillora/notifyjs) by [Xiaohan Zhang](https://github.com/hellochar) * [:link:](wnumb/wnumb.d.ts) [nouislider](https://github.com/leongersen/wnumb) by [Corey Jepperson](https://github.com/acoreyj) +* [:link:](nouislider/nouislider.d.ts) [nouislider](https://github.com/leongersen/noUiSlider) by [Corey Jepperson](https://github.com/acoreyj) * [:link:](noVNC/noVNC.d.ts) [noVNC](https://github.com/kanaka/noVNC) by [Ken Smith](https://github.com/smithkl42) * [:link:](npm/npm.d.ts) [npm](https://github.com/npm/npm) by [Maxime LUCE](https://github.com/SomaticIT) * [:link:](nprogress/NProgress.d.ts) [NProgress](https://github.com/rstacruz/nprogress) by [Judah Gabriel Himango](http://debuggerdotbreak.wordpress.com) @@ -779,10 +796,11 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](passport/passport.d.ts) [Passport](http://passportjs.org) by [Horiuchi_H](https://github.com/horiuchi) * [:link:](passport-strategy/passport-strategy.d.ts) [Passport Strategy module](https://github.com/jaredhanson/passport-strategy) by [Lior Mualem](https://github.com/liorm) * [:link:](passport-twitter/passport-twitter.d.ts) [passport-facebook](https://github.com/jaredhanson/passport-facebook) by [James Roland Cabresos](https://github.com/staticfunction) -* [:link:](passport-facebook/passport-facebook.d.ts) [passport-facebook](https://github.com/jaredhanson/passport-facebook) by [James Roland Cabresos](https://github.com/staticfunction) * [:link:](passport-google-oauth/passport-google-oauth.d.ts) [passport-facebook](https://github.com/jaredhanson/passport-facebook) by [James Roland Cabresos](https://github.com/staticfunction) +* [:link:](passport-facebook/passport-facebook.d.ts) [passport-facebook](https://github.com/jaredhanson/passport-facebook) by [James Roland Cabresos](https://github.com/staticfunction) * [:link:](passport-facebook-token/passport-facebook-token.d.ts) [passport-facebook-token](https://github.com/drudge/passport-facebook-token) by [Ray Martone](https://github.com/rmartone) * [:link:](passport-local/passport-local.d.ts) [passport-local](https://github.com/jaredhanson/passport-local) by [Maxime LUCE](https://github.com/SomaticIT) +* [:link:](path-exists/path-exists.d.ts) [path-exists](https://github.com/sindresorhus/path-exists) by [Shogo Iwano](https://github.com/shiwano) * [:link:](path-to-regexp/path-to-regexp.d.ts) [path-to-regexp](https://github.com/pillarjs/path-to-regexp) by [xica](https://github.com/xica) * [:link:](pathwatcher/pathwatcher.d.ts) [pathwatcher](https://github.com/atom/node-pathwatcher) by [vvakame](https://github.com/vvakame) * [:link:](pdf/pdf.d.ts) [PDF.js](https://github.com/mozilla/pdf.js) by [Josh Baldwin](https://github.com/jbaldwin) @@ -795,6 +813,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](phantom/phantom.d.ts) [PhantomJS bridge for NodeJS](https://github.com/sgentle/phantomjs-node) by [horiuchi](https://github.com/horiuchi) * [:link:](phantomjs/phantomjs.d.ts) [PhantomJS v1.9.0 API](https://github.com/ariya/phantomjs/wiki/API-Reference) by [Jed Hunsaker](https://github.com/jedhunsaker), [Mike Keesey](https://github.com/keesey) * [:link:](phonegap/phonegap.d.ts) [PhoneGap](http://phonegap.com) by [Boris Yankov](https://github.com/borisyankov), [Dick van den Brink](https://github.com/DickvdBrink) +* [:link:](photonui/photonui.d.ts) [PhotonUI](https://github.com/wanadev/PhotonUI) by [Florent Poujol](https://github.com/florentpoujol) * [:link:](photoswipe/photoswipe.d.ts) [PhotoSwipe](http://photoswipe.com) by [Xiaohan Zhang](https://github.com/hellochar) * [:link:](physijs/physijs.d.ts) [Physijs](http://chandlerprall.github.io/Physijs) by [Satoru Kimura](https://github.com/gyohk) * [:link:](pickadate/pickadate.d.ts) [pickadate.js](https://github.com/amsul/pickadate.js) by [Theodore Brown](https://github.com/theodorejb) @@ -924,8 +943,8 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](slickgrid/slick.rowselectionmodel.d.ts) [SlickGrid RowSelectionModel Plugin](https://github.com/mleibman/SlickGrid) by [Derek Cicerone](https://github.com/derekcicerone) * [:link:](smoothie/smoothie.d.ts) [Smoothie Charts](https://github.com/joewalnes/smoothie) by [Drew Noakes](https://drewnoakes.com), [Mike H. Hawley](https://github.com/mikehhawley) * [:link:](snapsvg/snapsvg.d.ts) [Snap-SVG](https://github.com/adobe-webplatform/Snap.svg) by [Lars Klein](https://github.com/lhk) -* [:link:](socket.io/socket.io.d.ts) [socket.io](http://socket.io) by [PROGRE](https://github.com/progre) -* [:link:](socket.io-client/socket.io-client.d.ts) [socket.io-client](http://socket.io) by [PROGRE](https://github.com/progre) +* [:link:](socket.io/socket.io.d.ts) [socket.io](http://socket.io) by [PROGRE](https://github.com/progre), [Damian Connolly](https://github.com/divillysausages) +* [:link:](socket.io-client/socket.io-client.d.ts) [socket.io-client](http://socket.io) by [PROGRE](https://github.com/progre), [Damian Connolly](https://github.com/divillysausages) * [:link:](sockjs/sockjs.d.ts) [SockJS 0.3.x](https://github.com/sockjs/sockjs-client) by [Emil Ivanov](https://github.com/vladev) * [:link:](sockjs-node/sockjs-node.d.ts) [sockjs-node 0.3.x](https://github.com/sockjs/sockjs-node) by [Phil McCloghry-Laing](https://github.com/pmccloghrylaing) * [:link:](soundjs/soundjs.d.ts) [SoundJS](http://www.createjs.com/#!/SoundJS) by [Pedro Ferreira](https://bitbucket.org/drk4) @@ -972,6 +991,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](swipeview/swipeview.d.ts) [SwipeView](http://cubiq.org/swipeview) by [Boris Yankov](https://github.com/borisyankov) * [:link:](switchery/switchery.d.ts) [switchery](https://github.com/abpetkov/switchery) by [Bruno Grieder](https://github.com/bgrieder) * [:link:](swiz/swiz.d.ts) [swiz](https://github.com/racker/node-swiz) by [Jeff Goddard](https://github.com/jedigo) +* [:link:](systemjs/systemjs.d.ts) [System.js](https://github.com/systemjs/systemjs) by [Ludovic HENIN](https://github.com/ludohenin), [Nathan Walker](https://github.com/NathanWalker) * [:link:](tabtab/tabtab.d.ts) [tabtab](https://github.com/mklabs/node-tabtab) by [Vojtěch Habarta](https://github.com/vojtechhabarta) * [:link:](tape/tape.d.ts) [tape](https://github.com/substack/tape) by [Bart van der Schoor](https://github.com/Bartvds) * [:link:](tar/tar.d.ts) [tar](https://github.com/npm/node-tar) by [Maxime LUCE](https://github.com/SomaticIT) @@ -1008,6 +1028,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](titanium/titanium.d.ts) [Titanium Mobile](http://www.appcelerator.com) by [Craig Younkins](https://github.com/cyounkins) * [:link:](title-case/title-case.d.ts) [title-case](https://github.com/blakeembrey/title-case) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](tmp/tmp.d.ts) [tmp](https://www.npmjs.com/package/tmp) by [Jared Klopper](https://github.com/optical) +* [:link:](to-title-case-gouch/to-title-case-gouch.d.ts) [to-title-case](https://github.com/gouch/to-title-case) by [Sam Saint-Pettersen](https://github.com/stpettersens) * [:link:](toastr/toastr.d.ts) [Toastr](https://github.com/CodeSeven/toastr) by [Boris Yankov](https://github.com/borisyankov) * [:link:](sencha_touch/SenchaTouch.d.ts) [Touch](http://www.sencha.com/products/touch) by [Brian Kotek](https://github.com/brian428) * [:link:](traceback/traceback.d.ts) [Traceback](http://github.com/iriscouch/traceback) by [Michael Zabka](https://github.com/misak113) @@ -1024,6 +1045,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](type-detect/type-detect.d.ts) [type-detect](https://github.com/chaijs/type-detect) by [Bart van der Schoor](https://github.com/Bartvds) * [:link:](type-name/type-name.d.ts) [type-name](https://github.com/twada/type-name) by [OKUNOKENTARO](https://github.com/armorik83) * [:link:](typeahead/typeahead.d.ts) [typeahead.js](http://twitter.github.io/typeahead.js) by [Ivaylo Gochkov](https://github.com/igochkov), [Gidon Junge](https://github.com/gjunge) +* [:link:](webfontloader/webfontloader.d.ts) [typekit-webfontloader](https://github.com/typekit/webfontloader) by [doskallemaskin](https://github.com/doskallemaskin) * [:link:](typescript/typescript.d.ts) [TypeScript API](http://www.typescriptlang.org) by [Microsoft TypeScript](http://typescriptlang.org) * [:link:](typescript-deferred/typescript-deferred.d.ts) [typescript-deferred](https://github.com/DirtyHairy/typescript-deferred) by [Christian Speckner](https://github.com/DirtyHairy) * [:link:](typescript-services/typescriptServices.d.ts) [TypeScript-Services](https://www.npmjs.org/package/typescript-services) by [Basarat Ali Syed](http://github.com/basarat) @@ -1060,7 +1082,6 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](watch/watch.d.ts) [watch](https://github.com/mikeal/watch) by [Carlos Ballesteros Velasco](https://github.com/soywiz) * [:link:](jquery.watermark/jquery.watermark.d.ts) [Watermark plugin for jQuery](http://jquery-watermark.googlecode.com) by [Anwar Javed](https://github.com/anwarjaved) * [:link:](webaudioapi/waa.d.ts) [Web Audio API](http://www.w3.org/TR/webaudio) by [Baruch Berger](https://github.com/bbss), [Kon](http://phyzkit.net), [kubosho](https://github.com/kubosho) -* [:link:](webaudioapi/waa-nightly.d.ts) [Web Audio API (nightly)](http://www.w3.org/TR/2012/WD-webaudio-20120802) by [Baruch Berger](https://github.com/bbss) * [:link:](webmidi/webmidi.d.ts) [Web MIDI API](http://www.w3.org/TR/webmidi) by [Toshiya Nakakura](https://github.com/nakakura) * [:link:](webspeechapi/webspeechapi.d.ts) [Web Speech API](https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html) by [SaschaNaz](https://github.com/saschanaz) * [:link:](webcola/webcola.d.ts) [webcola](https://github.com/tgdwyer/WebCola) by [Qinfeng Chen](https://github.com/qinfchen) diff --git a/angular-formly/angular-formly-tests.ts b/angular-formly/angular-formly-tests.ts new file mode 100644 index 0000000000..ef6a384637 --- /dev/null +++ b/angular-formly/angular-formly-tests.ts @@ -0,0 +1,108 @@ +/// + +var app = angular.module('app', ['formly']); + +interface IScope extends ng.IScope { + to: { label: string; } +} + +class FormConfig { + constructor(formlyConfig: AngularFormly.IFormlyConfig, formlyValidationMessages: AngularFormly.IValidationMessages) { + formlyConfig.setWrapper({ + name: 'validation', + types: ['input', 'customInput'], + templateUrl: 'my-messages.html' + }); + + formlyValidationMessages.addStringMessage('required', 'This field is required'); + + formlyConfig.setType({ + name: 'customInput', + extends: 'input' + }); + } +} + +class AppController { + fields: AngularFormly.IFieldConfigurationObject[]; + constructor() { + var vm = this; + vm.fields = [ + { + key: 'firstName', + type: 'customInput', + templateOptions: { + required: true, + label: 'First Name', + foo: 'hi' + } + }, + { + key: 'email', + type: 'input', + templateOptions: { + label: 'Email', + required: true, + type: 'email', + maxlength: 10, + minlength: 6, + placeholder: 'example@example.com' + } + }, + { + key: 'ip', + type: 'input', + validators: { + ipAddress: { + expression: function(viewValue, modelValue) { + var value = modelValue || viewValue; + return /(\d{1,3}\.){3}\d{1,3}/.test(value); + }, + message: '$viewValue + " is not a valid IP Address"' + } + }, + templateOptions: { + label: 'IP Address', + required: true, + type: 'text', + placeholder: '127.0.0.1', + }, + validation: { + messages: { + required: function($viewValue: any, $modelValue: any, scope: AngularFormly.ITemplateScope) { + return scope.to.label + ' is required' + } + } + } + }, + { + key: 'mac', + type: 'input', + templateOptions: { + label: 'MAC Address', + required: true, + placeholder: '49-8A-BD-4E-00-1D', + pattern: '([0-9A-F]{2}[:-]){5}([0-9A-F]{2})' + } + }, + { + type: 'checkbox', + key: 'checked', + templateOptions: { + label: 'Check this' + } + }, + { + key: 'checked2', + type: 'checkbox', + wrapper: null, + templateOptions: { + label: 'no wrapper here...' + } + } + ] + } +} + +app.controller("AppController", AppController); + diff --git a/angular-formly/angular-formly.d.ts b/angular-formly/angular-formly.d.ts new file mode 100644 index 0000000000..8f76b3ccf9 --- /dev/null +++ b/angular-formly/angular-formly.d.ts @@ -0,0 +1,574 @@ +// Type definitions for angular-formly 6.18.0 +// Project: https://github.com/formly-js/angular-formly +// Definitions by: Scott Hatcher +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module 'AngularFormly' { + export = AngularFormly; +} + +declare module AngularFormly { + + + interface IFieldGroup { + data?: Object; + className?: string; + elementAttributes?: { [key: string]: string }; + fieldGroup: IFieldConfigurationObject[]; + form?: Object; + hide?: boolean; + hideExpression?: string | IExpresssionFunction; + key?: string | number; + model?: string | Object; + options?: IFormOptionsAPI + } + + + interface IFormOptionsAPI { + data?: Object; + fieldTransform?: Function; + formState?: Object; + removeChromeAutoComplete?: boolean; + resetModel?: Function; + templateManipulators?: ITemplateManipulators; + updateInitialValue?: Function; + wrapper?: string | string[]; + } + + + /** + * see http://docs.angular-formly.com/docs/formly-expressions#expressionproperties-validators--messages + */ + interface IExpresssionFunction { + ($viewValue: any, $modelValue: any, scope: ITemplateScope): any; + } + + + interface IModelOptions { + updateOn?: string; + debounce?: number; + allowInvalid?: boolean; + getterSetter?: string; + timezone?: string; + } + + + interface ITemplateManipulator { + (template: string | HTMLElement, options: Object, scope: ITemplateScope): string | HTMLElement; + } + + + interface ITemplateManipulators { + preWrapper?: ITemplateManipulator[]; + postWrapper?: ITemplateManipulator[]; + } + + + /** + * see http://docs.angular-formly.com/docs/ngmodelattrstemplatemanipulator + */ + interface ITemplateOptions { + + // both attribute or regular attribute + disabled?: boolean; + maxlength?: number; + minlength?: number; + pattern?: string; + required?: boolean; + + //attribute only + max?: number; + min?: number; + placeholder?: number | string; + tabindex?: number; + type?: string; + + //expression types + onBlur?: string; + onChange?: string; + onClick?: string; + onFocus?: string; + onKeydown?: string; + onKeypress?: string; + onKeyup?: string; + + //Bootstrap types + label?: string; + description?: string; + [key: string]: any; + + } + + + /** + * see http://docs.angular-formly.com/docs/field-configuration-object#validators-object + */ + interface IValidator { + expression: string | IExpresssionFunction; + message?: string | IExpresssionFunction; + } + + + /** + * An object which has at least two properties called expression and listener. The watch.expression + * is added to the formly-form directive's scope (to allow it to run even when hide is true). You + * can specify a type ($watchCollection or $watchGroup) via the watcher.type property (defaults to + * $watch) and whether you want it to be a deep watch via the watcher.deep property (defaults to false). + * + * see http://docs.angular-formly.com/docs/field-configuration-object#watcher-objectarray-of-watches + */ + interface IWatcher { + deep?: boolean; //Defaults to false + expression?: string | { (field: string, scope: ITemplateScope): boolean }; + listener: (field: string, newValue: any, oldValue: any, scope: ITemplateScope, stopWatching: Function) => void; + type?: string; //Defaults to $watch but can be set to $watchCollection or $watchGroup + } + + + // see http://docs.angular-formly.com/docs/field-configuration-object + interface IFieldConfigurationObject { + + + /** + * Added in 6.18.0 + * + * Demo + * see http://angular-formly.com/#/example/other/unique-value-async-validation + */ + asyncValidators?: { + [key: string]: string | IExpresssionFunction | IValidator; + } + + /** + * This is a great way to add custom behavior to a specific field. It is injectable with the $scope of the + * field, and anything else you have in your injector. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#controller-controller-name-as-string--controller-f + */ + controller?: string | Function; + + + /** + * This is reserved for the developer. You have our guarantee to be able to use this and not worry about + * future versions of formly overriding your usage and preventing you from upgrading :-) + * + * see http://docs.angular-formly.com/docs/field-configuration-object#data-object + */ + data?: Object; + + + /** + * Use defaultValue to initialize it the model. If this is provided and the value of the + * model at compile-time is undefined, then the value of the model will be assigned to defaultValue. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#defaultvalue-any + */ + defaultValue?: any; + + + /** + * You can specify your own class that will be applied to the formly-field directive (or ng-form of + * a fieldGroup). + * + * see http://docs.angular-formly.com/docs/field-configuration-object#classname-string + */ + className?: string; + + + elementAttributes?: string; + + + /** + * An object where the key is a property to be set on the main field config and the value is an + * expression used to assign that property. The value is a formly expressions. The returned value is + * wrapped in $q.when so you can return a promise from your function :-) + * + * see http://docs.angular-formly.com/docs/field-configuration-object#expressionproperties-object + */ + expressionProperties?: { + [key: string]: string | IExpresssionFunction | IValidator; + } + + + /** + * Uses ng-if. Whether to hide the field. Defaults to false. If you wish this to be conditional, use + * hideExpression. See below. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#hide-boolean + */ + hide?: boolean + + + /** + * This is similar to expressionProperties with a slight difference. You should (hopefully) never + * notice the difference with the most common use case. This is available due to limitations with + * expressionProperties and ng-if not working together very nicely. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#hideexpression-string--function + */ + hideExpression?: string | IExpresssionFunction; + + + /** + * This allows you to specify the id of your field (which will be used for its name as well unless + * a name is provided). Note, you can also override the id generation code using the formlyConfig + * extra called getFieldId. + * + * AVOID THIS + * If you don't have to do this, don't. Specifying IDs makes it harder to re-use things and it's + * just extra work. Part of the beauty that angular-formly provides is the fact that you don't need + * to concern yourself with making sure that this is unique. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#id-string + */ + id?: string; + + + initialValue?: any; + + + /** + * Can be set instead of type or template to use a custom html template form field. Works + * just like a directive templateUrl and uses the $templateCache + * + * see http://docs.angular-formly.com/docs/field-configuration-object#key-string + */ + key?: string | number; + + + /** + * This allows you to specify a link function. It is invoked after your template has finished compiling. + * You are passed the normal arguments for a normal link function. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#link-link-function + */ + link?: ng.IDirectiveLinkFn; + + + /** + * By default, the model passed to the formly-field directive is the same as the model passed to the + * formly-form. However, if the field has a model specified, then it is used for that field (and that + * field only). In addition, a deep watch is added to the formly-field directive's scope to run the + * expressionProperties when the specified model changes. + * + * Note, the formly-form directive will allow you to specify a string which is an (almost) formly + * expression which allows you to define the model as relative to the scope of the form. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#model-object--string + */ + model?: Object | string; + + + /** + * Allows you to take advantage of ng-model-options directive. Formly's built-in templateManipulator (see + * below) will add this attribute to your ng-model element automatically if this property exists. Note, + * if you use the getter/setter option, formly's templateManipulator will change the value of ng-model + * to options.value which is a getterSetter that formly adds to field options. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#modeloptions + */ + modelOptions?: IModelOptions; + + + /** + * If you wish to, you can specify a specific name for your ng-model. This is useful if you're posting + * the form to a server using techniques of yester-year. + * + * AVOID THIS + * If you don't have to do this, don't. It's just extra work. Part of the beauty that angular-formly + * provides is the fact that you don't need to concern yourself with stuff like this. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#name-string + */ + name?: string; + + + /** + * This is used by ngModelAttrsTemplateManipulator to automatically add attributes to the ng-model element + * of field templates. You will likely not use this often. This object is a little complex, but extremely + * powerful. It's best to explain this api via an example. For more information, see the guide on ngModelAttrs. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#ngmodelattrs-object + */ + ngModelAttrs?: { + attribute?: any; + bound?: any; + expression?: any; + value?: any; + }; + + + /** + * Used to tell angular-formly to not attempt to add the formControl property to your object. This is useful + * for things like validation, but not necessary if your "field" doesn't use ng-model (if it's just a horizontal + * line for example). Defaults to undefined. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#noformcontrol-boolean + */ + noFormControl?: boolean; + + + /** + * Allows you to specify extra types to get options from. Duplicate options are overridden in later priority + * (index 1 will override index 0 properties). Also, these are applied after the type's defaultOptions and + * hence will override any duplicates of those properties as well. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#optionstypes-string--array-of-strings + */ + optionsTypes?: string | string[]; + + + /** + * Can be set instead of type or templateUrl to use a custom html + * template form field. Recommended to be used with one-liners mostly + * (like a directive), or if you're using webpack with the ability to require templates :-) + * + * If a function is passed, it is invoked with the field configuration object and can return + * either a string for the template or a promise that resolves to a string. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#template-string--function + */ + template?: string | { (fieldConfiguration: IFieldConfigurationObject): string | ng.IPromise }; + + + /** + * Allows you to specify custom template manipulators for this specific field. (use defaultOptions in a + * type configuration if you want it to apply to all fields of a certain type). + * + * see http://docs.angular-formly.com/docs/field-configuration-object#templatemanipulator-object-of-arrays-of-functions + */ + templateManipulators?: ITemplateManipulators; + + + /** + * This is reserved for the templates. Any template-specific options go in here. Look at your specific + * template implementation to know the options required for this. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#templateoptions-object + */ + templateOptions?: ITemplateOptions; + + + /** + * Can be set instead of type or template to use a custom html template form field. Works + * just like a directive templateUrl and uses the $templateCache + * + * see http://docs.angular-formly.com/docs/field-configuration-object#templateurl-string--function + */ + templateUrl?: string | { (fieldConfiguration: IFieldConfigurationObject): string | ng.IPromise }; + + + /** + * The type of field to be rendered. This is the recommended method + * for defining fields. Types must be pre-defined using formlyConfig. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#type-string + */ + type?: string; + + + /** + * An object with a few useful properties mostly handy when used in combination with ng-messages + */ + validation?: { + + /** + * This is set by angular-formly. This is a boolean indicating whether an error message should be shown. Because + * you generally only want to show error messages when the user has interacted with a specific field, this value + * is set to true based on this rule: field invalid && (field touched || validation.show) (with slight difference + * for pre-angular 1.3 because it doesn't have touched support). + */ + errorExistsAndShouldBeVisible?: boolean; + + + /** + * A map of Formly Expressions mapped to message names. This is really useful when you're using ng-messages + * like in this example. + */ + messages?: { + [key: string]: IExpresssionFunction | string; + } + + + /** + * A boolean you as the developer can set to specify to force options.validation.errorExistsAndShouldBeVisible + * to be set to true when there are $errors. This is useful when you're trying to call the user's attention to + * some fields for some reason. + */ + show?: boolean; + + } + + + /** + * An object where the keys are the name of the validator and the values are Formly Expressions; + * + * Async Validation + * All function validators can return true/false/Promise. A validator passes if it returns true or a promise + * that is resolved. A validator fails if it returns false or a promise that is rejected. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#validators-object + */ + validators?: { + [key: string]: string | IExpresssionFunction | IValidator; + } + + + /** + * This is a getter/setter function for the value that your field is representing. Useful when using getterSetter: true + * in the modelOptions (in fact, if you don't disable the ngModelAttrsTemplateManipulator that comes built-in with formly, + * it will automagically change your field's ng-model attribute to use options.value. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#value-gettersetter-function + */ + value?(): any; //Getter + value?(val: any): void; //Setter + + + /** + * An object which has at least two properties called expression and listener. The watch.expression is added + * to the formly-form directive's scope (to allow it to run even when hide is true). You can specify a type + * ($watchCollection or $watchGroup) via the watcher.type property (defaults to $watch) and whether you want + * it to be a deep watch via the watcher.deep property (defaults to false). + * + * see http://docs.angular-formly.com/docs/field-configuration-object#watcher-objectarray-of-watches + */ + watcher?: IWatcher | IWatcher[]; + + + /** + * This makes reference to setWrapper in formlyConfig. It is expected to be the name of the wrapper. If + * given an array, the formly field template will be wrapped by the first wrapper, then the second, then + * the third, etc. You can also specify these as part of a type (which is the recommended approach). + * Specifying this property will override the wrappers for the type for this field. + * + * http://docs.angular-formly.com/docs/field-configuration-object#wrapper-string--array-of-strings + */ + wrapper?: string | string[]; + + + //ALL PROPERTIES BELOW ARE ADDED (So you should not be setting them yourself.) + + + /** + * This is the NgModelController for the field. It provides you with awesome stuff like $errors :-) + * + * see http://docs.angular-formly.com/docs/field-configuration-object#formcontrol-ngmodelcontroller + */ + formControl?: ng.IFormController | ng.IFormController[]; + + + /** + * Will reset the field's model and the field control to the last initialValue. This is used by the + * formly-form's options.resetModel function. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#resetmodel-function + */ + resetModel?: () => void; + + + /** + * It is not likely that you'll ever want to invoke this function. It simply runs the expressionProperties expressions. + * It is used internally and you shouldn't have to use it, but you can if you want to, and any breaking changes to the + * way it works will result in a major version change, so you can rely on its api. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#runexpressions-function + */ + runExpressions?: () => void; + + + /** + * Will reset the field's initialValue to the current state of the model. Useful if you load the model asynchronously. + * Invoke this when the model gets set. This is used by the formly-form's options.updateInitialValue function. + * + * see http://docs.angular-formly.com/docs/field-configuration-object#updateinitialvalue-function + */ + updateInitialValue?: () => void; + + } + + /** + * + * + * see http://docs.angular-formly.com/docs/custom-templates#section-formlyconfig-settype-options + */ + interface ITypeOptions { + apiCheck?: { [key: string]: Function }; + apiCheckFunction?: string; //'throw' or 'warn + apiCheckInstance?: any; + apiCheckOptions?: Object; + defaultOptions?: IFieldConfigurationObject | Function; + controller?: Function | string | any[]; + data?: Object; + extends?: string; + link?: ng.IDirectiveLinkFn; + overwriteOk?: boolean; + name: string; + template?: Function | string; + templateUrl?: Function | string; + validateOptions?: Function; + wrapper?: string | string[]; + } + + interface IWrapperOptions { + apiCheck?: { [key: string]: Function }; + apiCheckFunction?: string; //'throw' or 'warn + apiCheckInstance?: any; + apiCheckOptions?: Object; + overwriteOk?: boolean; + name?: string; + template?: string; + templateUrl?: string; + types?: string[]; + validateOptions?: Function; + } + + interface IFormlyConfig { + setType(typeOptions: ITypeOptions): void; + setWrapper(wrapperOptions: IWrapperOptions): void; + + } + + interface ITemplateScopeOptions { + formControl: ng.IFormController | ng.IFormController[]; + templateOptions: ITemplateOptions; + validation: Object; + } + + /** + * see http://docs.angular-formly.com/docs/custom-templates#templates-scope + */ + interface ITemplateScope { + options: ITemplateScopeOptions; + //Shortcut to options.formControl + fc: ng.IFormController | ng.IFormController[]; + //all the fields for the form + fields: IFieldConfigurationObject[]; + //the form controller the field is in + form: any; + //The object passed as options.formState to the formly-form directive. Use this to share state between fields. + formState: Object; + //The id of the field. You shouldn't have to use this. + id: string; + //The index of the field the form is on (in ng-repeat) + index: number; + //the model of the form (or the model specified by the field if it was specified). + model: Object | string; + //Shortcut to options.validation.errorExistsAndShouldBeVisible + showError: boolean; + //Shortcut to options.templateOptions + to: ITemplateOptions; + } + + /** + * see http://docs.angular-formly.com/docs/formlyvalidationmessages#addtemplateoptionvaluemessage + */ + interface IValidationMessages { + addTemplateOptionValueMessage(name: string, prop: string, prefix: string, suffix: string, alternate: string): void; + addStringMessage(name: string, string: string): void; + messages: { [key: string]: ($viewValue: any, $modelValue: any, scope: ITemplateScope) => string }; + } + +} \ No newline at end of file diff --git a/angular-odata-resources/angular-odata-resources-tests.ts b/angular-odata-resources/angular-odata-resources-tests.ts index 0149533fab..5b8dbcc52b 100644 --- a/angular-odata-resources/angular-odata-resources-tests.ts +++ b/angular-odata-resources/angular-odata-resources-tests.ts @@ -186,4 +186,14 @@ var combination2 = Predicate.and([combination1, predicate2]); var predicate = new Predicate("FirstName", "John") .or(new Predicate("LastName", '!=', "Doe")) - .and(new Predicate("Age", '>', 10)); \ No newline at end of file + .and(new Predicate("Age", '>', 10)); + + +users = odataResourceClass.odata() + .withInlineCount() + .query(); + + +var countResult = odataResourceClass.odata().count(); +var total = countResult.result; + diff --git a/angular-odata-resources/angular-odata-resources.d.ts b/angular-odata-resources/angular-odata-resources.d.ts index 87b89687fa..0a83df2c3c 100644 --- a/angular-odata-resources/angular-odata-resources.d.ts +++ b/angular-odata-resources/angular-odata-resources.d.ts @@ -264,6 +264,11 @@ declare module OData { (queryString: string, success: () => any, error: () => any): T[]; (queryString: string, success: () => any, error: () => any, isSingleElement?: boolean, forceSingleElement?: boolean): T; } + + interface ICountResult{ + result: number; + } + class Provider { private callback; private filters; @@ -281,6 +286,8 @@ declare module OData { single(success?: any, error?: any): T; get(data: any, success?: any, error?: any): T; expand(params: any, otherParam1?: any, otherParam2?: any, otherParam3?: any, otherParam4?: any, otherParam5?: any, otherParam6?: any, otherParam7?: any): Provider; + count(success?: (result: ICountResult) => any, error?: () => any):ICountResult; + withInlineCount(): Provider; } interface ValueFactory { diff --git a/angular-protractor/angular-protractor-tests.ts b/angular-protractor/angular-protractor-tests.ts index b8b9585f47..45a5d7edc4 100644 --- a/angular-protractor/angular-protractor-tests.ts +++ b/angular-protractor/angular-protractor-tests.ts @@ -374,7 +374,7 @@ function TestElementArrayFinder() { var b: boolean = elementArrayFinder.isPending(); var locator: webdriver.Locator = elementArrayFinder.locator(); - var findersArray: protractor.ElementFinder[] = elementArrayFinder.asElementFinders_(); + var findersArrayPromise: protractor.promise.Promise = elementArrayFinder.asElementFinders_(); var driverElementArray: webdriver.WebElement[] = elementArrayFinder.getWebElements(); var elementFinder: protractor.ElementFinder = elementArrayFinder.get(42); diff --git a/angular-protractor/angular-protractor.d.ts b/angular-protractor/angular-protractor.d.ts index 76f0b5f10c..2b86864cd3 100644 --- a/angular-protractor/angular-protractor.d.ts +++ b/angular-protractor/angular-protractor.d.ts @@ -927,7 +927,7 @@ declare module protractor { * @return {Array.} Return a promise, which resolves to a list * of ElementFinders specified by the locator. */ - asElementFinders_(): ElementFinder[]; + asElementFinders_(): webdriver.promise.Promise; /** * Create a shallow copy of ElementArrayFinder. diff --git a/angular2/angular2-2.0.0-alpha.32.d.ts b/angular2/angular2-2.0.0-alpha.32.d.ts index 596db9287c..ff5661650f 100644 --- a/angular2/angular2-2.0.0-alpha.32.d.ts +++ b/angular2/angular2-2.0.0-alpha.32.d.ts @@ -23,7 +23,7 @@ declare module ng { type SetterFn = typeof Function; type int = number; interface Type extends Function { - new (...args: any[]): Type; + new (...args: any[]): any; } // See https://github.com/Microsoft/TypeScript/issues/1168 diff --git a/angular2/angular2.d.ts b/angular2/angular2.d.ts index 596db9287c..ff5661650f 100644 --- a/angular2/angular2.d.ts +++ b/angular2/angular2.d.ts @@ -23,7 +23,7 @@ declare module ng { type SetterFn = typeof Function; type int = number; interface Type extends Function { - new (...args: any[]): Type; + new (...args: any[]): any; } // See https://github.com/Microsoft/TypeScript/issues/1168 diff --git a/angularjs/angular.d.ts b/angularjs/angular.d.ts index 746fbb0e0d..5ad9895b04 100755 --- a/angularjs/angular.d.ts +++ b/angularjs/angular.d.ts @@ -238,7 +238,7 @@ declare module angular { fromJson(json: string): any; identity(arg?: any): any; - injector(modules?: any[]): auto.IInjectorService; + injector(modules?: any[], strictDi?: boolean): auto.IInjectorService; isArray(value: any): boolean; isDate(value: any): boolean; isDefined(value: any): boolean; @@ -421,9 +421,9 @@ declare module angular { /** * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with x- or data-) to its normalized, camelCase form. - * + * * Also there is special case for Moz prefix starting with upper case letter. - * + * * For further information check out the guide on @see https://docs.angularjs.org/guide/directive#matching-directives */ $normalize(name: string): void; diff --git a/angulartics/angulartics-tests.ts b/angulartics/angulartics-tests.ts new file mode 100644 index 0000000000..cc816a2ab5 --- /dev/null +++ b/angulartics/angulartics-tests.ts @@ -0,0 +1,25 @@ +/// +/// + +module Analytics { + angular.module("angulartics.app", ["angulartics"]) + .config(["$analyticsProvider", ($analyticsProvider: Angulartics.IAnalyticsServiceProvider) => { + angulartics.waitForVendorApi("location", 1000, (message: string) => { + console.log(message); + }); + + $analyticsProvider.virtualPageviews(false); + $analyticsProvider.firstPageview(false); + $analyticsProvider.withAutoBase(true); + $analyticsProvider.developerMode(true); + + $analyticsProvider.registerEventTrack((action: string, properties?: any) => { + console.log(action); + }); + + $analyticsProvider.registerPageTrack((path: string, locationObj: ng.ILocationService) => { + console.log("viewed " + path); + }); + }]); +} + diff --git a/angulartics/angulartics.d.ts b/angulartics/angulartics.d.ts new file mode 100644 index 0000000000..8c89575698 --- /dev/null +++ b/angulartics/angulartics.d.ts @@ -0,0 +1,39 @@ +// Type definitions for Angulartics v0.19.2 +// Project: http://luisfarzati.github.io/angulartics/ +// Definitions by: Steven Fan +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +interface Angulartics { + waitForVendorApi(objectName: string, delay: number, containsField?: any, registerFn?: any, onTimeout?: boolean): void; +} + +declare module Angulartics { + + interface IAnalyticsService { + eventTrack(eventName: string, properties?: any): any; + pageTrack(path: string, location?: ng.ILocationService): any; + setAlias(alias: string): any; + setUsername(username: string): any; + setUserProperties(properties: any): any; + setSuperProperties(properties: any): any; + } + + interface IAnalyticsServiceProvider extends angular.IServiceProvider { + virtualPageviews(value: boolean): void; + firstPageview(value: boolean): void; + withBase(value: boolean): void; + withAutoBase(value: boolean): void; + developerMode(value: boolean): void; + + registerPageTrack(callback: (path: string, location?: ng.ILocationService) => any): void; + registerEventTrack(callback: (eventName: string, properties?: any) => any): void; + registerSetAlias(callback: (alias: string) => any): void + registerSetUsername(callback: (username: string) => any): void + registerSetUserProperties(callback: (userProperties: any) => any): void + registerSetSuperProperties(callback: (superProperties: any) => any): void + } +} + +declare var angulartics:Angulartics; diff --git a/baconjs/.editorconfig b/baconjs/.editorconfig new file mode 100644 index 0000000000..8649cc5c38 --- /dev/null +++ b/baconjs/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*.ts] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/baconjs/baconjs-tests.ts b/baconjs/baconjs-tests.ts index 5d5998b708..9557e37cdf 100644 --- a/baconjs/baconjs-tests.ts +++ b/baconjs/baconjs-tests.ts @@ -1,389 +1,464 @@ /// 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]); + $("#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/")); + 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); + 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!"); - }); - Bacon.fromEvent($("body"), "click").onValue(() => { - 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(); - - { - var fs = require("fs"), - read = Bacon.fromNodeCallback(fs.readFile, "input.txt"); - read.onError(error => { - console.log("Reading failed: " + error); + Bacon.fromPromise($.ajax("https://baconjs.github.io/"), true, (n:string) => { + return [new Bacon.Next(n), new Bacon.Next(() => n), new Bacon.End()]; }); - read.onValue(value => { - console.log("Read contents: " + value); + Bacon.fromPromise(Promise.resolve(1), false, n => { + return [new Bacon.Next(n), new Bacon.Next(() => n), new Bacon.End()]; }); - } - Bacon.once(new Bacon.Error("fail")); + 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!"); + }); + Bacon.fromEvent($("body"), "click").onValue(() => { + alert("Bacon!"); + }); - // The following would lead to `1,2,3,1,2,3...` to be repeated indefinitely: - Bacon.fromArray([1, new Bacon.Error("")]); + // 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); + }); - Bacon.repeatedly(10, [1, 2, 3]); + // 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(); - // The following will produce values `0,1,2`. - Bacon.repeat(i => { - if (i < 3) { - return Bacon.once(i); - } else { - return false; + { + var 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); + }); } - }).log(); - { - var 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(); - } + Bacon.once(new Bacon.Error("fail")); - new Bacon.Next("value"); - new Bacon.Next(() => "value"); + // 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(); + + { + var 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(); - }); + // 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]).scan(0, (a, b) => a + b); - Bacon.sequentially(1, [1, 2, 3]).diff(0, (a, b) => Math.abs(b - a)); + 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); + // 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); - { - var x = Bacon.fromArray([1, 2]), y = Bacon.fromArray([3, 4]); - x.zip(y, (x, y) => x + y); - } - - { - var 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(), []]; + { + var x = Bacon.fromArray([1, 2]), y = Bacon.fromArray([3, 4]); + x.zip(y, (x, y) => x + y); } - else if (event.isEnd()) { - return [undefined, [new Bacon.Next(sum), event]]; + + { + var stream = Bacon.fromArray([1, 2]); + stream.log("New event in myStream"); + stream.log(); } - else { - return [sum, [event]]; + + 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]]; + } + }); + + { + var 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}}); } - }); - { - var 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: - var 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); + { + // This is handy for keeping track whether we are currently awaiting an AJAX response: + var ajaxRequest = >{}, + ajaxResponse = >{}, + showAjaxIndicator = ajaxRequest.awaiting(ajaxResponse); } - }); - { - var src = Bacon.once(1), - obs = src.map(x => -x); - console.log(obs.toString()); // > "Bacon.once(1).map(function)" + 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); + } + }); - obs.withDescription(src, "times", -1); - console.log(obs.toString()); // > "Bacon.once(1).times(-1)" - } + { + var src = Bacon.once(1), + obs = src.map(x => -x); + console.log(obs.toString()); // > "Bacon.once(1).map(function)" - { - // Calculator for grouped consecutive values until group is cancelled: - var 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) => { - 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); - }; + obs.withDescription(src, "times", -1); + console.log(obs.toString()); // > "Bacon.once(1).times(-1)" + } - 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 - }); - } + { + // Calculator for grouped consecutive values until group is cancelled: + var 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) => { + 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); + }; + + 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(); + // 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 + 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); + // 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)`: - { - var stream = Bacon.fromArray([1, 2, 3, 4, 5, 6, 7]); - stream.bufferWithTime(f => { - setTimeout(f, 10); - }); - } + // Here's an equivalent to `stream.bufferWithTime(10)`: + { + var 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); + // 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(); + // This creates the property which doesn't produce any events and never ends: + Bacon.interval(1e1, 0).toProperty().last(); - { - 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"); + { + 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"); - // A simpler example would be to toggle the visibility of an element based on a Property: - property.assign($("#my-button"), "toggle"); - } + // 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 + Bacon.fromArray([1, 2, 2, 1]).toProperty() + .skipDuplicates().log(); // > returns [1, 2, 1] in an order } function CombiningMultipleStreamsAndProperties() { - { - var property = Bacon.constant(1), - stream = Bacon.once(2), - constant = 3; - Bacon.combineAsArray(property, stream, constant) - .log(); // > returns [1, 2, 3] - } + { + var 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: - 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` - Bacon.combineWith((x:number, y:number, z:number) => x + y + z, property, stream, constant); - } + { + // To calculate the current sum of three numeric Properties, you can do: + 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` + 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: - var 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); - }); + { + // Assuming you've got streams or properties named `password`, `username`, `firstname` and `lastname`, you can do: + var 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(); - } + // 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(); + } - { - var 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]` - } + { + var 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); - }); + // 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"); + 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; - }); + // 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 => { - var isNonCriticalError = (error:string) => Math.random() < .5, - handleNonCriticalError = (error:string) => 42; - return isNonCriticalError(error) ? handleNonCriticalError(error) : new Bacon.Error(error); - }); + // Conversely, if you want to convert some Error events into value events, you may use `flatMapError`: + Bacon.fromArray([1, 2, 3, 4]).flatMapError(error => { + 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 => { - var dangerousFunction = (x:number) => { - throw new Error("dangerous function!"); - }; - try { - return dangerousFunction(x); - } catch (e) { - return new Bacon.Error(e); - } - }); + // 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 => { + var 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. - var ajaxCall = (url:string) => { - return Bacon.fromPromise($.ajax(url)); - }; - return Bacon.retry({ - source: () => ajaxCall(url), - retries: 5, - isRetryable: (error:JQueryXHR) => error.status !== 404, - delay: context => 100 // Just use the same delay always + Bacon.once("https://baconjs.github.io/").flatMap(url => { + // `ajaxCall` gives `Error`s on network or server `Error`s. + var ajaxCall = (url:string) => { + return Bacon.fromPromise($.ajax(url)); + }; + return Bacon.retry({ + source: () => ajaxCall(url), + retries: 5, + isRetryable: (error:JQueryXHR) => 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: - var 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. - } + { + // 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: + var 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: - 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}.`; - Bacon.zipWith(f, a, b, c); - Bacon.when([a, b, c], f); - } - { - // The inputs to `Bacon.update` are defined like this: - var 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: - var 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. - } + { + // 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: + 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}.`; + Bacon.zipWith(f, a, b, c); + Bacon.when([a, b, c], f); + } + { + // The inputs to `Bacon.update` are defined like this: + var 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: + var 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. + } + { + // Join patterns as a "chemical machine". A quick way to get some intuition for join patterns is to understand them through an analogy in terms of atoms and molecules. A join pattern can here be regarded as a recipe for a chemical reaction. Lets say we have observables `oxygen`, `carbon` and `hydrogen`, where an event in these spawns an 'atom' of that type into a mixture. We can state reactions: + let oxygen = Bacon.interval(1e3, "O"), + hydrogen = Bacon.interval(2e3, "H"), + carbon = Bacon.interval(1.5e3, "C"), + makeWater = (oxygen:string, hydrogen1:string, hydrogen2:string) => `${hydrogen1}${[hydrogen1, hydrogen2].length}${oxygen}`, + makeCarbonMonoxide = (oxygen:string, carbon:string) => `${carbon}${oxygen}`; + + Bacon.when( + [oxygen, hydrogen, hydrogen], makeWater, + [oxygen, carbon], makeCarbonMonoxide + ); + // Now, every time a new 'atom' is spawned from one of the observables, this atom is added to the mixture. If at any time there are two hydrogen atoms, and an oxygen atom, the corresponding atoms are *consumed*, and output is produced via `makeWater`. The same semantics apply for the second rule to create carbon monoxide. The rules are tried at each point from top to bottom. + } +} + +function JoinPatternsAndProperties() { + { + // Join patterns and properties + //Properties are not part of the synchronization pattern, but are instead just sampled. The following example take three input streams `$price`, `$quantity` and `$total`, e.g. coming from input fields, and defines mutally recursive behaviours in properties `price`, `quantity` and `total` such that + // -- updating price sets total to price * quantity; + // -- updating quantity sets total to price * quantity; + // -- updating total sets price to total / quantity. + let random = (x:number) => Math.round(x * Math.random()), + id = (x:A):A => x; + let $quantity = Bacon.interval(1e3, 10).map(random), + $price = Bacon.interval(2e3, 100).map(random), + $total = Bacon.interval(1.5e3, 1000).map(random); + let quantity = $quantity.toProperty(1), + price = Bacon.when( + [$price], id, + [$total, quantity], (x, y) => x / y + ).toProperty(0), + total = Bacon.when( + [$total], id, + [$price, quantity], (x, y) => x * y, + [price, $quantity], (x, y) => x * y + ).toProperty(0); + } +} + +function JoinPatternsAndBaconBus() { + { + // Join patterns and `Bacon.Bus` + // The result functions of join patterns are allowed to push values onto a `Bus` that may in turn be in one of its patterns. For instance, an implementation of the dining philosophers problem can be written as follows: + // Availability of chopsticks are implemented using bus. + let chopsticks = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + // Hungry could be any type of observable, but we'll use bus here. + hungry = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + // A philosopher eats for one second, then makes the chopsticks available again by pushing values onto their bus. + eat = (i:number) => () => { + setTimeout(() => { + console.log("done!"); + chopsticks[i].push({}); + chopsticks[(i + 1) % 3].push({}); + }, 1e3); + return `philosopher ${i} eating`; + }, + // We use Bacon.when to make sure a hungry philosopher can eat only when both his chopsticks are available. + dining = Bacon.when( + [hungry[0], chopsticks[0], chopsticks[1]], eat(0), + [hungry[1], chopsticks[1], chopsticks[2]], eat(1), + [hungry[2], chopsticks[2], chopsticks[0]], eat(2) + ).log("dining"); + // Make all chopsticks initially available. + chopsticks[0].push({}); + chopsticks[1].push({}); + chopsticks[2].push({}); + // Make philosophers hungry in some way, in this case we just push to their bus. + for (var i = 0; i < 3; i++) { + hungry[0].push({}); + hungry[1].push({}); + hungry[2].push({}); + } + } } diff --git a/baconjs/baconjs.d.ts b/baconjs/baconjs.d.ts index 2021b3dd7b..4717d0e956 100644 --- a/baconjs/baconjs.d.ts +++ b/baconjs/baconjs.d.ts @@ -4,2070 +4,2074 @@ // 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. + * @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; + /** + * @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#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; + /** + * @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|JQuery} target - * @param {string} eventName - * @returns {EventStream} - * @example - * Bacon.fromEvent(document.body, "click").onValue(() => { - * alert("Bacon!"); - * }); - * Bacon.fromEvent(process.stdin, "readable", () => { - * alert("Bacon!"); - * }); - * Bacon.fromEvent($("body"), "click").onValue(() => { - * alert("Bacon!"); - * }); - */ - function fromEvent(target:EventTarget|NodeJS.EventEmitter|JQuery, 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|JQuery} 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|JQuery, 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}. - */ - var 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}. - */ - var 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 + * @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); */ - bufferingThrottle(minimumInterval:number):EventStream; + function fromPromise(promise:Promise|JQueryXHR, abort?:boolean):EventStream; /** - * @callback Observable#flatMap~f + * @callback Bacon.fromPromise~eventTransformer * @param {A} value - * @returns {B|Initial|Next|End|Error|Observable} + * @returns {(Initial|Next|End|Error)[]} */ /** - * @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 + * @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 - * // Converting strings to integers, skipping empty values: - * Bacon.once("").flatMap(text => { - * return text != "" ? parseInt(text) : Bacon.never(); + * 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()]; * }); */ - flatMap(f:(value:A) => B|Initial|Next|End|Error|Observable):EventStream; + function fromPromise(promise:Promise|JQueryXHR, abort:boolean, eventTransformer:(value:A) => (Initial|Next|End|Error)[]):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} + * @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|JQuery} target + * @param {string} eventName + * @returns {EventStream} * @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]]; - * } + * Bacon.fromEvent(document.body, "click").onValue(() => { + * alert("Bacon!"); + * }); + * Bacon.fromEvent(process.stdin, "readable", () => { + * alert("Bacon!"); + * }); + * Bacon.fromEvent($("body"), "click").onValue(() => { + * alert("Bacon!"); * }); */ - withStateMachine(initState:B, f:(state:B, event:Initial|Next|End|Error) => [B, (Initial|Next|End|Error)[]]):EventStream; + function fromEvent(target:EventTarget|NodeJS.EventEmitter|JQuery, eventName:string):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 + * @callback Bacon.fromEvent~eventTransformer + * @param {A} event * @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 + * @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|JQuery} target + * @param {string} eventName + * @param {Bacon.fromEvent~eventTransformer} eventTransformer * @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); - * } + * Bacon.fromEvent(document.body, "click", (event:MouseEvent) => event.clientX).onValue(clientX => { + * alert("Bacon!"); * }); */ - withHandler(f:(event:Initial|Next|End|Error) => any):EventStream; + function fromEvent(target:EventTarget|NodeJS.EventEmitter|JQuery, eventName:string, eventTransformer:(event:A) => B):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 + * @callback Bacon.fromCallback1~f + * @param {Bacon.fromCallback1~callback} callback * @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 + * @callback Bacon.fromCallback1~callback * @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} + * @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 - * // 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); }); } + * // 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); + * }); */ - bufferWithTime(f:(defer:(...args:any[]) => void) => void):EventStream; + function fromCallback(f:(callback:(...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); + * @callback Bacon.fromCallback2~f + * @param {...*} args + * @returns {void} */ - bufferWithCount(count:number):EventStream; + /** + * @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; /** - * @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. + * @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 {number} count - * @returns {EventStream} + * @param {A} value + * @returns {EventStream} */ - bufferWithTimeOrCount(delay:number, count:number):EventStream; + function later(delay:number, value:A):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] + * @function + * @description Creates a constant [Property]{@link Bacon.Property} with value `x`. + * @param {A} x * @returns {Property} */ - toProperty(initialValue?:A):Property; - } + function constant(x:A):Property; - var EventStream:{ /** - * @callback EventStream#new~subscribe - * @param {EventStream#new~sink} sink - * @returns {EventStream#new~unsubscribe} + * @callback Bacon.fromBinder~subscribe + * @param {Bacon.fromBinder~sink} sink + * @returns {Bacon.fromBinder~unsubscribe} */ /** - * @callback EventStream#new~sink + * @callback Bacon.fromBinder~sink * @param {More|NoMore|(A|Initial|Next|End|Error)|(A|Initial|Next|End|Error)[]} value * @returns {void} */ /** - * @callback EventStream#new~unsubscribe + * @callback Bacon.fromBinder~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 + * @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} - */ - 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); - * } + * 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(); */ - withHandler(f:(event:Initial|Next|End|Error) => any):Property; + function fromBinder(subscribe:(sink:(value:More|NoMore|(A|Initial|Next|End|Error)|(A|Initial|Next|End|Error)[]) => void) => (() => void)):EventStream; /** - * @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} + * @interface + * @see Bacon.more */ - name(newName:string):Property; + interface More { + } + /** + * @property more + * @constant + * @description The opaque value `sink` function may return. See [Bacon.fromBinder]{@link Bacon.fromBinder}. + */ + var more:More; /** - * @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 + * @interface + * @see Bacon.noMore + */ + interface NoMore { + } + /** + * @property noMore + * @constant + * @description The opaque value `sink` function may return. See [Bacon.fromBinder]{@link Bacon.fromBinder}. + */ + var 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 {E} error + * @returns {void} + */ + error(error:E):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 - * 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 => { + * // 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 => { + * + * // 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 => { + * + * // 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!"); * }; @@ -2077,673 +2081,1053 @@ declare module Bacon { * return new Bacon.Error(e); * } * }); - */ - class Error extends Event { + */ + 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; + } + /** - * @constructor - * @constructs Error + * @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 - * */ - 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} + * @returns {boolean} */ /** - * @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 + * @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 - * new Bacon.Next(() => "value"); - * */ - constructor(f:() => A); - } + * { + * // 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); + * } + * + * { + * // Join patterns as a "chemical machine". + * // A quick way to get some intuition for join patterns is to understand them through an analogy in terms of atoms and molecules. A join pattern can here be regarded as a recipe for a chemical reaction. Lets say we have observables `oxygen`, `carbon` and `hydrogen`, where an event in these spawns an 'atom' of that type into a mixture. We can state reactions: + * let oxygen = Bacon.interval(1e3, "O"), + * hydrogen = Bacon.interval(2e3, "H"), + * carbon = Bacon.interval(1.5e3, "C"), + * makeWater = (oxygen:string, hydrogen1:string, hydrogen2:string) => `${hydrogen1}${[hydrogen1, hydrogen2].length}${oxygen}`, + * makeCarbonMonoxide = (oxygen:string, carbon:string) => `${carbon}${oxygen}`; + * Bacon.when( + * [oxygen, hydrogen, hydrogen], makeWater, + * [oxygen, carbon], makeCarbonMonoxide + * ); + * // Now, every time a new 'atom' is spawned from one of the observables, this atom is added to the mixture. If at any time there are two hydrogen atoms, and an oxygen atom, the corresponding atoms are *consumed*, and output is produced via `makeWater`. The same semantics apply for the second rule to create carbon monoxide. The rules are tried at each point from top to bottom. + * } + * + * { + * // Join patterns and properties. + * // Properties are not part of the synchronization pattern, but are instead just sampled. The following example take three input streams `$price`, `$quantity` and `$total`, e.g. coming from input fields, and defines mutally recursive behaviours in properties `price`, `quantity` and `total` such that: + * // -- updating `quantity` sets `total` to `price * quantity`; + * // -- updating `total` sets `price` to `total / quantity`. + * let random = (x:number) => Math.round(x * Math.random()), + * id = (x:A):A => x; + * let $quantity = Bacon.interval(1e3, 10).map(random), + * $price = Bacon.interval(2e3, 100).map(random), + * $total = Bacon.interval(1.5e3, 1000).map(random); + * let quantity = $quantity.toProperty(1), + * price = Bacon.when( + * [$price], id, + * [$total, quantity], (x, y) => x / y + * ).toProperty(0), + * total = Bacon.when( + * [$total], id, + * [$price, quantity], (x, y) => x * y, + * [price, $quantity], (x, y) => x * y + * ).toProperty(0); + * } + * + * { + * // Join patterns and `Bacon.Bus`. + * // The result functions of join patterns are allowed to push values onto a `Bus` that may in turn be in one of its patterns. For instance, an implementation of the dining philosophers problem can be written as follows: + * // Availability of chopsticks are implemented using bus. + * let chopsticks = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // Hungry could be any type of observable, but we'll use bus here. + * hungry = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // A philosopher eats for one second, then makes the chopsticks available again by pushing values onto their bus. + * eat = (i:number) => () => { + * setTimeout(() => { + * console.log("done!"); + * chopsticks[i].push({}); + * chopsticks[(i + 1) % 3].push({}); + * }, 1e3); + * return `philosopher ${i} eating`; + * }, + * // We use Bacon.when to make sure a hungry philosopher can eat only when both his chopsticks are available. + * dining = Bacon.when( + * [hungry[0], chopsticks[0], chopsticks[1]], eat(0), + * [hungry[1], chopsticks[1], chopsticks[2]], eat(1), + * [hungry[2], chopsticks[2], chopsticks[0]], eat(2) + * ).log("dining"); + * // Make all chopsticks initially available. + * chopsticks[0].push({}); + * chopsticks[1].push({}); + * chopsticks[2].push({}); + * // Make philosophers hungry in some way, in this case we just push to their bus. + * for (let i = 0; i < 3; i++) { + * hungry[0].push({}); + * hungry[1].push({}); + * hungry[2].push({}); + * } + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B):EventStream; - /** - * @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.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); + * } + * + * { + * // Join patterns as a "chemical machine". + * // A quick way to get some intuition for join patterns is to understand them through an analogy in terms of atoms and molecules. A join pattern can here be regarded as a recipe for a chemical reaction. Lets say we have observables `oxygen`, `carbon` and `hydrogen`, where an event in these spawns an 'atom' of that type into a mixture. We can state reactions: + * let oxygen = Bacon.interval(1e3, "O"), + * hydrogen = Bacon.interval(2e3, "H"), + * carbon = Bacon.interval(1.5e3, "C"), + * makeWater = (oxygen:string, hydrogen1:string, hydrogen2:string) => `${hydrogen1}${[hydrogen1, hydrogen2].length}${oxygen}`, + * makeCarbonMonoxide = (oxygen:string, carbon:string) => `${carbon}${oxygen}`; + * Bacon.when( + * [oxygen, hydrogen, hydrogen], makeWater, + * [oxygen, carbon], makeCarbonMonoxide + * ); + * // Now, every time a new 'atom' is spawned from one of the observables, this atom is added to the mixture. If at any time there are two hydrogen atoms, and an oxygen atom, the corresponding atoms are *consumed*, and output is produced via `makeWater`. The same semantics apply for the second rule to create carbon monoxide. The rules are tried at each point from top to bottom. + * } + * + * { + * // Join patterns and properties. + * // Properties are not part of the synchronization pattern, but are instead just sampled. The following example take three input streams `$price`, `$quantity` and `$total`, e.g. coming from input fields, and defines mutally recursive behaviours in properties `price`, `quantity` and `total` such that: + * // -- updating `quantity` sets `total` to `price * quantity`; + * // -- updating `total` sets `price` to `total / quantity`. + * let random = (x:number) => Math.round(x * Math.random()), + * id = (x:A):A => x; + * let $quantity = Bacon.interval(1e3, 10).map(random), + * $price = Bacon.interval(2e3, 100).map(random), + * $total = Bacon.interval(1.5e3, 1000).map(random); + * let quantity = $quantity.toProperty(1), + * price = Bacon.when( + * [$price], id, + * [$total, quantity], (x, y) => x / y + * ).toProperty(0), + * total = Bacon.when( + * [$total], id, + * [$price, quantity], (x, y) => x * y, + * [price, $quantity], (x, y) => x * y + * ).toProperty(0); + * } + * + * { + * // Join patterns and `Bacon.Bus`. + * // The result functions of join patterns are allowed to push values onto a `Bus` that may in turn be in one of its patterns. For instance, an implementation of the dining philosophers problem can be written as follows: + * // Availability of chopsticks are implemented using bus. + * let chopsticks = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // Hungry could be any type of observable, but we'll use bus here. + * hungry = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // A philosopher eats for one second, then makes the chopsticks available again by pushing values onto their bus. + * eat = (i:number) => () => { + * setTimeout(() => { + * console.log("done!"); + * chopsticks[i].push({}); + * chopsticks[(i + 1) % 3].push({}); + * }, 1e3); + * return `philosopher ${i} eating`; + * }, + * // We use Bacon.when to make sure a hungry philosopher can eat only when both his chopsticks are available. + * dining = Bacon.when( + * [hungry[0], chopsticks[0], chopsticks[1]], eat(0), + * [hungry[1], chopsticks[1], chopsticks[2]], eat(1), + * [hungry[2], chopsticks[2], chopsticks[0]], eat(2) + * ).log("dining"); + * // Make all chopsticks initially available. + * chopsticks[0].push({}); + * chopsticks[1].push({}); + * chopsticks[2].push({}); + * // Make philosophers hungry in some way, in this case we just push to their bus. + * for (let i = 0; i < 3; i++) { + * hungry[0].push({}); + * hungry[1].push({}); + * hungry[2].push({}); + * } + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B, pattern2:Observable[], f2:(...args:A2[]) => B):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.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); + * } + * + * { + * // Join patterns as a "chemical machine". + * // A quick way to get some intuition for join patterns is to understand them through an analogy in terms of atoms and molecules. A join pattern can here be regarded as a recipe for a chemical reaction. Lets say we have observables `oxygen`, `carbon` and `hydrogen`, where an event in these spawns an 'atom' of that type into a mixture. We can state reactions: + * let oxygen = Bacon.interval(1e3, "O"), + * hydrogen = Bacon.interval(2e3, "H"), + * carbon = Bacon.interval(1.5e3, "C"), + * makeWater = (oxygen:string, hydrogen1:string, hydrogen2:string) => `${hydrogen1}${[hydrogen1, hydrogen2].length}${oxygen}`, + * makeCarbonMonoxide = (oxygen:string, carbon:string) => `${carbon}${oxygen}`; + * Bacon.when( + * [oxygen, hydrogen, hydrogen], makeWater, + * [oxygen, carbon], makeCarbonMonoxide + * ); + * // Now, every time a new 'atom' is spawned from one of the observables, this atom is added to the mixture. If at any time there are two hydrogen atoms, and an oxygen atom, the corresponding atoms are *consumed*, and output is produced via `makeWater`. The same semantics apply for the second rule to create carbon monoxide. The rules are tried at each point from top to bottom. + * } + * + * { + * // Join patterns and properties. + * // Properties are not part of the synchronization pattern, but are instead just sampled. The following example take three input streams `$price`, `$quantity` and `$total`, e.g. coming from input fields, and defines mutally recursive behaviours in properties `price`, `quantity` and `total` such that: + * // -- updating `quantity` sets `total` to `price * quantity`; + * // -- updating `total` sets `price` to `total / quantity`. + * let random = (x:number) => Math.round(x * Math.random()), + * id = (x:A):A => x; + * let $quantity = Bacon.interval(1e3, 10).map(random), + * $price = Bacon.interval(2e3, 100).map(random), + * $total = Bacon.interval(1.5e3, 1000).map(random); + * let quantity = $quantity.toProperty(1), + * price = Bacon.when( + * [$price], id, + * [$total, quantity], (x, y) => x / y + * ).toProperty(0), + * total = Bacon.when( + * [$total], id, + * [$price, quantity], (x, y) => x * y, + * [price, $quantity], (x, y) => x * y + * ).toProperty(0); + * } + * + * { + * // Join patterns and `Bacon.Bus`. + * // The result functions of join patterns are allowed to push values onto a `Bus` that may in turn be in one of its patterns. For instance, an implementation of the dining philosophers problem can be written as follows: + * // Availability of chopsticks are implemented using bus. + * let chopsticks = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // Hungry could be any type of observable, but we'll use bus here. + * hungry = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // A philosopher eats for one second, then makes the chopsticks available again by pushing values onto their bus. + * eat = (i:number) => () => { + * setTimeout(() => { + * console.log("done!"); + * chopsticks[i].push({}); + * chopsticks[(i + 1) % 3].push({}); + * }, 1e3); + * return `philosopher ${i} eating`; + * }, + * // We use Bacon.when to make sure a hungry philosopher can eat only when both his chopsticks are available. + * dining = Bacon.when( + * [hungry[0], chopsticks[0], chopsticks[1]], eat(0), + * [hungry[1], chopsticks[1], chopsticks[2]], eat(1), + * [hungry[2], chopsticks[2], chopsticks[0]], eat(2) + * ).log("dining"); + * // Make all chopsticks initially available. + * chopsticks[0].push({}); + * chopsticks[1].push({}); + * chopsticks[2].push({}); + * // Make philosophers hungry in some way, in this case we just push to their bus. + * for (let i = 0; i < 3; i++) { + * hungry[0].push({}); + * hungry[1].push({}); + * hungry[2].push({}); + * } + * } + */ + function when(pattern1:Observable[], f1:(...args:A1[]) => B, pattern2:Observable[], f2:(...args:A2[]) => B, pattern3:Observable[], f3:(...args:A3[]) => B):EventStream; - /** - * @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.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); + * } + * + * { + * // Join patterns as a "chemical machine". + * // A quick way to get some intuition for join patterns is to understand them through an analogy in terms of atoms and molecules. A join pattern can here be regarded as a recipe for a chemical reaction. Lets say we have observables `oxygen`, `carbon` and `hydrogen`, where an event in these spawns an 'atom' of that type into a mixture. We can state reactions: + * let oxygen = Bacon.interval(1e3, "O"), + * hydrogen = Bacon.interval(2e3, "H"), + * carbon = Bacon.interval(1.5e3, "C"), + * makeWater = (oxygen:string, hydrogen1:string, hydrogen2:string) => `${hydrogen1}${[hydrogen1, hydrogen2].length}${oxygen}`, + * makeCarbonMonoxide = (oxygen:string, carbon:string) => `${carbon}${oxygen}`; + * Bacon.when( + * [oxygen, hydrogen, hydrogen], makeWater, + * [oxygen, carbon], makeCarbonMonoxide + * ); + * // Now, every time a new 'atom' is spawned from one of the observables, this atom is added to the mixture. If at any time there are two hydrogen atoms, and an oxygen atom, the corresponding atoms are *consumed*, and output is produced via `makeWater`. The same semantics apply for the second rule to create carbon monoxide. The rules are tried at each point from top to bottom. + * } + * + * { + * // Join patterns and properties. + * // Properties are not part of the synchronization pattern, but are instead just sampled. The following example take three input streams `$price`, `$quantity` and `$total`, e.g. coming from input fields, and defines mutally recursive behaviours in properties `price`, `quantity` and `total` such that: + * // -- updating `quantity` sets `total` to `price * quantity`; + * // -- updating `total` sets `price` to `total / quantity`. + * let random = (x:number) => Math.round(x * Math.random()), + * id = (x:A):A => x; + * let $quantity = Bacon.interval(1e3, 10).map(random), + * $price = Bacon.interval(2e3, 100).map(random), + * $total = Bacon.interval(1.5e3, 1000).map(random); + * let quantity = $quantity.toProperty(1), + * price = Bacon.when( + * [$price], id, + * [$total, quantity], (x, y) => x / y + * ).toProperty(0), + * total = Bacon.when( + * [$total], id, + * [$price, quantity], (x, y) => x * y, + * [price, $quantity], (x, y) => x * y + * ).toProperty(0); + * } + * + * { + * // Join patterns and `Bacon.Bus`. + * // The result functions of join patterns are allowed to push values onto a `Bus` that may in turn be in one of its patterns. For instance, an implementation of the dining philosophers problem can be written as follows: + * // Availability of chopsticks are implemented using bus. + * let chopsticks = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // Hungry could be any type of observable, but we'll use bus here. + * hungry = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // A philosopher eats for one second, then makes the chopsticks available again by pushing values onto their bus. + * eat = (i:number) => () => { + * setTimeout(() => { + * console.log("done!"); + * chopsticks[i].push({}); + * chopsticks[(i + 1) % 3].push({}); + * }, 1e3); + * return `philosopher ${i} eating`; + * }, + * // We use Bacon.when to make sure a hungry philosopher can eat only when both his chopsticks are available. + * dining = Bacon.when( + * [hungry[0], chopsticks[0], chopsticks[1]], eat(0), + * [hungry[1], chopsticks[1], chopsticks[2]], eat(1), + * [hungry[2], chopsticks[2], chopsticks[0]], eat(2) + * ).log("dining"); + * // Make all chopsticks initially available. + * chopsticks[0].push({}); + * chopsticks[1].push({}); + * chopsticks[2].push({}); + * // Make philosophers hungry in some way, in this case we just push to their bus. + * for (let i = 0; i < 3; i++) { + * hungry[0].push({}); + * hungry[1].push({}); + * hungry[2].push({}); + * } + * } + */ + 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.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.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); + * } + * + * { + * // Join patterns as a "chemical machine". + * // A quick way to get some intuition for join patterns is to understand them through an analogy in terms of atoms and molecules. A join pattern can here be regarded as a recipe for a chemical reaction. Lets say we have observables `oxygen`, `carbon` and `hydrogen`, where an event in these spawns an 'atom' of that type into a mixture. We can state reactions: + * let oxygen = Bacon.interval(1e3, "O"), + * hydrogen = Bacon.interval(2e3, "H"), + * carbon = Bacon.interval(1.5e3, "C"), + * makeWater = (oxygen:string, hydrogen1:string, hydrogen2:string) => `${hydrogen1}${[hydrogen1, hydrogen2].length}${oxygen}`, + * makeCarbonMonoxide = (oxygen:string, carbon:string) => `${carbon}${oxygen}`; + * Bacon.when( + * [oxygen, hydrogen, hydrogen], makeWater, + * [oxygen, carbon], makeCarbonMonoxide + * ); + * // Now, every time a new 'atom' is spawned from one of the observables, this atom is added to the mixture. If at any time there are two hydrogen atoms, and an oxygen atom, the corresponding atoms are *consumed*, and output is produced via `makeWater`. The same semantics apply for the second rule to create carbon monoxide. The rules are tried at each point from top to bottom. + * } + * + * { + * // Join patterns and properties. + * // Properties are not part of the synchronization pattern, but are instead just sampled. The following example take three input streams `$price`, `$quantity` and `$total`, e.g. coming from input fields, and defines mutally recursive behaviours in properties `price`, `quantity` and `total` such that: + * // -- updating `quantity` sets `total` to `price * quantity`; + * // -- updating `total` sets `price` to `total / quantity`. + * let random = (x:number) => Math.round(x * Math.random()), + * id = (x:A):A => x; + * let $quantity = Bacon.interval(1e3, 10).map(random), + * $price = Bacon.interval(2e3, 100).map(random), + * $total = Bacon.interval(1.5e3, 1000).map(random); + * let quantity = $quantity.toProperty(1), + * price = Bacon.when( + * [$price], id, + * [$total, quantity], (x, y) => x / y + * ).toProperty(0), + * total = Bacon.when( + * [$total], id, + * [$price, quantity], (x, y) => x * y, + * [price, $quantity], (x, y) => x * y + * ).toProperty(0); + * } + * + * { + * // Join patterns and `Bacon.Bus`. + * // The result functions of join patterns are allowed to push values onto a `Bus` that may in turn be in one of its patterns. For instance, an implementation of the dining philosophers problem can be written as follows: + * // Availability of chopsticks are implemented using bus. + * let chopsticks = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // Hungry could be any type of observable, but we'll use bus here. + * hungry = [new Bacon.Bus(), new Bacon.Bus(), new Bacon.Bus()], + * // A philosopher eats for one second, then makes the chopsticks available again by pushing values onto their bus. + * eat = (i:number) => () => { + * setTimeout(() => { + * console.log("done!"); + * chopsticks[i].push({}); + * chopsticks[(i + 1) % 3].push({}); + * }, 1e3); + * return `philosopher ${i} eating`; + * }, + * // We use Bacon.when to make sure a hungry philosopher can eat only when both his chopsticks are available. + * dining = Bacon.when( + * [hungry[0], chopsticks[0], chopsticks[1]], eat(0), + * [hungry[1], chopsticks[1], chopsticks[2]], eat(1), + * [hungry[2], chopsticks[2], chopsticks[0]], eat(2) + * ).log("dining"); + * // Make all chopsticks initially available. + * chopsticks[0].push({}); + * chopsticks[1].push({}); + * chopsticks[2].push({}); + * // Make philosophers hungry in some way, in this case we just push to their bus. + * for (let i = 0; i < 3; i++) { + * hungry[0].push({}); + * hungry[1].push({}); + * hungry[2].push({}); + * } + * } + */ + 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.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.update1~f1 + * @param {B} initial + * @param {...A1} args + * @returns {B} + */ + /** + * @method Bacon.update1 + * @description Creates an [Property]{@link Bacon.Property} from an `initial` value and a join-pattern system. + * @param {B} initial + * @param {Observable[]} pattern1 + * @param {Bacon.update1~f1} f1 + * @returns {Property} + * @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[]) => B):Property; - /** - * @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.update2~f1 + * @param {B} initial + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update2~f2 + * @param {B} initial + * @param {...A2} args + * @returns {B} + */ + /** + * @method Bacon.update2 + * @description Creates an [Property]{@link Bacon.Property} 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 {Property} + * @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[]) => B, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => B):Property; - /** - * @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.update3~f1 + * @param {B} initial + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update3~f2 + * @param {B} initial + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.update3~f3 + * @param {B} initial + * @param {...A3} args + * @returns {B} + */ + /** + * @method Bacon.update3 + * @description Creates an [Property]{@link Bacon.Property} 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 {Property} + * @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[]) => B, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => B, pattern3:Observable[], f3:(initial:B, ...args:A3[]) => B):Property; - /** - * @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.update4~f1 + * @param {B} initial + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update4~f2 + * @param {B} initial + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.update4~f3 + * @param {B} initial + * @param {...A3} args + * @returns {B} + */ + /** + * @callback Bacon.update4~f4 + * @param {B} initial + * @param {...A4} args + * @returns {B} + */ + /** + * @method Bacon.update4 + * @description Creates an [Property]{@link Bacon.Property} 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 {Property} + * @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[]) => B, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => B, pattern3:Observable[], f3:(initial:B, ...args:A3[]) => B, pattern4:Observable[], f4:(initial:B, ...args:A4[]) => B):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; + /** + * @callback Bacon.update5~f1 + * @param {B} initial + * @param {...A1} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f2 + * @param {B} initial + * @param {...A2} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f3 + * @param {B} initial + * @param {...A3} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f4 + * @param {B} initial + * @param {...A4} args + * @returns {B} + */ + /** + * @callback Bacon.update5~f5 + * @param {B} initial + * @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 {Property} + * @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[]) => B, pattern2:Observable[], f2:(initial:B, ...args:A2[]) => B, pattern3:Observable[], f3:(initial:B, ...args:A3[]) => B, pattern4:Observable[], f4:(initial:B, ...args:A4[]) => B, pattern5:Observable[], f5:(initial:B, ...args:A5[]) => B):Property; } declare module "baconjs" { - export = Bacon; + export = Bacon; } diff --git a/bootstrap/bootstrap.d.ts b/bootstrap/bootstrap.d.ts index b9fe9cd597..47a992fba5 100644 --- a/bootstrap/bootstrap.d.ts +++ b/bootstrap/bootstrap.d.ts @@ -7,7 +7,7 @@ /// interface ModalOptions { - backdrop?: boolean; + backdrop?: boolean|string; keyboard?: boolean; show?: boolean; remote?: string; diff --git a/codemirror/codemirror.d.ts b/codemirror/codemirror.d.ts index 5fc335ed64..198eaa0a4d 100644 --- a/codemirror/codemirror.d.ts +++ b/codemirror/codemirror.d.ts @@ -7,6 +7,8 @@ declare function CodeMirror(host: HTMLElement, options?: CodeMirror.EditorConfig declare function CodeMirror(callback: (host: HTMLElement) => void , options?: CodeMirror.EditorConfiguration): CodeMirror.Editor; declare module CodeMirror { + export var Doc : CodeMirror.Doc; + export var Pos: CodeMirror.Position; export var Pass: any; function fromTextArea(host: HTMLTextAreaElement, options?: EditorConfiguration): CodeMirror.EditorFromTextArea; @@ -387,8 +389,8 @@ declare module CodeMirror { getTextArea(): HTMLTextAreaElement; } - class Doc { - constructor (text: string, mode?: any, firstLineNumber?: number); + interface Doc { + new (text: string, mode?: any, firstLineNumber?: number): Doc; /** Get the current editor content. You can pass it an optional argument to specify the string to be used to separate lines (defaults to "\n"). */ getValue(seperator?: string): string; @@ -618,6 +620,7 @@ declare module CodeMirror { } interface Position { + new (line: number, ch: number): Position; ch: number; line: number; } diff --git a/colors/colors-tests.ts b/colors/colors-tests.ts index a7f595fdf1..15fd5ab4e5 100644 --- a/colors/colors-tests.ts +++ b/colors/colors-tests.ts @@ -3,16 +3,9 @@ import colors = require("colors"); -var test:string = 'test'; -var arr:string[] = ['color', 'odd'.italic.zebra, 'radical'.bold.rainbow, test.underline + 'super'.green]; - -colors.black("abc").trim(); -colors.red("abc").trim(); -colors.green("abc").trim(); -colors.yellow("abc").trim(); -colors.blue("abc").trim(); -colors.magenta("abc").trim(); -colors.cyan("abc").trim(); -colors.white("abc").trim(); -colors.gray("abc").trim(); -colors.grey("abc").trim(); +console.log(colors.black.underline('test')); +console.log(colors.rainbow.black.blue.gray('test')); +console.log(colors.random.reset.bgWhite.dim('test')); +console.log('test'.black.underline); +console.log('test'.rainbow.black.blue.gray); +console.log('test'.random.reset.bgWhite.dim); diff --git a/colors/colors.d.ts b/colors/colors.d.ts index 8332ac5bb9..5aa28553a3 100644 --- a/colors/colors.d.ts +++ b/colors/colors.d.ts @@ -4,34 +4,120 @@ // Definitions: https://github.com/borisyankov/DefinitelyTyped declare module "colors" { - export function setTheme(theme:any):any; + interface Color { + (text: string): string; - export function black(text: string): string; - export function red(text: string): string; - export function green(text: string): string; - export function yellow(text: string): string; - export function blue(text: string): string; - export function magenta(text: string): string; - export function cyan(text: string): string; - export function white(text: string): string; - export function gray(text: string): string; - export function grey(text: string): string; + black: Color; + red: Color; + green: Color; + yellow: Color; + blue: Color; + magenta: Color; + cyan: Color; + white: Color; + gray: Color; + grey: Color; + + bgBlack: Color; + bgRed: Color; + bgGreen: Color; + bgYellow: Color; + bgBlue: Color; + bgMagenta: Color; + bgCyan: Color; + bgWhite: Color; + + reset: Color; + bold: Color; + dim: Color; + italic: Color; + underline: Color; + inverse: Color; + hidden: Color; + strikethrough: Color; + + rainbow: Color; + zebra: Color; + america: Color; + trap: Color; + random: Color; + } + + module e { + export function setTheme(theme:any): void; + + export var black: Color; + export var red: Color; + export var green: Color; + export var yellow: Color; + export var blue: Color; + export var magenta: Color; + export var cyan: Color; + export var white: Color; + export var gray: Color; + export var grey: Color; + + export var bgBlack: Color; + export var bgRed: Color; + export var bgGreen: Color; + export var bgYellow: Color; + export var bgBlue: Color; + export var bgMagenta: Color; + export var bgCyan: Color; + export var bgWhite: Color; + + export var reset: Color; + export var bold: Color; + export var dim: Color; + export var italic: Color; + export var underline: Color; + export var inverse: Color; + export var hidden: Color; + export var strikethrough: Color; + + export var rainbow: Color; + export var zebra: Color; + export var america: Color; + export var trap: Color; + export var random: Color; + } + + export = e; } interface String { - bold:string; - italic:string; - underline:string; - inverse:string; - yellow:string; - cyan:string; - white:string; - magenta:string; - green:string; - red:string; - grey:string; - blue:string; - rainbow:string; - zebra:string; - random:string; + black: string; + red: string; + green: string; + yellow: string; + blue: string; + magenta: string; + cyan: string; + white: string; + gray: string; + grey: string; + + bgBlack: string; + bgRed: string; + bgGreen: string; + bgYellow: string; + bgBlue: string; + bgMagenta: string; + bgCyan: string; + bgWhite: string; + + reset: string; + bold: string; + dim: string; + italic: string; + underline: string; + inverse: string; + hidden: string; + strikethrough: string; + + rainbow: string; + zebra: string; + america: string; + trap: string; + random: string; } diff --git a/d3/d3.d.ts b/d3/d3.d.ts index 50d6fbdaa8..a4431b0f35 100644 --- a/d3/d3.d.ts +++ b/d3/d3.d.ts @@ -74,16 +74,16 @@ declare module d3 { * Derive an attribute value for each node in the selection based on bound data. * * @param name The attribute name, optionally prefixed. - * @param value The function of the datum (the bound data item) and index (the position in the subgrouping) which computes the attribute value. If the function returns null, the attribute is removed. + * @param value The function of the datum (the bound data item), index (the position in the subgrouping), and outer index (overall position in nested selections) which computes the attribute value. If the function returns null, the attribute is removed. */ - attr(name: string, value: (datum: Datum, index: number) => Primitive): Update; + attr(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive): Update; /** * Set multiple properties at once using an Object. D3 iterates over all enumerable properties and either sets or computes the attribute's value based on the corresponding entry in the Object. * * @param obj A key-value mapping corresponding to attributes and values. If the value is a simple string or number, it is taken as a constant. Otherwise, it is a function that derives the attribute value. */ - attr(obj: { [key: string]: Primitive | ((datum: Datum, index: number) => Primitive) }): Update; + attr(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }): Update; /** * Returns true if the first node in this selection has the given class list. If multiple classes are specified (i.e., "foo bar"), then returns true only if all classes match. @@ -106,14 +106,14 @@ declare module d3 { * @param name The class list. Spaces separate multiple class names. * @param value The function to run for each node. Should return true to add the class to the node, or false to remove it. */ - classed(name: string, value: (datum: Datum, index: number) => boolean): Update; + classed(name: string, value: (datum: Datum, index: number, outerIndex: number) => boolean): Update; /** * Set or derive classes for multiple class lists at once. * * @param obj An Object mapping class lists to values that are either plain booleans or functions that return booleans. */ - classed(obj: { [key: string]: boolean | ((datum: Datum, index: number) => boolean) }): Update; + classed(obj: { [key: string]: boolean | ((datum: Datum, index: number, outerIndex: number) => boolean) }): Update; /** * Retrieve the computed style value for the first node in the selection. @@ -135,7 +135,7 @@ declare module d3 { * @param value the function to derive the value * @param priority if specified, either null or the string "important" (no exclamation mark) */ - style(name: string, value: (datum: Datum, index: number) => Primitive, priority?: string): Update; + style(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive, priority?: string): Update; /** * Set a large number of CSS properties from an object. @@ -143,7 +143,7 @@ declare module d3 { * @param obj an Object whose keys correspond to CSS property names and values are either constants or functions that derive property values * @param priority if specified, either null or the string "important" (no exclamation mark) */ - style(obj: { [key: string]: Primitive | ((datum: Datum, index: number) => Primitive) }, priority?: string): Update; + style(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }, priority?: string): Update; /** * Retrieve an arbitrary node property such as the 'checked' property of checkboxes, or the 'value' of text boxes. @@ -166,14 +166,14 @@ declare module d3 { * @param name the property name * @param value the function used to derive the property's value */ - property(name: string, value: (datum: Datum, index: number) => any): Update; + property(name: string, value: (datum: Datum, index: number, outerIndex: number) => any): Update; /** * Set multiple node properties. Caveats apply: take care not to mutate special properties like __proto__. * * @param obj an Object whose keys correspond to node properties and values are either constants or functions that will compute a value. */ - property(obj: { [key: string]: any | ((datum: Datum, index: number) => any) }): Update; + property(obj: { [key: string]: any | ((datum: Datum, index: number, outerIndex: number) => any) }): Update; /** * Retrieve the textContent of the first node in the selection. @@ -190,7 +190,7 @@ declare module d3 { * Compute the textContent of each node in the selection. * @param value the function which will compute the text */ - text(value: (datum: Datum, index: number) => Primitive): Update; + text(value: (datum: Datum, index: number, outerIndex: number) => Primitive): Update; /** * Retrieve the HTML content of the first node in the selection. Uses 'innerHTML' internally and will not work with SVG or other elements without a polyfill. @@ -207,7 +207,7 @@ declare module d3 { * Compute the HTML content for each node in the selection. Uses 'innerHTML' internally and thus will not work with SVG or other elements without a polyfill. * @param value the function to compute HTML content */ - html(value: (datum: Datum, index: number) => string): Selection; + html(value: (datum: Datum, index: number, outerIndex: number) => string): Selection; /** * Appends a new child to each node in the selection. This child will inherit the parent's data (if available). Returns a fresh selection consisting of the newly-appended children. @@ -221,7 +221,7 @@ declare module d3 { * * @param name the function to compute a new element */ - append(name: (datum: Datum, index: number) => EventTarget): Update; + append(name: (datum: Datum, index: number, outerIndex: number) => EventTarget): Update; /** * Inserts a new child to each node in the selection. This child will inherit its parent's data (if available). Returns a fresh selection consisting of the newly-inserted children. @@ -235,21 +235,21 @@ declare module d3 { * @param name the element name to append. May be prefixed (see d3.ns.prefix). * @param before a function to determine the node to use as the next sibling */ - insert(name: string, before: (datum: Datum, index: number) => EventTarget): Update; + insert(name: string, before: (datum: Datum, index: number, outerIndex: number) => EventTarget): Update; /** * Inserts a new child to the end of each node in the selection by computing a new node. This child will inherit its parent's data (if available). Returns a fresh selection consisting of the newly-inserted children. * @param name the function to compute a new child * @param before the selector to determine position (e.g., ":first-child") */ - insert(name: (datum: Datum, index: number) => EventTarget, before: string): Update; + insert(name: (datum: Datum, index: number, outerIndex: number) => EventTarget, before: string): Update; /** * Inserts a new child to the end of each node in the selection by computing a new node. This child will inherit its parent's data (if available). Returns a fresh selection consisting of the newly-inserted children. * @param name the function to compute a new child * @param before a function to determine the node to use as the next sibling */ - insert(name: (datum: Datum, index: number) => EventTarget, before: (datum: Datum, index: number) => EventTarget): Update; + insert(name: (datum: Datum, index: number, outerIndex: number) => EventTarget, before: (datum: Datum, index: number, outerIndex: number) => EventTarget): Update; /** * Removes the elements from the DOM. They are in a detached state and may be re-added (though there is currently no dedicated API for doing so). @@ -266,14 +266,14 @@ declare module d3 { * @param data the array of data to bind to this selection * @param key the optional function to determine the unique key for each piece of data. When unspecified, uses the index of the element. */ - data(data: NewDatum[], key?: (datum: NewDatum, index: number) => string): Update; + data(data: NewDatum[], key?: (datum: NewDatum, index: number, outerIndex: number) => string): Update; /** * Derives data to bind to this selection. * @param data the function to derive data. Must return an array. * @param key the optional function to determine the unique key for each data item. When unspecified, uses the index of the element. */ - data(data: (datum: Datum, index: number) => NewDatum[], key?: (datum: NewDatum, index: number) => string): Update; + data(data: (datum: Datum, index: number, outerIndex: number) => NewDatum[], key?: (datum: NewDatum, index: number, outerIndex: number) => string): Update; /** * Filters the selection, returning only those nodes that match the given CSS selector. @@ -285,7 +285,7 @@ declare module d3 { * Filters the selection, returning only those nodes for which the given function returned true. * @param selector the filter function */ - filter(selector: (datum: Datum, index: number) => boolean): Update; + filter(selector: (datum: Datum, index: number, outerIndex: number) => boolean): Update; /** * Return the data item bound to the first element in the selection. @@ -302,7 +302,7 @@ declare module d3 { * Derive the data item for each node in the selection. Useful for situations such as the HTML5 'dataset' attribute. * @param value the function to compute data for each node */ - datum(value: (datum: Datum, index: number) => NewDatum): Update; + datum(value: (datum: Datum, index: number, outerIndex: number) => NewDatum): Update; /** * Reorders nodes in the selection based on the given comparator. Nodes are re-inserted into the document once sorted. @@ -319,7 +319,7 @@ declare module d3 { * Returns the listener (if any) for the given event. * @param type the type of event to load the listener for. May have a namespace (e.g., ".foo") at the end. */ - on(type: string): (datum: Datum, index: number) => any; + on(type: string): (datum: Datum, index: number, outerIndex: number) => any; /** * Adds a listener for the specified event. If one was already registered, it is removed before the new listener is added. The return value of the listener function is ignored. @@ -327,7 +327,7 @@ declare module d3 { * @param listener an event listener function, or null to unregister * @param capture sets the DOM useCapture flag */ - on(type: string, listener: (datum: Datum, index: number) => any, capture?: boolean): Update; + on(type: string, listener: (datum: Datum, index: number, outerIndex: number) => any, capture?: boolean): Update; /** * Begins a new transition. Interrupts any active transitions of the same name. @@ -351,7 +351,7 @@ declare module d3 { * Creates a subselection by using a function to find descendent elements. Bound data is inherited. * @param selector the function to find matching descendants */ - select(selector: (datum: Datum, index: number) => EventTarget): Update; + select(selector: (datum: Datum, index: number, outerIndex: number) => EventTarget): Update; /** * Creates a subselection by finding all descendents that match the given selector. Bound data is not inherited. @@ -363,13 +363,13 @@ declare module d3 { * Creates a subselection by using a function to find descendent elements. Bound data is not inherited. * @param selector the function to find matching descendents */ - selectAll(selector: (datum: Datum, index: number) => Array | NodeList): Update; + selectAll(selector: (datum: Datum, index: number, outerIndex: number) => Array | NodeList): Update; /** * Invoke the given function for each element in the selection. The return value of the function is ignored. * @param func the function to invoke */ - each(func: (datum: Datum, index: number) => any): Update; + each(func: (datum: Datum, index: number, outerIndex: number) => any): Update; /** * Call a function on the selection. sel.call(foo) is equivalent to foo(sel). @@ -406,14 +406,14 @@ declare module d3 { interface Enter { append(name: string): Selection; - append(name: (datum: Datum, index: number) => EventTarget): Selection; + append(name: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; insert(name: string, before?: string): Selection; - insert(name: string, before: (datum: Datum, index: number) => EventTarget): Selection; - insert(name: (datum: Datum, index: number) => EventTarget, before?: string): Selection; - insert(name: (datum: Datum, index: number) => EventTarget, before: (datum: Datum, index: number) => EventTarget): Selection; + insert(name: string, before: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; + insert(name: (datum: Datum, index: number, outerIndex: number) => EventTarget, before?: string): Selection; + insert(name: (datum: Datum, index: number, outerIndex: number) => EventTarget, before: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; - select(name: (datum: Datum, index: number) => EventTarget): Selection; + select(name: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; call(func: (selection: Enter, ...args: any[]) => any, ...args: any[]): Enter; } } @@ -464,16 +464,16 @@ declare module d3 { * Derive an attribute value for each node in the selection based on bound data. * * @param name The attribute name, optionally prefixed. - * @param value The function of the datum (the bound data item) and index (the position in the subgrouping) which computes the attribute value. If the function returns null, the attribute is removed. + * @param value The function of the datum (the bound data item), index (the position in the subgrouping), and outer index (overall position in nested selections) which computes the attribute value. If the function returns null, the attribute is removed. */ - attr(name: string, value: (datum: Datum, index: number) => Primitive): Selection; + attr(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive): Selection; /** * Set multiple properties at once using an Object. D3 iterates over all enumerable properties and either sets or computes the attribute's value based on the corresponding entry in the Object. * * @param obj A key-value mapping corresponding to attributes and values. If the value is a simple string or number, it is taken as a constant. Otherwise, it is a function that derives the attribute value. */ - attr(obj: { [key: string]: Primitive | ((datum: Datum, index: number) => Primitive) }): Selection; + attr(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }): Selection; /** * Returns true if the first node in this selection has the given class list. If multiple classes are specified (i.e., "foo bar"), then returns true only if all classes match. @@ -496,14 +496,14 @@ declare module d3 { * @param name The class list. Spaces separate multiple class names. * @param value The function to run for each node. Should return true to add the class to the node, or false to remove it. */ - classed(name: string, value: (datum: Datum, index: number) => boolean): Selection; + classed(name: string, value: (datum: Datum, index: number, outerIndex: number) => boolean): Selection; /** * Set or derive classes for multiple class lists at once. * * @param obj An Object mapping class lists to values that are either plain booleans or functions that return booleans. */ - classed(obj: { [key: string]: boolean | ((datum: Datum, index: number) => boolean) }): Selection; + classed(obj: { [key: string]: boolean | ((datum: Datum, index: number, outerIndex: number) => boolean) }): Selection; /** * Retrieve the computed style value for the first node in the selection. @@ -525,7 +525,7 @@ declare module d3 { * @param value the function to derive the value * @param priority if specified, either null or the string "important" (no exclamation mark) */ - style(name: string, value: (datum: Datum, index: number) => Primitive, priority?: string): Selection; + style(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive, priority?: string): Selection; /** * Set a large number of CSS properties from an object. @@ -533,7 +533,7 @@ declare module d3 { * @param obj an Object whose keys correspond to CSS property names and values are either constants or functions that derive property values * @param priority if specified, either null or the string "important" (no exclamation mark) */ - style(obj: { [key: string]: Primitive | ((datum: Datum, index: number) => Primitive) }, priority?: string): Selection; + style(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }, priority?: string): Selection; /** * Retrieve an arbitrary node property such as the 'checked' property of checkboxes, or the 'value' of text boxes. @@ -556,14 +556,14 @@ declare module d3 { * @param name the property name * @param value the function used to derive the property's value */ - property(name: string, value: (datum: Datum, index: number) => any): Selection; + property(name: string, value: (datum: Datum, index: number, outerIndex: number) => any): Selection; /** * Set multiple node properties. Caveats apply: take care not to mutate special properties like __proto__. * * @param obj an Object whose keys correspond to node properties and values are either constants or functions that will compute a value. */ - property(obj: { [key: string]: any | ((datum: Datum, index: number) => any) }): Selection; + property(obj: { [key: string]: any | ((datum: Datum, index: number, innerInder: number) => any) }): Selection; /** * Retrieve the textContent of the first node in the selection. @@ -580,7 +580,7 @@ declare module d3 { * Compute the textContent of each node in the selection. * @param value the function which will compute the text */ - text(value: (datum: Datum, index: number) => Primitive): Selection; + text(value: (datum: Datum, index: number, outerIndex: number) => Primitive): Selection; /** * Retrieve the HTML content of the first node in the selection. Uses 'innerHTML' internally and will not work with SVG or other elements without a polyfill. @@ -597,7 +597,7 @@ declare module d3 { * Compute the HTML content for each node in the selection. Uses 'innerHTML' internally and thus will not work with SVG or other elements without a polyfill. * @param value the function to compute HTML content */ - html(value: (datum: Datum, index: number) => string): Selection; + html(value: (datum: Datum, index: number, outerIndex: number) => string): Selection; /** * Appends a new child to each node in the selection. This child will inherit the parent's data (if available). Returns a fresh selection consisting of the newly-appended children. @@ -611,7 +611,7 @@ declare module d3 { * * @param name the function to compute a new element */ - append(name: (datum: Datum, index: number) => EventTarget): Selection; + append(name: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; /** * Inserts a new child to each node in the selection. This child will inherit its parent's data (if available). Returns a fresh selection consisting of the newly-inserted children. @@ -625,21 +625,21 @@ declare module d3 { * @param name the element name to append. May be prefixed (see d3.ns.prefix). * @param before a function to determine the node to use as the next sibling */ - insert(name: string, before: (datum: Datum, index: number) => EventTarget): Selection; + insert(name: string, before: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; /** * Inserts a new child to the end of each node in the selection by computing a new node. This child will inherit its parent's data (if available). Returns a fresh selection consisting of the newly-inserted children. * @param name the function to compute a new child * @param before the selector to determine position (e.g., ":first-child") */ - insert(name: (datum: Datum, index: number) => EventTarget, before: string): Selection; + insert(name: (datum: Datum, index: number, outerIndex: number) => EventTarget, before: string): Selection; /** * Inserts a new child to the end of each node in the selection by computing a new node. This child will inherit its parent's data (if available). Returns a fresh selection consisting of the newly-inserted children. * @param name the function to compute a new child * @param before a function to determine the node to use as the next sibling */ - insert(name: (datum: Datum, index: number) => EventTarget, before: (datum: Datum, index: number) => EventTarget): Selection; + insert(name: (datum: Datum, index: number, outerIndex: number) => EventTarget, before: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; /** * Removes the elements from the DOM. They are in a detached state and may be re-added (though there is currently no dedicated API for doing so). @@ -656,14 +656,14 @@ declare module d3 { * @param data the array of data to bind to this selection * @param key the optional function to determine the unique key for each piece of data. When unspecified, uses the index of the element. */ - data(data: NewDatum[], key?: (datum: NewDatum, index: number) => string): selection.Update; + data(data: NewDatum[], key?: (datum: NewDatum, index: number, outerIndex: number) => string): selection.Update; /** * Derives data to bind to this selection. * @param data the function to derive data. Must return an array. * @param key the optional function to determine the unique key for each data item. When unspecified, uses the index of the element. */ - data(data: (datum: Datum, index: number) => NewDatum[], key?: (datum: NewDatum, index: number) => string): selection.Update; + data(data: (datum: Datum, index: number, outerIndex: number) => NewDatum[], key?: (datum: NewDatum, index: number, outerIndex: number) => string): selection.Update; /** * Filters the selection, returning only those nodes that match the given CSS selector. @@ -675,7 +675,7 @@ declare module d3 { * Filters the selection, returning only those nodes for which the given function returned true. * @param selector the filter function */ - filter(selector: (datum: Datum, index: number) => boolean): Selection; + filter(selector: (datum: Datum, index: number, outerIndex: number) => boolean): Selection; /** * Return the data item bound to the first element in the selection. @@ -686,7 +686,7 @@ declare module d3 { * Derive the data item for each node in the selection. Useful for situations such as the HTML5 'dataset' attribute. * @param value the function to compute data for each node */ - datum(value: (datum: Datum, index: number) => NewDatum): Selection; + datum(value: (datum: Datum, index: number, outerIndex: number) => NewDatum): Selection; /** * Set the data item for each node in the selection. @@ -709,7 +709,7 @@ declare module d3 { * Returns the listener (if any) for the given event. * @param type the type of event to load the listener for. May have a namespace (e.g., ".foo") at the end. */ - on(type: string): (datum: Datum, index: number) => any; + on(type: string): (datum: Datum, index: number, outerIndex: number) => any; /** * Adds a listener for the specified event. If one was already registered, it is removed before the new listener is added. The return value of the listener function is ignored. @@ -717,7 +717,7 @@ declare module d3 { * @param listener an event listener function, or null to unregister * @param capture sets the DOM useCapture flag */ - on(type: string, listener: (datum: Datum, index: number) => any, capture?: boolean): Selection; + on(type: string, listener: (datum: Datum, index: number, outerIndex: number) => any, capture?: boolean): Selection; /** * Begins a new transition. Interrupts any active transitions of the same name. @@ -741,7 +741,7 @@ declare module d3 { * Creates a subselection by using a function to find descendent elements. Bound data is inherited. * @param selector the function to find matching descendants */ - select(selector: (datum: Datum, index: number) => EventTarget): Selection; + select(selector: (datum: Datum, index: number, outerIndex: number) => EventTarget): Selection; /** * Creates a subselection by finding all descendents that match the given selector. Bound data is not inherited. @@ -760,7 +760,7 @@ declare module d3 { * Creates a subselection by using a function to find descendent elements. Bound data is not inherited. * @param selector the function to find matching descendents */ - selectAll(selector: (datum: Datum, index: number) => Array | NodeList): Selection; + selectAll(selector: (datum: Datum, index: number, outerIndex: number) => Array | NodeList): Selection; /** * Creates a subselection by using a function to find descendent elements. Bound data is not inherited. @@ -768,13 +768,13 @@ declare module d3 { * Use this overload when data-binding a subselection (that is, sel.selectAll('.foo').data(d => ...)). The type will carry over. * @param selector the function to find matching descendents */ - selectAll(selector: (datum: Datum, index: number) => Array | NodeList): Selection; + selectAll(selector: (datum: Datum, index: number, outerIndex: number) => Array | NodeList): Selection; /** * Invoke the given function for each element in the selection. The return value of the function is ignored. * @param func the function to invoke */ - each(func: (datum: Datum, index: number) => any): Selection; + each(func: (datum: Datum, index: number, outerIndex: number) => any): Selection; /** * Call a function on the selection. sel.call(foo) is equivalent to foo(sel). @@ -805,32 +805,35 @@ declare module d3 { } interface Transition { + + transition(): Transition; + delay(): number; delay(delay: number): Transition; - delay(delay: (datum: Datum, index: number) => number): Transition; + delay(delay: (datum: Datum, index: number, outerIndex: number) => number): Transition; duration(): number; duration(duration: number): Transition; - duration(duration: (datum: Datum, index: number) => number): Transition; + duration(duration: (datum: Datum, index: number, outerIndex: number) => number): Transition; ease(): (t: number) => number; ease(value: string, ...args: any[]): Transition; ease(value: (t: number) => number): Transition; attr(name: string, value: Primitive): Transition; - attr(name: string, value: (datum: Datum, index: number) => Primitive): Transition; - attr(obj: { [key: string]: Primitive | ((datum: Datum, index: number) => Primitive) }): Transition; + attr(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive): Transition; + attr(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }): Transition; - attrTween(name: string, tween: (datum: Datum, index: number, attr: string) => Primitive): Transition; + attrTween(name: string, tween: (datum: Datum, index: number, attr: string) => (t: number) => Primitive): Transition; style(name: string, value: Primitive, priority?: string): Transition; - style(name: string, value: (datum: Datum, index: number) => Primitive, priority?: string): Transition; - style(obj: { [key: string]: Primitive | ((datum: Datum, index: number) => Primitive) }, priority?: string): Transition; + style(name: string, value: (datum: Datum, index: number, outerIndex: number) => Primitive, priority?: string): Transition; + style(obj: { [key: string]: Primitive | ((datum: Datum, index: number, outerIndex: number) => Primitive) }, priority?: string): Transition; styleTween(name: string, tween: (datum: Datum, index: number, attr: string) => Primitive, priority?: string): Transition; text(value: Primitive): Transition; - text(value: (datum: Datum, index: number) => Primitive): Transition; + text(value: (datum: Datum, index: number, outerIndex: number) => Primitive): Transition; tween(name: string, factory: () => (t: number) => any): Transition; @@ -2358,7 +2361,7 @@ declare module d3 { } interface Arc { - (d: T, i: number): string; + (d: T, i?: number): string; innerRadius(): (d: T, i: number) => number; innerRadius(radius: number): Arc; diff --git a/detect-indent/detect-indent.d.ts b/detect-indent/detect-indent.d.ts index 3ce72401dc..0ee7cad076 100644 --- a/detect-indent/detect-indent.d.ts +++ b/detect-indent/detect-indent.d.ts @@ -4,6 +4,10 @@ // Definitions: https://github.com/borisyankov/DefinitelyTyped declare module 'detect-indent' { - function DetectIndent (dir: string, alt?: string): string; - export = DetectIndent; + interface DetectIndent { + (dir: string, alt?: string): string; + } + var _: DetectIndent; + export = _; } + diff --git a/durandal/durandal.d.ts b/durandal/durandal.d.ts index 8250a3325e..86f988cbe7 100644 --- a/durandal/durandal.d.ts +++ b/durandal/durandal.d.ts @@ -295,7 +295,7 @@ interface DurandalViewEngineModule { * @param {string} id The view id whose view should be cached. * @param {DOMElement} view The view to cache. */ - putViewInCache(id:string, view:HTMLElement); + putViewInCache(id: string, view: HTMLElement); /** * Creates the view associated with the view id. @@ -1107,7 +1107,7 @@ declare module 'plugins/serializer' { * @param {object} [settings] Settings can specify any of the options allowed by the serialize or deserialize methods. * @return {object} The new clone. */ - export function clone(obj:T, settings?:Object): T; + export function clone(obj: T, settings?: Object): T; } /** @@ -1262,8 +1262,8 @@ interface DurandalEventModule { } interface DialogButton { - text: string; - value: any; + text: string; + value: any; } interface DurandalAppModule extends DurandalEventSupport { @@ -1509,13 +1509,12 @@ interface DurandalRouteConfiguration { title?: any; moduleId?: string; hash?: string; - /** string or string[] */ - route?: any; + route?: string|string[]; routePattern?: RegExp; isActive?: KnockoutComputed; nav?: any; hasChildRoutes?: boolean; - viewUrl?:string; + viewUrl?: string; } interface DurandalRouteInstruction { @@ -1523,7 +1522,7 @@ interface DurandalRouteInstruction { queryString: string; config: DurandalRouteConfiguration; params: any[]; - queryParams: Object; + queryParams: { [index: string]: any }; } interface DurandalRelativeRouteSettings { @@ -1766,7 +1765,12 @@ interface DurandalRouterBase extends DurandalEventSupport { * @param {object} instruction The route instruction. The instruction object has config, fragment, queryString, params and queryParams properties. * @returns {Promise|Boolean|String} If a boolean, determines whether or not the route should activate or be cancelled. If a string, causes a redirect to the specified route. Can also be a promise for either of these value types. */ - guardRoute?: (instance: Object, instruction: DurandalRouteInstruction) => any; + guardRoute?: (instance: Object, instruction: DurandalRouteInstruction) => JQueryPromise|boolean|string; + + /** + * Parent router of the current child router. + */ + parent?: DurandalRouter; } interface DurandalRouter extends DurandalRouterBase { } @@ -1792,4 +1796,4 @@ interface DurandalRootRouter extends DurandalRouterBase { * Installs the router's custom ko binding handler. */ install(): void; -} \ No newline at end of file +} diff --git a/fbsdk/fbsdk.d.ts b/fbsdk/fbsdk.d.ts index 6e3890e014..eb3f232695 100644 --- a/fbsdk/fbsdk.d.ts +++ b/fbsdk/fbsdk.d.ts @@ -21,7 +21,7 @@ interface FBUIParams{ interface FBLoginOptions{ auth_type ?: string; - scopes ?: string; + scope ?: string; return_scopes ?: boolean; enable_profile_selector ?: boolean; profile_selector_ids ?: string; @@ -132,4 +132,4 @@ declare module "FB" { export = FB; } -declare var FB : FBSDK; \ No newline at end of file +declare var FB : FBSDK; diff --git a/form-data/form-data.d.ts b/form-data/form-data.d.ts index 0f22b8ff5a..98dc1567df 100644 --- a/form-data/form-data.d.ts +++ b/form-data/form-data.d.ts @@ -7,7 +7,7 @@ declare module "form-data" { export class FormData { - append(key: string, value: any): FormData; + append(key: string, value: any, options?: any): FormData; getHeaders(): Object; // TODO expand pipe pipe(to: any): any; diff --git a/googlemaps/google.maps.d.ts b/googlemaps/google.maps.d.ts index ed7908df7a..9fed2e393f 100644 --- a/googlemaps/google.maps.d.ts +++ b/googlemaps/google.maps.d.ts @@ -2037,7 +2037,7 @@ declare module google.maps { /***** Visualization Library *****/ export module visualization { export class MapsEngineLayer extends MVCObject { - constructor(options: MapsEngineLayerOptions) + constructor(options: MapsEngineLayerOptions); getLayerId(): string; getLayerKey(): string; getMap(): Map; diff --git a/is-lower-case/is-lower-case-tests.ts b/is-lower-case/is-lower-case-tests.ts new file mode 100644 index 0000000000..6b37359cc1 --- /dev/null +++ b/is-lower-case/is-lower-case-tests.ts @@ -0,0 +1,7 @@ +/// + +import isLowerCase = require('is-lower-case') + +console.log(isLowerCase('string')); // => true +console.log(isLowerCase('String')); // => false +console.log(isLowerCase('STRING')); // => false diff --git a/is-lower-case/is-lower-case.d.ts b/is-lower-case/is-lower-case.d.ts new file mode 100644 index 0000000000..8f0f4c9119 --- /dev/null +++ b/is-lower-case/is-lower-case.d.ts @@ -0,0 +1,9 @@ +// Type definitions for is-lower-case +// Project: https://github.com/blakeembrey/is-lower-case +// Definitions by: Sam Saint-Pettersen +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "is-lower-case" { + function isLowerCase(string: string): boolean; + export = isLowerCase; +} diff --git a/iso8601-localizer/iso8601-localizer-tests.ts b/iso8601-localizer/iso8601-localizer-tests.ts new file mode 100644 index 0000000000..592799388d --- /dev/null +++ b/iso8601-localizer/iso8601-localizer-tests.ts @@ -0,0 +1,5 @@ +/// + +new ISO8601Localizer('2015-06-02T14:13:12').localize(); + +new ISO8601Localizer('2015-06-02T14:13:12').to(-5).localize(); diff --git a/iso8601-localizer/iso8601-localizer.d.ts b/iso8601-localizer/iso8601-localizer.d.ts new file mode 100644 index 0000000000..0fdc1b4cb6 --- /dev/null +++ b/iso8601-localizer/iso8601-localizer.d.ts @@ -0,0 +1,15 @@ +// Type definitions for ISO8601-Localizer v1.0.5 +// Project: https://github.com/avielfedida/ISO8601-Localizer +// Definitions by: Aviel Fedida +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +interface localizer { + to(offset: number): localizer, + localize(): string; +} + +declare class ISO8601Localizer implements localizer { + constructor(userISO8601: string); + to(offset: number): localizer; + localize(): string; +} diff --git a/jasmine/jasmine.d.ts b/jasmine/jasmine.d.ts index bcbf986a1a..581353b348 100644 --- a/jasmine/jasmine.d.ts +++ b/jasmine/jasmine.d.ts @@ -442,14 +442,21 @@ declare module jasmine { /** By chaining the spy with calls.allArgs(), will return the arguments to all calls **/ allArgs(): any[]; /** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls **/ - all(): any; + all(): CallInfo[]; /** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call **/ - mostRecent(): any; + mostRecent(): CallInfo; /** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call **/ - first(): any; + first(): CallInfo; /** By chaining the spy with calls.reset(), will clears all tracking for a spy **/ reset(): void; } + + interface CallInfo { + /** The context (the this) for the call */ + object: any; + /** All arguments passed to the call */ + args: any[]; + } interface Util { inherit(childClass: Function, parentClass: Function): any; diff --git a/lodash/lodash-tests.ts b/lodash/lodash-tests.ts index 627dda565c..877364ef0f 100644 --- a/lodash/lodash-tests.ts +++ b/lodash/lodash-tests.ts @@ -366,16 +366,31 @@ result = _.contains([1, 2, 3], 1, 2); result = _.contains({ 'moe': 30, 'larry': 40, 'curly': 67 }, 40); result = _.contains('curly', 'ur'); +result = _([1, 2, 3]).contains(1); +result = _([1, 2, 3]).contains(1, 2); +result = _({ 'moe': 30, 'larry': 40, 'curly': 67 }).contains(40); +result = _('curly').contains('ur'); + result = _.include([1, 2, 3], 1); result = _.include([1, 2, 3], 1, 2); result = _.include({ 'moe': 30, 'larry': 40, 'curly': 67 }, 40); result = _.include('curly', 'ur'); +result = _([1, 2, 3]).include(1); +result = _([1, 2, 3]).include(1, 2); +result = _({ 'moe': 30, 'larry': 40, 'curly': 67 }).include(40); +result = _('curly').include('ur'); + result = _.includes([1, 2, 3], 1); result = _.includes([1, 2, 3], 1, 2); result = _.includes({ 'moe': 30, 'larry': 40, 'curly': 67 }, 40); result = _.includes('curly', 'ur'); +result = _([1, 2, 3]).includes(1); +result = _([1, 2, 3]).includes(1, 2); +result = _({ 'moe': 30, 'larry': 40, 'curly': 67 }).includes(40); +result = _('curly').includes('ur'); + result = <_.Dictionary>_.countBy([4.3, 6.1, 6.4], function (num) { return Math.floor(num); }); result = <_.Dictionary>_.countBy([4.3, 6.1, 6.4], function (num) { return this.floor(num); }, Math); result = <_.Dictionary>_.countBy(['one', 'two', 'three'], 'length'); @@ -520,6 +535,20 @@ result = _(6.004).ceil(2); result = _(6040).ceil(-2); // → 6100 +// _.floor +result = _.floor(4.006); +// → 4 +result = _.floor(0.046, 2); +// → 0.04 +result = _.floor(4060, -2); +// → 4000 +result = _(4.006).floor(); +// → 4 +result = _(0.046).floor(2); +// → 0.04 +result = _(4060).floor(-2); +// → 4000 + result = _.max([4, 2, 8, 6]); result = _.max(stoogesAges, function (stooge) { return stooge.age; }); result = _.max(stoogesAges, 'age'); @@ -534,6 +563,20 @@ result = <_.LoDashWrapper>_([4, 2, 8, 6]).min(); result = <_.LoDashWrapper>_(stoogesAges).min(function (stooge) { return stooge.age; }); result = <_.LoDashWrapper>_(stoogesAges).min('age'); +// _.round +result = _.round(4.006); +// → 4 +result = _.round(4.006, 2); +// → 4.01 +result = _.round(4060, -2); +// → 4100 +result = _(4.006).round(); +// → 4 +result = _(4.006).round(2); +// → 4.01 +result = _(4060).round(-2); +// → 4100 + result = _.sum([4, 2, 8, 6]); result = _.sum([4, 2, 8, 6], function(v) { return v; }); result = _.sum({a: 2, b: 4}); @@ -651,6 +694,20 @@ result = _.sortBy([1, 2, 3], function (num) { return Math.sin(num); }) result = _.sortBy([1, 2, 3], function (num) { return this.sin(num); }, Math); result = _.sortBy(['banana', 'strawberry', 'apple'], 'length'); +result = _.sortByAll(stoogesAges, function(stooge) { return Math.sin(stooge.age); }, function(stooge) { return stooge.name.slice(1); }); +result = _.sortByAll(stoogesAges, ['name', 'age']); +result = _.sortByAll(stoogesAges, 'name', function(stooge) { return Math.sin(stooge.age); }); + +result = _.sortByOrder(stoogesAges, [function(stooge) { return Math.sin(stooge.age); }, function(stooge) { return stooge.name.slice(1); }]); +result = _.sortByOrder(stoogesAges, ['name', 'age']); +result = _.sortByOrder(stoogesAges, ['name', function(stooge) { return Math.sin(stooge.age); }]); +result = _.sortByOrder(stoogesAges, [function(stooge) { return Math.sin(stooge.age); }, function(stooge) { return stooge.name.slice(1); }], ['asc', 'desc']); +result = _.sortByOrder(stoogesAges, ['name', 'age'], ['asc', 'desc']); +result = _.sortByOrder(stoogesAges, ['name', function(stooge) { return Math.sin(stooge.age); }], ['asc', 'desc']); +result = _.sortByOrder(stoogesAges, [function(stooge) { return Math.sin(stooge.age); }, function(stooge) { return stooge.name.slice(1); }], [true, false]); +result = _.sortByOrder(stoogesAges, ['name', 'age'], [true, false]); +result = _.sortByOrder(stoogesAges, ['name', function(stooge) { return Math.sin(stooge.age); }], [true, false]); + result = _([1, 2, 3]).sortBy(function (num) { return Math.sin(num); }).value(); result = _([1, 2, 3]).sortBy(function (num) { return this.sin(num); }, Math).value(); result = _(['banana', 'strawberry', 'apple']).sortBy('length').value(); @@ -815,6 +872,27 @@ stooge('curly'); var returnedMemoize = _.throttle(function (a: any) { return a * 5; }, 5); returnedMemoize(4); +// _.modArgs +function modArgsFn1(n: number): string {return n.toString()} +function modArgsFn2(n: boolean): string {return n.toString()} +interface ModArgsFunc { + (x: string, y: string): string[]; +} +interface ModArgsResult { + (x: number, y: boolean): string[] +} +result = _.modArgs((x: string, y: string) => [x, y], modArgsFn1, modArgsFn2); +result = result(1, true); + +result = _.modArgs((x: string, y: string) => [x, y], [modArgsFn1, modArgsFn2]); +result = result(1, true); + +result = _((x: string, y: string) => [x, y]).modArgs(modArgsFn1, modArgsFn2).value(); +result = result(1, true); + +result = _((x: string, y: string) => [x, y]).modArgs([modArgsFn1, modArgsFn2]).value(); +result = result(1, true); + var initialize = _.once(function () { }); initialize(); initialize();'' @@ -850,6 +928,24 @@ var helloWrap2 = _.wrap(helloWrap, function (func) { }); helloWrap2(); +/******** + * Lang * + ********/ + +// _.toPlainObject +result = _.toPlainObject(); +result = _.toPlainObject(true); +result = _.toPlainObject(1); +result = _.toPlainObject('a'); +result = _.toPlainObject([]); +result = _.toPlainObject({}); +result = _(true).toPlainObject(); +result = _(1).toPlainObject(); +result = _('a').toPlainObject(); +result = _([1]).toPlainObject(); +result = _([]).toPlainObject(); +result = _({}).toPlainObject(); + /********** * Objects * ***********/ @@ -896,6 +992,18 @@ var foodDefaults = { 'name': 'apple' }; result = _.defaults(foodDefaults, { 'name': 'banana', 'type': 'fruit' }); result = <_.LoDashObjectWrapper>_(foodDefaults).defaults({ 'name': 'banana', 'type': 'fruit' }); +//_.defaultsDeep +interface DefaultsDeepResult { + user: { + name: string; + age: number; + } +} +var TestDefaultsDeepObject = {'user': {'name': 'barney'}}; +var TestDefaultsDeepSource = {'user': {'name': 'fred', 'age': 36}}; +result = _.defaultsDeep(TestDefaultsDeepObject, TestDefaultsDeepSource); +result = _(TestDefaultsDeepObject).defaultsDeep(TestDefaultsDeepSource).value(); + result = _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function (num) { return num % 2 == 0; }); @@ -986,21 +1094,30 @@ result = _.isEmpty([1, 2, 3]); result = _.isEmpty({}); result = _.isEmpty(''); -var moe = { 'name': 'moe', 'age': 40 }; -var copy = { 'name': 'moe', 'age': 40 }; +// _.isEqual (alias: _.eq) +result = _.isEqual(1, 1); +result = _(1).isEqual(1); +result = _.eq(1, 1); +result = _(1).eq(1); -result = _.isEqual(moe, copy); +var testEqObject = { 'user': 'fred' }; +var testEqOtherObject = { 'user': 'fred' }; +result = _.isEqual(testEqObject, testEqOtherObject); +result = _(testEqObject).isEqual(testEqOtherObject); +result = _.eq(testEqObject, testEqOtherObject); +result = _(testEqObject).eq(testEqOtherObject); -var words = ['hello', 'goodbye']; -var otherWords = ['hi', 'goodbye']; - -result = _.isEqual(words, otherWords, function (a, b) { - var reGreet = /^(?:hello|hi)$/i, - aGreet = _.isString(a) && reGreet.test(a), - bGreet = _.isString(b) && reGreet.test(b); - - return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; -}); +var testEqArray = ['hello', 'goodbye']; +var testEqOtherArray = ['hi', 'goodbye']; +var testEqCustomizerFn = (value: any, other: any): boolean => { + if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + return true; + } +}; +result = _.isEqual(testEqArray, testEqOtherArray, testEqCustomizerFn); +result = _(testEqArray).isEqual(testEqOtherArray, testEqCustomizerFn); +result = _.eq(testEqArray, testEqOtherArray, testEqCustomizerFn); +result = _(testEqArray).eq(testEqOtherArray, testEqCustomizerFn); result = _.isFinite(-101); result = _.isFinite('10'); @@ -1105,8 +1222,9 @@ result = _.pick({ 'name': 'moe', '_userid': 'moe1' }, function (value, return key.charAt(0) != '_'; }); - +// _.set result = <{ a: { b: { c: number; }}[]}>_.set({ 'a': [{ 'b': { 'c': 3 } }] }, 'a[0].b.c', 4); +result = <{ a: { b: { c: number; }}[]}>_({ 'a': [{ 'b': { 'c': 3 } }] }).set('a[0].b.c', 4).value(); result = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (r: number[], num: number) { num *= num; @@ -1255,6 +1373,18 @@ result = _.words('fred, barney, & pebbles', /[^, ]+/g); * Utilities * ***********/ +// _.constant +result = <() => number>_.constant(1); +result = <() => string>_.constant('a'); +result = <() => boolean>_.constant(true); +result = <() => any[]>_.constant([]); +result = <() => {}>_.constant<{}>({}); +result = <() => number>_(1).constant(); +result = <() => string>_('a').constant(); +result = <() => boolean>_(true).constant(); +result = <() => any[]>_(['a']).constant(); +result = <() => {}>_({}).constant<{}>(); + result = _.VERSION; result = <_.Support>_.support; result = <_.TemplateSettings>_.templateSettings; diff --git a/lodash/lodash.d.ts b/lodash/lodash.d.ts index 7bc1df648d..7bbb65a54c 100644 --- a/lodash/lodash.d.ts +++ b/lodash/lodash.d.ts @@ -39,7 +39,7 @@ declare module _ { * Explicit chaining can be enabled by using the _.chain method. **/ (value: number): LoDashWrapper; - (value: string): LoDashWrapper; + (value: string): LoDashStringWrapper; (value: boolean): LoDashWrapper; (value: Array): LoDashNumberArrayWrapper; (value: Array): LoDashArrayWrapper; @@ -196,10 +196,17 @@ declare module _ { * @see _.value **/ valueOf(): T; + + /** + * @see _.toPlainObject + */ + toPlainObject(): Object; } interface LoDashWrapper extends LoDashWrapperBase> { } + interface LoDashStringWrapper extends LoDashWrapper { } + interface LoDashObjectWrapper extends LoDashWrapperBase> { } interface LoDashArrayWrapper extends LoDashWrapperBase> { @@ -2159,6 +2166,57 @@ declare module _ { fromIndex?: number): boolean; } + interface LoDashArrayWrapper { + /** + * @see _.contains + **/ + contains(target: T, fromIndex?: number): boolean; + + /** + * @see _.contains + **/ + include(target: T, fromIndex?: number): boolean; + + /** + * @see _.contains + **/ + includes(target: T, fromIndex?: number): boolean; + } + + interface LoDashObjectWrapper { + /** + * @see _.contains + **/ + contains(target: TValue, fromIndex?: number): boolean; + + /** + * @see _.contains + **/ + include(target: TValue, fromIndex?: number): boolean; + + /** + * @see _.contains + **/ + includes(target: TValue, fromIndex?: number): boolean; + } + + interface LoDashStringWrapper { + /** + * @see _.contains + **/ + contains(target: string, fromIndex?: number): boolean; + + /** + * @see _.contains + **/ + include(target: string, fromIndex?: number): boolean; + + /** + * @see _.contains + **/ + includes(target: string, fromIndex?: number): boolean; + } + //_.countBy interface LoDashStatic { /** @@ -3572,6 +3630,24 @@ declare module _ { ceil(precision?: number): number; } + //_.floor + interface LoDashStatic { + /** + * Calculates n rounded down to precision. + * @param n The number to round down. + * @param precision The precision to round down to. + * @return Returns the rounded down number. + */ + floor(n: number, precision?: number): number; + } + + interface LoDashWrapper { + /** + * @see _.floor + */ + floor(precision?: number): number; + } + //_.max interface LoDashStatic { /** @@ -3794,6 +3870,24 @@ declare module _ { whereValue: W): LoDashWrapper; } + //_.round + interface LoDashStatic { + /** + * Calculates n rounded to precision. + * @param n The number to round. + * @param precision The precision to round to. + * @return Returns the rounded number. + */ + round(n: number, precision?: number): number; + } + + interface LoDashWrapper { + /** + * @see _.round + */ + round(precision?: number): number; + } + //_.sum interface LoDashStatic { /** @@ -3872,7 +3966,7 @@ declare module _ { /** * @see _.sum **/ - sum(): number + sum(): number; /** * @see _.sum @@ -3883,6 +3977,11 @@ declare module _ { } interface LoDashArrayWrapper { + /** + * @see _.sum + **/ + sum(): number; + /** * @see _.sum **/ @@ -3902,7 +4001,7 @@ declare module _ { /** * @see _.sum **/ - sum(): number + sum(): number; /** * @see _.sum @@ -4753,8 +4852,11 @@ declare module _ { * * If a property name is provided for callback the created "_.pluck" style callback will * return the property value of the given element. - * - * If an object is provided for callback the created "_.where" style callback will return + * + * If a value is also provided for thisArg the created "_.matchesProperty" style callback + * returns true for elements that have a matching property value, else false. + * + * If an object is provided for an iteratee the created "_.matches" style callback returns * true for elements that have the properties of the given object, else false. * @param collection The collection to iterate over. * @param callback The function called per iteration. @@ -4763,7 +4865,7 @@ declare module _ { **/ sortBy( collection: Array, - callback?: ListIterator, + iteratee?: ListIterator, thisArg?: any): T[]; /** @@ -4771,7 +4873,7 @@ declare module _ { **/ sortBy( collection: List, - callback?: ListIterator, + iteratee?: ListIterator, thisArg?: any): T[]; /** @@ -4812,7 +4914,7 @@ declare module _ { * @see _.sortBy **/ sortBy( - callback?: ListIterator, + iteratee?: ListIterator, thisArg?: any): LoDashArrayWrapper; /** @@ -4828,6 +4930,131 @@ declare module _ { sortBy(whereValue: W): LoDashArrayWrapper; } + //_.sortByAll + interface LoDashStatic { + /** + * This method is like "_.sortBy" except that it can sort by multiple iteratees or + * property names. + * + * If a property name is provided for an iteratee the created "_.property" style callback + * returns the property value of the given element. + * + * If a value is also provided for thisArg the created "_.matchesProperty" style callback + * returns true for elements that have a matching property value, else false. + * + * If an object is provided for an iteratee the created "_.matches" style callback returns + * true for elements that have the properties of the given object, else false. + * + * @param collection The collection to iterate over. + * @param callback The function called per iteration. + * @param thisArg The this binding of callback. + * @return A new array of sorted elements. + **/ + sortByAll( + collection: Array, + iteratees: (ListIterator|string|Object)[]): T[]; + + /** + * @see _.sortByAll + **/ + sortByAll( + collection: List, + iteratees: (ListIterator|string|Object)[]): T[]; + + /** + * @see _.sortByAll + **/ + sortByAll( + collection: Array, + ...iteratees: (ListIterator|string|Object)[]): T[]; + + /** + * @see _.sortByAll + **/ + sortByAll( + collection: List, + ...iteratees: (ListIterator|string|Object)[]): T[]; + } + + interface LoDashArrayWrapper { + /** + * @see _.sortByAll + **/ + sortByAll( + iteratees: (ListIterator|string|Object)[]): LoDashArrayWrapper; + + /** + * @see _.sortByAll + **/ + sortByAll( + ...iteratees: (ListIterator|string|Object)[]): LoDashArrayWrapper; + } + + //_.sortByOrder + interface LoDashStatic { + /** + * This method is like "_.sortByAll" except that it allows specifying the sort orders of the + * iteratees to sort by. If orders is unspecified, all values are sorted in ascending order. + * Otherwise, a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * If a property name is provided for an iteratee the created "_.property" style callback + * returns the property value of the given element. + * + * If an object is provided for an iteratee the created "_.matches" style callback returns + * true for elements that have the properties of the given object, else false. + * + * @param collection The collection to iterate over. + * @param callback The function called per iteration. + * @param thisArg The this binding of callback. + * @return A new array of sorted elements. + **/ + sortByOrder( + collection: Array, + iteratees: (ListIterator|string|Object)[], + orders?: boolean[]): T[]; + + /** + * @see _.sortByOrder + **/ + sortByOrder( + collection: List, + iteratees: (ListIterator|string|Object)[], + orders?: boolean[]): T[]; + + /** + * @see _.sortByOrder + **/ + sortByOrder( + collection: Array, + iteratees: (ListIterator|string|Object)[], + orders?: string[]): T[]; + + /** + * @see _.sortByOrder + **/ + sortByOrder( + collection: List, + iteratees: (ListIterator|string|Object)[], + orders?: string[]): T[]; + } + + interface LoDashArrayWrapper { + /** + * @see _.sortByOrder + **/ + sortByOrder( + iteratees: (ListIterator|string|Object)[], + orders?: boolean[]): LoDashArrayWrapper; + + /** + * @see _.sortByOrder + **/ + sortByOrder( + iteratees: (ListIterator|string|Object)[], + orders?: string[]): LoDashArrayWrapper; + } + //_.toArray interface LoDashStatic { /** @@ -5212,6 +5439,41 @@ declare module _ { resolver?: Function): T; } + //_.modArgs + interface LoDashStatic { + /** + * Creates a function that runs each argument through a corresponding transform function. + * @param func The function to wrap. + * @param transforms The functions to transform arguments, specified as individual functions or arrays + * of functions. + * @return Returns the new function. + */ + modArgs( + func: T, + ...transforms: Function[] + ): TResult; + + /** + * @see _.modArgs + */ + modArgs( + func: T, + transforms: Function[] + ): TResult; + } + + interface LoDashObjectWrapper { + /** + * @see _.modArgs + */ + modArgs(...transforms: Function[]): LoDashObjectWrapper; + + /** + * @see _.modArgs + */ + modArgs(transforms: Function[]): LoDashObjectWrapper; + } + //_.once interface LoDashStatic { /** @@ -5304,6 +5566,21 @@ declare module _ { wrapper: (func: Function, ...args: any[]) => any): Function; } + /******** + * Lang * + ********/ + + //_.toPlainObject + interface LoDashStatic { + /** + * Converts value to a plain object flattening inherited enumerable properties of value to own properties + * of the plain object. + * @param value The value to convert. + * @return Returns the converted plain object. + */ + toPlainObject(value?: any): Object; + } + /************* * Objects * *************/ @@ -5564,6 +5841,26 @@ declare module _ { defaults(...sources: any[]): LoDashObjectWrapper } + //_.defaultsDeep + interface LoDashStatic { + /** + * This method is like _.defaults except that it recursively assigns default properties. + * @param object The destination object. + * @param sources The source objects. + * @return Returns object. + **/ + defaultsDeep( + object: T, + ...sources: any[]): TResult; + } + + interface LoDashObjectWrapper { + /** + * @see _.defaultsDeep + **/ + defaultsDeep(...sources: any[]): LoDashObjectWrapper + } + //_.findKey interface LoDashStatic { /** @@ -5907,25 +6204,84 @@ declare module _ { isError(value: any): boolean; } - //_.isEqual + interface EqCustomizer { + (value: any, other: any, indexOrKey?: number|string): boolean; + } + interface LoDashStatic { /** - * Performs a deep comparison between two values to determine if they are equivalent to each - * other. If a callback is provided it will be executed to compare values. If the callback - * returns undefined comparisons will be handled by the method instead. The callback is bound to - * thisArg and invoked with two arguments; (a, b). - * @param a The value to compare. - * @param b The other value to compare. - * @param callback The function to customize comparing values. - * @param thisArg The this binding of callback. - * @return True if the values are equivalent, else false. - **/ - isEqual( - a?: any, - b?: any, - callback?: (a: any, b: any) => boolean, - thisArg?: any): boolean; + * Performs a deep comparison between two values to determine if they are equivalent. If customizer is + * provided it is invoked to compare values. If customizer returns undefined comparisons are handled + * by the method instead. The customizer is bound to thisArg and invoked with three + * arguments: (value, other [, index|key]). + * @param value The value to compare. + * @param other The other value to compare. + * @param callback The function to customize value comparisons. + * @param thisArg The this binding of customizer. + * @return True if the values are equivalent, else false. + */ + isEqual(value?: any, + other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + + /** + * @see _.isEqual + */ + eq(value?: any, + other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + } + + interface LoDashWrapper { + /** + * @see _.isEqual + */ + isEqual(other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + + /** + * @see _.isEqual + */ + eq(other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + + } + + interface LoDashArrayWrapper { + /** + * @see _.isEqual + */ + isEqual(other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + + /** + * @see _.isEqual + */ + eq(other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + } + + interface LoDashObjectWrapper { + /** + * @see _.isEqual + */ + isEqual(other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; + + /** + * @see _.isEqual + */ + eq(other?: any, + callback?: EqCustomizer, + thisArg?: any): boolean; } //_.isFinite @@ -6300,6 +6656,14 @@ declare module _ { value: any): T; } + interface LoDashObjectWrapper { + /** + * @see _.set + **/ + set(path: string|string[], + value: any): LoDashObjectWrapper; + } + //_.transform interface LoDashStatic { /** @@ -6626,11 +6990,20 @@ declare module _ { //_.constant interface LoDashStatic { /** - * Creates a function that returns value.. - **/ + * Creates a function that returns value. + * @param value The value to return from the new function. + * @return Returns the new function. + */ constant(value: T): () => T; } + interface LoDashWrapperBase { + /** + * @see _.constant + */ + constant(): () => TResult; + } + //_.create interface LoDashStatic { /** diff --git a/magic-number/magic-number-tests.ts b/magic-number/magic-number-tests.ts new file mode 100644 index 0000000000..ac0b599820 --- /dev/null +++ b/magic-number/magic-number-tests.ts @@ -0,0 +1,12 @@ +/// +/// + +import fs = require('fs'); +import magic = require('magic-number'); + +var buffer: any = new Buffer(100); +buffer.write('7z', 'binary'); +fs.writeFile('test.love', buffer, function(err: any) { + console.log(magic.detectFile('test.love')); // => 'application/7z-x-compressed' + fs.unlinkSync('test.love'); +}); diff --git a/magic-number/magic-number.d.ts b/magic-number/magic-number.d.ts new file mode 100644 index 0000000000..295bb1d43e --- /dev/null +++ b/magic-number/magic-number.d.ts @@ -0,0 +1,8 @@ +// Type definitions for magic-number +// Project: https://github.com/stpettersens/node-magic-number +// Definitions by: Sam Saint-Pettersen +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "magic-number" { + export function detectFile(file: string): string; +} diff --git a/mariasql/mariasql-tests.ts b/mariasql/mariasql-tests.ts index c9173058ca..76819feba8 100644 --- a/mariasql/mariasql-tests.ts +++ b/mariasql/mariasql-tests.ts @@ -92,6 +92,9 @@ c.query('SELECT * FROM users WHERE id = ? AND name = ?', console.log('Result error: ' + inspect(err)); }) .on('end', function (info) { + console.log(info.affectedRows); + console.log(info.insertId); + console.log(info.numRows); console.log('Result finished successfully'); }); }) diff --git a/mariasql/mariasql.d.ts b/mariasql/mariasql.d.ts index 05d7fa0621..9eb80068fb 100644 --- a/mariasql/mariasql.d.ts +++ b/mariasql/mariasql.d.ts @@ -24,6 +24,10 @@ declare module mariasql { (result:Object):void } + export interface MariaCallBackInfo { + (result:MariaInfo):void + } + export interface MariaCallBackVoid { ():void } @@ -32,6 +36,12 @@ declare module mariasql { [index: string]: any; } + export interface MariaInfo { + affectedRows: number; + insertId: number; + numRows: number + } + export interface MariaPreparedQuery { (values:Dictionary):string; (values:Array):string; @@ -57,18 +67,20 @@ declare module mariasql { } export interface MariaResult { - on(signal:string, cb:MariaCallBackObject):MariaResult; // signal 'end' - on(signal:string, cb:MariaCallBackError):MariaResult; // signal 'error' - on(signal:string, cb:MariaCallBackRow):MariaResult; // signal 'row' - on(signal:string, cb:MariaCallBackVoid):MariaResult; // signal 'abort' + on(signal:'end', cb:MariaCallBackInfo):MariaResult; + on(signal:'error', cb:MariaCallBackError):MariaResult; + on(signal:'row', cb:MariaCallBackRow):MariaResult; + on(signal:'abort', cb:MariaCallBackVoid):MariaResult; + on(signal:string, cb:MariaCallBackVoid):MariaResult; abort():void; } export interface MariaQuery { - on(signal:string, cb:MariaCallBackResult):MariaQuery; // signal 'result' - on(signal:string, cb:MariaCallBackVoid):MariaQuery; // signal 'end' - on(signal:string, cb:MariaCallBackVoid):MariaQuery; // signal 'abort' - on(signal:string, cb:MariaCallBackError):MariaQuery; // signal 'error' + on(signal:'result', cb:MariaCallBackResult):MariaQuery; + on(signal:'end', cb:MariaCallBackVoid):MariaQuery; + on(signal:'abort', cb:MariaCallBackVoid):MariaQuery; + on(signal:'error', cb:MariaCallBackError):MariaQuery; + on(signal:string, cb:MariaCallBackVoid):MariaQuery; abort():void; } @@ -82,9 +94,10 @@ declare module mariasql { query(q:string, useArray?:boolean):MariaQuery; prepare(query:string): MariaPreparedQuery; isMariaDB():boolean; - on(signal:string, cb:MariaCallBackError): MariaClient; // signal 'error' - on(signal:string, cb:MariaCallBackObject): MariaClient; // signal 'close' - on(signal:string, cb:MariaCallBackVoid): MariaClient; // signal 'connect' + on(signal:'error', cb:MariaCallBackError): MariaClient; + on(signal:'close', cb:MariaCallBackObject): MariaClient; + on(signal:'connect', cb:MariaCallBackVoid): MariaClient; + on(signal:string, cb:MariaCallBackVoid): MariaClient; connected: boolean; threadId: string; } diff --git a/marked/marked.d.ts b/marked/marked.d.ts index 427771edc8..8e78cdabbd 100644 --- a/marked/marked.d.ts +++ b/marked/marked.d.ts @@ -63,6 +63,13 @@ interface MarkedStatic { } interface MarkedOptions { + /** + * Type: object Default: new Renderer() + * + * An object containing functions to render tokens to HTML. + */ + renderer?: Object; + /** * Enable GitHub flavored markdown. */ @@ -118,4 +125,4 @@ declare module "marked" { export = marked; } -declare var marked: MarkedStatic; \ No newline at end of file +declare var marked: MarkedStatic; diff --git a/mssql/mssql-tests.ts b/mssql/mssql-tests.ts index 5a7e3e3059..453b2b4e3f 100644 --- a/mssql/mssql-tests.ts +++ b/mssql/mssql-tests.ts @@ -39,7 +39,7 @@ var connection: sql.Connection = new sql.Connection(config, function (err: any) requestStoredProcedure.input('pId', testId); requestStoredProcedure.input('pString', testString); - + requestStoredProcedure.execute('StoredProcedureName', function (err, recordsets, returnValue) { if (err != null) { @@ -54,9 +54,17 @@ var connection: sql.Connection = new sql.Connection(config, function (err: any) var testId: number = 0; var testString: string = 'test'; - requestStoredProcedure.input('pId', testId); - requestStoredProcedure.input('pString', testString); - requestStoredProcedure.output('output', sql.Int); + requestStoredProcedureWithOutput.input("name", sql.VarChar, "abc"); // varchar(3) + requestStoredProcedureWithOutput.input("name", sql.VarChar(50), "abc"); // varchar(MAX) + requestStoredProcedureWithOutput.output("name", sql.VarChar); // varchar(8000) + requestStoredProcedureWithOutput.output("name", sql.VarChar, "abc"); // varchar(3) + + requestStoredProcedureWithOutput.input("name", sql.Decimal, 155.33); // decimal(18, 0) + requestStoredProcedureWithOutput.input("name", sql.Decimal(10), 155.33); // decimal(10, 0) + requestStoredProcedureWithOutput.input("name", sql.Decimal(10, 2), 155.33); // decimal(10, 2) + + requestStoredProcedureWithOutput.input("name", sql.DateTime2, new Date()); // datetime2(7) + requestStoredProcedureWithOutput.input("name", sql.DateTime2(5), new Date()); // datetime2(5) requestStoredProcedure.execute('StoredProcedureName', function (err, recordsets, returnValue) { if (err != null) { diff --git a/mssql/mssql.d.ts b/mssql/mssql.d.ts index 5a6e6a00cf..880eb716cb 100644 --- a/mssql/mssql.d.ts +++ b/mssql/mssql.d.ts @@ -5,12 +5,38 @@ declare module "mssql" { + export var Date: any; export var DateTime: any; + export var DateTime2: any; + export var DateTimeOffset: any; + export var SmallDateTime: any; + export var Time: any; + export var Char: any; + export var VarChar:any; + export var NChar: any; export var NVarChar: any; + export var Text:any; + export var NText:any; + export var Xml: any; + export var TinyInt:any; + export var SmallInt:any; export var Int: any; + export var BigInt:any; + export var Decimal:any; + export var Float:any; + export var Real:any; + export var SmallMoney:any; + export var Money:any; + export var Numeric:any; export var Bit: any; + export var Binary: any; export var VarBinary: any; export var TVP: any; + export var UniqueIdentifier: any; + export var Image: any; + export var UDT: any; + export var Geography: any; + export var Geometry: any; export interface options { encrypt: boolean; diff --git a/ng-command/ng-command-tests.ts b/ng-command/ng-command-tests.ts new file mode 100644 index 0000000000..77fea7b400 --- /dev/null +++ b/ng-command/ng-command-tests.ts @@ -0,0 +1,25 @@ +/// +/// + +var app = angular.module('testModule', ['ng-command']); + +class CommandTestController { + + constructor($command: ngCommand.ICommandFactory, $scope: ng.IScope, $timeout: ng.ITimeoutService) { + + var cmd = $command($scope, () => { + return $timeout(() => {}, 0) + }) + + var cmdWithCanExecute = $command($scope, () => { + return $timeout(() => {}, 0) + }, () => false); + + cmd.isExecuting === false; + cmd.canExecute === false; + cmd.execute(); + } + +} + +app.controller('TestController', CommandTestController); diff --git a/ng-command/ng-command.d.ts b/ng-command/ng-command.d.ts new file mode 100644 index 0000000000..1a2cd6bd22 --- /dev/null +++ b/ng-command/ng-command.d.ts @@ -0,0 +1,51 @@ +// Type definitions for ng-command 0.2.0 +// Project: https://github.com/stephenlautier/ng-command +// Definitions by: Stephen Lautier +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module ngCommand { + + var ModuleName: string; + + /** + * Command proxy object. + */ + interface ICommand { + /** + * Determines whether the command is currently executing. + */ + isExecuting: boolean; + /** + * Determines whether the command can execute or not. + */ + canExecute: boolean; + /** + * Executes the command function. + */ + execute: () => angular.IPromise; + } + + class Command implements ICommand { + static id: string; + + isExecuting: boolean; + canExecute: boolean; + constructor($scope: angular.IScope, execute: () => angular.IPromise, canExecute?: () => boolean); + execute(): angular.IPromise; + } + + /** + * Command factory which creates instances of @see ICommand. + */ + interface ICommandFactory { + /** + * Factory instance creator method. + * @param $scope Scope which will keep track of the command. + * @param execute The execute function when the command is executed. + * @param canExecute Additional function which determines whether the command can executes. + */ + ($scope: angular.IScope, execute: () => angular.IPromise, canExecute?: () => boolean): ICommand; + } +} diff --git a/node-getopt/node-getopt-test.ts b/node-getopt/node-getopt-test.ts new file mode 100644 index 0000000000..83aa050536 --- /dev/null +++ b/node-getopt/node-getopt-test.ts @@ -0,0 +1,97 @@ +/// +/// + +import Getopt = require('node-getopt'); + +function help() { + // examples/help.js + // Works with help + + var getopt = new Getopt([ + ['s' , '' , 'short option.'], + ['' , 'long' , 'long option.'], + ['S' , 'short-with-arg=ARG' , 'option with argument'], + ['L' , 'long-with-arg=ARG' , 'long option with argument'], + ['' , 'color[=COLOR]' , 'COLOR is optional'], + ['m' , 'multi-with-arg=ARG+' , 'multiple option with argument'], + ['' , 'no-comment'], + ['h' , 'help' , 'display this help'] + ]); + + // Use custom help template instead of default help + // [[OPTIONS]] is the placeholder for options list + getopt.setHelp( + "Usage: node help.js [OPTION]\n" + + "node-getopt help demo.\n" + + "\n" + + "[[OPTIONS]]\n" + + "\n" + + "Installation: npm install node-getopt\n" + + "Respository: https://github.com/jiangmiao/node-getopt" + ); + + getopt.showHelp(); +} + +function onedragon() { + // examples/onedragon.js + var opt = require('node-getopt').create([ + ['s' , '' , 'short option.'], + ['' , 'long' , 'long option.'], + ['S' , 'short-with-arg=ARG' , 'option with argument'], + ['L' , 'long-with-arg=ARG' , 'long option with argument'], + ['' , 'color[=COLOR]' , 'COLOR is optional'], + ['m' , 'multi-with-arg=ARG+' , 'multiple option with argument'], + ['' , 'no-comment'], + ['h' , 'help' , 'display this help'] + ]) + .bindHelp() + .parseSystem(); + + console.info(opt); +} + +function online(){ + // node-getopt oneline example. + var opt = require('..').create([ + ['s' , '' , 'short option.'], + ['' , 'long' , 'long option.'], + ['S' , 'short-with-arg=ARG' , 'option with argument'], + ['L' , 'long-with-arg=ARG' , 'long option with argument'], + ['' , 'color[=COLOR]' , 'COLOR is optional'], + ['m' , 'multi-with-arg=ARG+' , 'multiple option with argument'], + ['' , 'no-comment'], + ['h' , 'help' , 'display this help'], + ['v' , 'version' , 'show version'] + ]) // create Getopt instance + .bindHelp() // bind option 'help' to default action + .parseSystem(); // parse command line + + console.info(opt); +} + +function simple() { + // examples/simple.js + // argv parse + // Getopt = require('node-getopt'); + + // Getopt arguments options + // '=': has argument + // '[=]': has argument but optional + // '+': multiple option supported + var getopt = new Getopt([ + ['s'], + ['S' , '='], + ['' , 'long-with-arg=ARG'], + ['m' , '=+'], + ['' , 'color[=COLOR]'], + ['h' , 'help'] + ]).bindHelp(); + + // process.argv needs slice(2) for it starts with 'node' and 'script name' + // parseSystem is alias of parse(process.argv.slice(2)) + // opt = getopt.parseSystem(); + var opt = getopt.parse(process.argv.slice(2)); + console.info(opt); + +} diff --git a/node-getopt/node-getopt.d.ts b/node-getopt/node-getopt.d.ts new file mode 100644 index 0000000000..9fec278b57 --- /dev/null +++ b/node-getopt/node-getopt.d.ts @@ -0,0 +1,129 @@ +// Type definitions for node-getopt 0.2.3 +// Project: https://github.com/jiangmiao/node-getopt +// Definitions by: Karl.M.Cauchy +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/** + * Type Script Declaration for node-getopt + */ +declare module "node-getopt" { + + interface StringMap { + [index: string]: string; + } + + /** + * Parsed options. + */ + class ParsedOption { + public argv: string[]; + public options: StringMap; + + constructor(argv: string[], options: StringMap); + public empty() : boolean; + } + + interface EventCallback { + (arguments: string[], options: StringMap) : void; + } + + interface ErrorFunc { + (exception: Error): void; + } + + interface OptionConfigurationArray { + [index: number]: string[]; + } + + class Getopt { + static HAS_ARGUMENT : boolean; + static NO_ARGUMENT : boolean; + static MULTI_SUPPORTED : boolean; + static SINGLE_ONLY : boolean; + static VERSION : string; + + /** + * options is a set of option. each option contains 3 fields. + * [short_name, long_name_with_definition, comment] + * Definition: + * * '=ARG': has argument + * * '[=ARG]': has argument but optional + * * '+': multiple option supported + * + * ARG can be replaced by any word. + * @param options + */ + public constructor(options: any[]); + + /** + * after parsing, trigger the action if optionName is found. + * the 'this' in action will be the instance of Getopt. + * @param name + * @param cb + */ + public on(name: string, cb: EventCallback) : Getopt; + + public emit(name: string, cb: EventCallback) : Getopt; + + /** + * parse argv + * + * Returns: {argv: '...', options: {...}} + * + */ + public parse(argv: string[]): ParsedOption; + + /** + * alias of parse(process.argv.slice(2)) + */ + public parse_system(): ParsedOption; + + public parseSystem():ParsedOption; + + /** + * Set help template. the placeholders will be replaced by getopt. + * + * Placeholders: + * * [[OPTIONS]] - The options list + * + * Returns: String + * @param help + */ + public setHelp(help: string): Getopt; + + /** + * console.info(getopt.getHelp()); + */ + public showHelp():Getopt; + + /** + * Get the help generated. + */ + public getHelp(): string; + + /** + * set help template to HELP if HELP is not empty. + * bind 'help' option to default action, show help and exit with 0. + * @param help + */ + public bindHelp(help?:string): Getopt; + + public getVersion(): string; + + static getVersion():string; + + /** + * when parse failed callback will be trigger. default is display error message and exit with 1. + * @param errorFunc + */ + public error(errorFunc: ErrorFunc) : Getopt; + + /** + * equals new Getopt(options) + * @param options + */ + static create(options: string[]): Getopt; + } + + export = Getopt; +} diff --git a/request/request-tests.ts b/request/request-tests.ts index 64aef2a04f..9d7cbf3bc4 100644 --- a/request/request-tests.ts +++ b/request/request-tests.ts @@ -46,9 +46,9 @@ str = cookie.path; str = cookie.toString(); var jar: request.CookieJar; -jar.add(cookie); -cookie = jar.get(req); -str = jar.cookieString(req); +jar.setCookie(cookie, uri); +str = jar.getCookieString(uri); +var cookies: request.Cookie[] = jar.getCookies(uri); var aws: request.AWSOptions; str = aws.secret; diff --git a/request/request.d.ts b/request/request.d.ts index e16eafadb7..e261d36152 100644 --- a/request/request.d.ts +++ b/request/request.d.ts @@ -12,6 +12,7 @@ declare module 'request' { import stream = require('stream'); import http = require('http'); import FormData = require('form-data'); + import url = require('url'); export = RequestAPI; @@ -85,6 +86,7 @@ declare module 'request' { timeout?: number; proxy?: any; strictSSL?: boolean; + gzip?: boolean; } export interface RequestPart { @@ -160,9 +162,9 @@ declare module 'request' { } export interface CookieJar { - add(cookie: Cookie): void; - get(req: Request): Cookie; - cookieString(req: Request): string; + setCookie(cookie: Cookie, uri: string|url.Url, options?: any): void + getCookieString(uri: string|url.Url): string + getCookies(uri: string|url.Url): Cookie[] } export interface CookieValue { diff --git a/systemjs/systemjs-tests.ts b/systemjs/systemjs-tests.ts new file mode 100644 index 0000000000..7a56ef8dc9 --- /dev/null +++ b/systemjs/systemjs-tests.ts @@ -0,0 +1,10 @@ +/// + +import System = require('systemjs'); + +System.config({ + baseURL: '/', + paths: {'*': '*.js?v=0.18.4'} +}); + +System.import('app'); \ No newline at end of file diff --git a/systemjs/systemjs.d.ts b/systemjs/systemjs.d.ts new file mode 100644 index 0000000000..c63a791582 --- /dev/null +++ b/systemjs/systemjs.d.ts @@ -0,0 +1,21 @@ +// Type definitions for System.js 0.18.4 +// Project: https://github.com/systemjs/systemjs +// Definitions by: Ludovic HENIN , Nathan Walker +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +interface System { + import(name: string): any; + defined: any; + amdDefine: () => void; + amdRequire: () => void; + baseURL: string; + paths: { [key: string]: string }; + meta: { [key: string]: Object }; + config: any; +} + +declare var System: System; + +declare module "systemjs" { + export = System; +} \ No newline at end of file diff --git a/ui-grid/ui-grid-tests.ts b/ui-grid/ui-grid-tests.ts index 6bdae2f64c..21d42c021a 100644 --- a/ui-grid/ui-grid-tests.ts +++ b/ui-grid/ui-grid-tests.ts @@ -72,7 +72,7 @@ columnDef.menuItems = [{ columnDef.minWidth = 100; columnDef.name = 'MyColumn'; columnDef.sort = { - direction: 0, + direction: 'ASC', ignoreSort: false, priority: 1 }; @@ -86,3 +86,17 @@ columnDef.visible = true; columnDef.width = 100; columnDef.width = '*'; + +var gridApi: uiGrid.IGridApi; +var gridInstance: uiGrid.IGridInstance; +var menuItem: uiGrid.IMenuItem; +var colProcessor: uiGrid.IColumnProcessor; + +gridApi.core.clearAllFilters(true); +gridApi.core.addToGridMenu(gridInstance, [menuItem]); +gridApi.core.getVisibleRows(gridInstance); +gridApi.core.handleWindowResize(); +gridApi.core.queueGridRefresh() +gridApi.core.queueRefresh(); +gridApi.core.registerColumnsProcessor(colProcessor, 100); + diff --git a/ui-grid/ui-grid.d.ts b/ui-grid/ui-grid.d.ts index f27700e701..15c65e50d3 100644 --- a/ui-grid/ui-grid.d.ts +++ b/ui-grid/ui-grid.d.ts @@ -12,6 +12,109 @@ /// declare module uiGrid { + export interface UIGridConstants { + LOG_DEBUG_MESSAGES: boolean; + LOG_WARN_MESSAGES: boolean; + LOG_ERROR_MESSAGES: boolean; + CUSTOM_FILTERS: RegExp; + COL_FIELD: RegExp; + MODEL_COL_FIELD: RegExp; + TOOLTIP: RegExp; + DISPLAY_CELL_TEMPLATE: RegExp; + TEMPLATE_REGEXP: RegExp; + FUNC_REGEXP: RegExp; + DOT_REGEXP: RegExp; + APOS_REGEXP: RegExp; + BRACKET_REGEXP: RegExp; + COL_CLASS_PREFIX: string; + events: { + GRID_SCROLL: string; + COLUMN_MENU_SHOWN: string; + ITEM_DRAGGING: string; + COLUMN_HEADER_CLICK: string; + }; + keymap: { + TAB: number; + STRG: number; + CAPSLOCK: number; + CTRL: number; + CTRLRIGHT: number; + CTRLR: number; + SHIFT: number; + RETURN: number; + ENTER: number; + BACKSPACE: number; + BCKSP: number; + ALT: number; + ALTR: number; + ALTRIGHT: number; + SPACE: number; + WIN: number; + MAC: number; + FN: number; + PG_UP: number; + PG_DOWN: number; + UP: number; + DOWN: number; + LEFT: number; + RIGHT: number; + ESC: number; + DEL: number; + F1: number; + F2: number; + F3: number; + F4: number; + F5: number; + F6: number; + F7: number; + F8: number; + F9: number; + F10: number; + F11: number; + F12: number; + }; + ASC: string; + DESC: string; + filter: { + STARTS_WITH: number; + ENDS_WITH: number; + EXACT: number; + CONTAINS: number; + GREATER_THAN: number; + GREATER_THAN_OR_EQUAL: number; + LESS_THAN: number; + LESS_THAN_OR_EQUAL: number; + NOT_EQUAL: number; + SELECT: string; + INPUT: string; + }; + scrollDirection: { + UP: string; + DOWN: string; + LEFT: string; + RIGHT: string; + NONE: string; + }; + aggregationTypes: { + sum: number; + count: number; + avg: number; + min: number; + max: number; + }; + CURRENCY_SYMBOLS: Array; + dataChange: { + ALL: string; + EDIT: string; + ROW: string; + COLUMN: string; + OPTIONS: string; + } + scrollbars: { + NEVER: number; + ALWAYS: number; + } + } export interface IGridInstance { appScope?: ng.IScope; columnFooterHeight?: number; @@ -65,9 +168,9 @@ declare module uiGrid { registerStyleComputation(styleComputation: ($scope: ng.IScope) => string): void; removeRowsProcessor(rows: IRowProcessor): void; resetColumnSorting(excludedColumn: IGridColumn): void; - scrollTo(rowEntity: any, colDef: IColumnDef): ng.IPromise; + scrollTo(rowEntity: IGridRow, colDef: IColumnDef): ng.IPromise; scrollToIfNecessary(gridRow: IGridRow, gridCol: IGridColumn): ng.IPromise; - sortColumn(column: IGridColumn, direction?: number, add?: boolean): ng.IPromise; + sortColumn(column: IGridColumn, direction?: string, add?: boolean): ng.IPromise; updateCanvasHeight(): void; updateFooterHeightCallback(name: string): void; } @@ -88,12 +191,13 @@ declare module uiGrid { } export interface IGridOptions { aggregationCalcThrottle?: number; - appScopeProvider?: ng.IScope; + appScopeProvider?: ng.IScope | Object; columnDefs?: IColumnDef; columnFooterHeight?: number; columnVirtualizationThreshold?: number; - data?: Array; + data?: Array | string; enableColumnMenus?: boolean; + enablePagiationControls?: boolean; enableFiltering?: boolean; enableHorizontalScrollbar?: boolean; enableMinHeightCheck?: boolean; @@ -109,7 +213,7 @@ declare module uiGrid { gridFooterTemplate?: string; gridMenuCustomItems?: Array; gridMenuShowHideColumns?: boolean; - gridMenuTitleFilter: (title: string) => ng.IPromise | string; + gridMenuTitleFilter?: (title: string) => ng.IPromise | string; headerTemplate?: string; horizontalScrollThreshold?: number; infiniteScrollDown?: boolean; @@ -118,7 +222,7 @@ declare module uiGrid { maxVisibleColumnCount?: number; minRowsToShow?: number; minimumColumnSize?: number; - onRegisterApi: (gridApi: IGridApi) => void; + onRegisterApi?: (gridApi: IGridApi) => void; rowHeight?: number; rowTemplate?: string; scrollDebounce?: number; @@ -130,12 +234,90 @@ declare module uiGrid { useExternalSorting?: boolean; virtualizationThreshold?: number; wheelScrollThrottle?: number; - getRowIdentity(): any; - rowEquality(entityA: IGridRow, entityB: IGridRow): boolean; - rowIdentity(): any; + getRowIdentity?(): any; + rowEquality?(entityA: IGridRow, entityB: IGridRow): boolean; + rowIdentity? (): any; + totalItems?: number; + paginationPageSize?: number; + paginationCurrentPage?: number; } + export interface IGridCoreApi { + addRowHeaderColumn(column: IColumnDef): void; + addToGridMenu(grid: IGridInstance, items: Array): void; + clearAllFilters(refreshRows?: boolean, clearConditions?: boolean, clearFlags?: boolean): ng.IPromise>; + clearRowInvisible(rowEntity: any): void; + getVisibleRows(grid: IGridInstance): Array; + handleWindowResize(): void; + notifiyDataChange(type: string): void; + refreshRows(): ng.IPromise; + registerColumnsProcessor(processorFunction: IColumnProcessor, priority: number): void; + registerRowsProcessor(rowProcessor: IRowProcessor, priority: number): void; + removeFromGridMenu(grid: IGridInstance, id: string): void; + scrollTo(entity: any, colDef: IColumnDef): void; /*A row entity can be anything?*/ + scrollToIfNecessary(gridRow: IGridRow, gridCol: IGridColumn): void; + setRowInvisible(rowEntity: any): void; + sortHandleNulls(a: any,b: any): number; + queueGridRefresh(): void; + queueRefresh(): void; + on: { + sortChanged: (scope: ng.IScope, handler: (grid: IGridInstance, sortColumns: Array) => void) => void; + columnVisiblityChanged: (scope: ng.IScope, handler: (grid: IGridColumn) => void) => void; + canvasHeightChanged: (scope: ng.IScope, handler: (oldHeight: number, newHeight: number) => void) => void; + + /** + * filterChangedis raised after the filter is changed. The nature of the watch expression doesn't allow notification + * of what changed, so the receiver of this event will need to re-extract the filter conditions from the columns. + * http://ui-grid.info/docs/#/api/ui.grid.core.api:PublicApi + */ + filterChanged: (scope: ng.IScope, handler: () => void) => void; + rowsRendered: (scope: ng.IScope, handler: () => void) => void; + rowsVisibleChanged: (scope: ng.IScope, handler: () => void) => void; + scrollBegin: (scope: ng.IScope, handler: () => void) => void; + scrollEnd: (scope: ng.IScope, handler: () => void) => void; + } + } + export interface IGridSelectionApi { + toggleRowSelection: (rowEntity: IGridRow, event?: Event) => void; + selectRow: (rowEntity: IGridRow, event?: Event) => void; + selectRowByVisibleIndex: (rowEntity: number, event?: Event) => void; + unSelectRow: (rowEntity: IGridRow, event?: Event) => void; + selectAllRows: (event?: Event) => void; + selectAllVisibleRows: (event?: Event) => void; + clearSelectedRows: (event?: Event) => void; + getSelectedRows: () => Array; + getSelectedGridRows: () => Array; + setMultiSelect: (multiSelect: boolean) => void; + setModifierKeysToMultiSelect: (multiSelect: boolean) => void; + getSelectAllState: () => boolean; + on: { + rowSelectionChanged: (scope: ng.IScope, handler: (row: IGridRow, event?: Event) => void) => void; + rowSelectionChangedBatch: (scope: ng.IScope, handler: (row: Array, event?: Event) => void) => void; + } + } + export interface IGridPaginationApi { + getPage: () => number; + getTotalPages: () => number; + nextPage: () => void; + previousPage: () => void; + seek: () => void; + on: { + paginationChanged: (scope: ng.IScope, handler: (newPage: number, pageSize: number) => void) => void; + } + } + export interface IGridRowEditApi { + flushDirtyRows(grid?: IGridInstance): ng.IPromise; + getDirtyRows(grid?: IGridInstance): Array; + getErrorRows(grid?: IGridInstance): Array; + setRowsClean(dataRows: Array): Array; + setRowsDirty(dataRows: Array): Array; + setSavePromise(rowEntity: Object, savePromise: ng.IPromise): void; + on: { + saveRow: (scope: ng.IScope, handler: (rowEntity: Array) => void) => void + } + } + export interface IGridApiConstructor { - new(grid: IGridInstance): IGridApi; + new (grid: IGridInstance): IGridApi; } export interface IGridApi { /** @@ -186,6 +368,33 @@ declare module uiGrid { * @param callBackFn function to execute */ suppressEvents(listenerFuncs: Function | Array, callBackFn: Function): void; + + /** + * Core Api + */ + core: IGridCoreApi; + + /** + * Selection api + */ + selection: IGridSelectionApi; + + + /** + * Pagination api + */ + pagination: IGridPaginationApi; + + + /** + * Grid Row Edit Api + */ + rowEdit: IGridRowEditApi; + + /** + * A grid instance is made available in the gridApi. + */ + grid: IGridInstance; } export interface IGridRowConstructor { /** @@ -330,6 +539,8 @@ declare module uiGrid { /** Filters for this column. Includes 'term' property bound to filter input elements */ filters?: Array; name?: string; + /** Sort on this column */ + sort?: ISortInfo /** Algorithm to use for sorting this column. Takes 'a' and 'b' parameters like any normal sorting function. */ sortingAlgorithm?: (a: any, b: any) => number; /** @@ -410,7 +621,7 @@ declare module uiGrid { * in this case your function needs to accept the full set of visible rows, * and return a value that should be shown */ - aggregationType: number | Function; + aggregationType?: number | Function; /** * cellClass can be a string specifying the class to append to a cell * or it can be a function(row,rowRenderIndex, col, colRenderIndex) @@ -604,7 +815,7 @@ declare module uiGrid { leaveOpen?: boolean; } export interface ISortInfo { - direction?: number; + direction?: string; ignoreSort?: boolean; priority?: number; } diff --git a/underscore/underscore.d.ts b/underscore/underscore.d.ts index 653d3ea074..4842224c91 100644 --- a/underscore/underscore.d.ts +++ b/underscore/underscore.d.ts @@ -2212,8 +2212,8 @@ interface Underscore { * Wrapped type `object`. * @see _.pick **/ - pick(...keys: string[]): any; - pick(keys: string[]): any; + pick(...keys: any[]): any; + pick(keys: any[]): any; pick(fn: (value: any, key: any, object: any) => any): any; /** @@ -3069,7 +3069,8 @@ interface _Chain { * Wrapped type `object`. * @see _.pick **/ - pick(...keys: string[]): _Chain; + pick(...keys: any[]): _Chain; + pick(keys: any[]): _Chain; pick(fn: (value: any, key: any, object: any) => any): _Chain; /**