rx.lua 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313
  1. -- RxLua v0.0.3
  2. -- https://github.com/bjornbytes/rxlua
  3. -- MIT License
  4. local util = {}
  5. util.pack = table.pack or function(...) return { n = select('#', ...), ... } end
  6. util.unpack = table.unpack or unpack
  7. util.eq = function(x, y) return x == y end
  8. util.noop = function() end
  9. util.identity = function(x) return x end
  10. util.constant = function(x) return function() return x end end
  11. util.isa = function(object, class)
  12. return type(object) == 'table' and getmetatable(object).__index == class
  13. end
  14. util.tryWithObserver = function(observer, fn, ...)
  15. local success, result = pcall(fn, ...)
  16. if not success then
  17. observer:onError(result)
  18. end
  19. return success, result
  20. end
  21. --- @class Subscription
  22. -- @description A handle representing the link between an Observer and an Observable, as well as any
  23. -- work required to clean up after the Observable completes or the Observer unsubscribes.
  24. local Subscription = {}
  25. Subscription.__index = Subscription
  26. Subscription.__tostring = util.constant('Subscription')
  27. --- Creates a new Subscription.
  28. -- @arg {function=} action - The action to run when the subscription is unsubscribed. It will only
  29. -- be run once.
  30. -- @returns {Subscription}
  31. function Subscription.create(action)
  32. local self = {
  33. action = action or util.noop,
  34. unsubscribed = false
  35. }
  36. return setmetatable(self, Subscription)
  37. end
  38. --- Unsubscribes the subscription, performing any necessary cleanup work.
  39. function Subscription:unsubscribe()
  40. if self.unsubscribed then return end
  41. self.action(self)
  42. self.unsubscribed = true
  43. end
  44. --- @class Observer
  45. -- @description Observers are simple objects that receive values from Observables.
  46. local Observer = {}
  47. Observer.__index = Observer
  48. Observer.__tostring = util.constant('Observer')
  49. --- Creates a new Observer.
  50. -- @arg {function=} onNext - Called when the Observable produces a value.
  51. -- @arg {function=} onError - Called when the Observable terminates due to an error.
  52. -- @arg {function=} onCompleted - Called when the Observable completes normally.
  53. -- @returns {Observer}
  54. function Observer.create(onNext, onError, onCompleted)
  55. local self = {
  56. _onNext = onNext or util.noop,
  57. _onError = onError or error,
  58. _onCompleted = onCompleted or util.noop,
  59. stopped = false
  60. }
  61. return setmetatable(self, Observer)
  62. end
  63. --- Pushes zero or more values to the Observer.
  64. -- @arg {*...} values
  65. function Observer:onNext(...)
  66. if not self.stopped then
  67. self._onNext(...)
  68. end
  69. end
  70. --- Notify the Observer that an error has occurred.
  71. -- @arg {string=} message - A string describing what went wrong.
  72. function Observer:onError(message)
  73. if not self.stopped then
  74. self.stopped = true
  75. self._onError(message)
  76. end
  77. end
  78. --- Notify the Observer that the sequence has completed and will produce no more values.
  79. function Observer:onCompleted()
  80. if not self.stopped then
  81. self.stopped = true
  82. self._onCompleted()
  83. end
  84. end
  85. --- @class Observable
  86. -- @description Observables push values to Observers.
  87. local Observable = {}
  88. Observable.__index = Observable
  89. Observable.__tostring = util.constant('Observable')
  90. --- Creates a new Observable.
  91. -- @arg {function} subscribe - The subscription function that produces values.
  92. -- @returns {Observable}
  93. function Observable.create(subscribe)
  94. local self = {
  95. _subscribe = subscribe
  96. }
  97. return setmetatable(self, Observable)
  98. end
  99. --- Shorthand for creating an Observer and passing it to this Observable's subscription function.
  100. -- @arg {function} onNext - Called when the Observable produces a value.
  101. -- @arg {function} onError - Called when the Observable terminates due to an error.
  102. -- @arg {function} onCompleted - Called when the Observable completes normally.
  103. function Observable:subscribe(onNext, onError, onCompleted)
  104. if type(onNext) == 'table' then
  105. return self._subscribe(onNext)
  106. else
  107. return self._subscribe(Observer.create(onNext, onError, onCompleted))
  108. end
  109. end
  110. --- Returns an Observable that immediately completes without producing a value.
  111. function Observable.empty()
  112. return Observable.create(function(observer)
  113. observer:onCompleted()
  114. end)
  115. end
  116. --- Returns an Observable that never produces values and never completes.
  117. function Observable.never()
  118. return Observable.create(function(observer) end)
  119. end
  120. --- Returns an Observable that immediately produces an error.
  121. function Observable.throw(message)
  122. return Observable.create(function(observer)
  123. observer:onError(message)
  124. end)
  125. end
  126. --- Creates an Observable that produces a set of values.
  127. -- @arg {*...} values
  128. -- @returns {Observable}
  129. function Observable.of(...)
  130. local args = {...}
  131. local argCount = select('#', ...)
  132. return Observable.create(function(observer)
  133. for i = 1, argCount do
  134. observer:onNext(args[i])
  135. end
  136. observer:onCompleted()
  137. end)
  138. end
  139. --- Creates an Observable that produces a range of values in a manner similar to a Lua for loop.
  140. -- @arg {number} initial - The first value of the range, or the upper limit if no other arguments
  141. -- are specified.
  142. -- @arg {number=} limit - The second value of the range.
  143. -- @arg {number=1} step - An amount to increment the value by each iteration.
  144. -- @returns {Observable}
  145. function Observable.fromRange(initial, limit, step)
  146. if not limit and not step then
  147. initial, limit = 1, initial
  148. end
  149. step = step or 1
  150. return Observable.create(function(observer)
  151. for i = initial, limit, step do
  152. observer:onNext(i)
  153. end
  154. observer:onCompleted()
  155. end)
  156. end
  157. --- Creates an Observable that produces values from a table.
  158. -- @arg {table} table - The table used to create the Observable.
  159. -- @arg {function=pairs} iterator - An iterator used to iterate the table, e.g. pairs or ipairs.
  160. -- @arg {boolean} keys - Whether or not to also emit the keys of the table.
  161. -- @returns {Observable}
  162. function Observable.fromTable(t, iterator, keys)
  163. iterator = iterator or pairs
  164. return Observable.create(function(observer)
  165. for key, value in iterator(t) do
  166. observer:onNext(value, keys and key or nil)
  167. end
  168. observer:onCompleted()
  169. end)
  170. end
  171. --- Creates an Observable that produces values when the specified coroutine yields.
  172. -- @arg {thread|function} fn - A coroutine or function to use to generate values. Note that if a
  173. -- coroutine is used, the values it yields will be shared by all
  174. -- subscribed Observers (influenced by the Scheduler), whereas a new
  175. -- coroutine will be created for each Observer when a function is used.
  176. -- @returns {Observable}
  177. function Observable.fromCoroutine(fn, scheduler)
  178. return Observable.create(function(observer)
  179. local thread = type(fn) == 'function' and coroutine.create(fn) or fn
  180. return scheduler:schedule(function()
  181. while not observer.stopped do
  182. local success, value = coroutine.resume(thread)
  183. if success then
  184. observer:onNext(value)
  185. else
  186. return observer:onError(value)
  187. end
  188. if coroutine.status(thread) == 'dead' then
  189. return observer:onCompleted()
  190. end
  191. coroutine.yield()
  192. end
  193. end)
  194. end)
  195. end
  196. --- Creates an Observable that produces values from a file, line by line.
  197. -- @arg {string} filename - The name of the file used to create the Observable
  198. -- @returns {Observable}
  199. function Observable.fromFileByLine(filename)
  200. return Observable.create(function(observer)
  201. local file = io.open(filename, 'r')
  202. if file then
  203. file:close()
  204. for line in io.lines(filename) do
  205. observer:onNext(line)
  206. end
  207. return observer:onCompleted()
  208. else
  209. return observer:onError(filename)
  210. end
  211. end)
  212. end
  213. --- Creates an Observable that creates a new Observable for each observer using a factory function.
  214. -- @arg {function} factory - A function that returns an Observable.
  215. -- @returns {Observable}
  216. function Observable.defer(fn)
  217. if not fn or type(fn) ~= 'function' then
  218. error('Expected a function')
  219. end
  220. return setmetatable({
  221. subscribe = function(_, ...)
  222. local observable = fn()
  223. return observable:subscribe(...)
  224. end
  225. }, Observable)
  226. end
  227. --- Returns an Observable that repeats a value a specified number of times.
  228. -- @arg {*} value - The value to repeat.
  229. -- @arg {number=} count - The number of times to repeat the value. If left unspecified, the value
  230. -- is repeated an infinite number of times.
  231. -- @returns {Observable}
  232. function Observable.replicate(value, count)
  233. return Observable.create(function(observer)
  234. while count == nil or count > 0 do
  235. observer:onNext(value)
  236. if count then
  237. count = count - 1
  238. end
  239. end
  240. observer:onCompleted()
  241. end)
  242. end
  243. --- Subscribes to this Observable and prints values it produces.
  244. -- @arg {string=} name - Prefixes the printed messages with a name.
  245. -- @arg {function=tostring} formatter - A function that formats one or more values to be printed.
  246. function Observable:dump(name, formatter)
  247. name = name and (name .. ' ') or ''
  248. formatter = formatter or tostring
  249. local onNext = function(...) print(name .. 'onNext: ' .. formatter(...)) end
  250. local onError = function(e) print(name .. 'onError: ' .. e) end
  251. local onCompleted = function() print(name .. 'onCompleted') end
  252. return self:subscribe(onNext, onError, onCompleted)
  253. end
  254. --- Determine whether all items emitted by an Observable meet some criteria.
  255. -- @arg {function=identity} predicate - The predicate used to evaluate objects.
  256. function Observable:all(predicate)
  257. predicate = predicate or util.identity
  258. return Observable.create(function(observer)
  259. local function onNext(...)
  260. util.tryWithObserver(observer, function(...)
  261. if not predicate(...) then
  262. observer:onNext(false)
  263. observer:onCompleted()
  264. end
  265. end, ...)
  266. end
  267. local function onError(e)
  268. return observer:onError(e)
  269. end
  270. local function onCompleted()
  271. observer:onNext(true)
  272. return observer:onCompleted()
  273. end
  274. return self:subscribe(onNext, onError, onCompleted)
  275. end)
  276. end
  277. --- Given a set of Observables, produces values from only the first one to produce a value.
  278. -- @arg {Observable...} observables
  279. -- @returns {Observable}
  280. function Observable.amb(a, b, ...)
  281. if not a or not b then return a end
  282. return Observable.create(function(observer)
  283. local subscriptionA, subscriptionB
  284. local function onNextA(...)
  285. if subscriptionB then subscriptionB:unsubscribe() end
  286. observer:onNext(...)
  287. end
  288. local function onErrorA(e)
  289. if subscriptionB then subscriptionB:unsubscribe() end
  290. observer:onError(e)
  291. end
  292. local function onCompletedA()
  293. if subscriptionB then subscriptionB:unsubscribe() end
  294. observer:onCompleted()
  295. end
  296. local function onNextB(...)
  297. if subscriptionA then subscriptionA:unsubscribe() end
  298. observer:onNext(...)
  299. end
  300. local function onErrorB(e)
  301. if subscriptionA then subscriptionA:unsubscribe() end
  302. observer:onError(e)
  303. end
  304. local function onCompletedB()
  305. if subscriptionA then subscriptionA:unsubscribe() end
  306. observer:onCompleted()
  307. end
  308. subscriptionA = a:subscribe(onNextA, onErrorA, onCompletedA)
  309. subscriptionB = b:subscribe(onNextB, onErrorB, onCompletedB)
  310. return Subscription.create(function()
  311. subscriptionA:unsubscribe()
  312. subscriptionB:unsubscribe()
  313. end)
  314. end):amb(...)
  315. end
  316. --- Returns an Observable that produces the average of all values produced by the original.
  317. -- @returns {Observable}
  318. function Observable:average()
  319. return Observable.create(function(observer)
  320. local sum, count = 0, 0
  321. local function onNext(value)
  322. sum = sum + value
  323. count = count + 1
  324. end
  325. local function onError(e)
  326. observer:onError(e)
  327. end
  328. local function onCompleted()
  329. if count > 0 then
  330. observer:onNext(sum / count)
  331. end
  332. observer:onCompleted()
  333. end
  334. return self:subscribe(onNext, onError, onCompleted)
  335. end)
  336. end
  337. --- Returns an Observable that buffers values from the original and produces them as multiple
  338. -- values.
  339. -- @arg {number} size - The size of the buffer.
  340. function Observable:buffer(size)
  341. if not size or type(size) ~= 'number' then
  342. error('Expected a number')
  343. end
  344. return Observable.create(function(observer)
  345. local buffer = {}
  346. local function emit()
  347. if #buffer > 0 then
  348. observer:onNext(util.unpack(buffer))
  349. buffer = {}
  350. end
  351. end
  352. local function onNext(...)
  353. local values = {...}
  354. for i = 1, #values do
  355. table.insert(buffer, values[i])
  356. if #buffer >= size then
  357. emit()
  358. end
  359. end
  360. end
  361. local function onError(message)
  362. emit()
  363. return observer:onError(message)
  364. end
  365. local function onCompleted()
  366. emit()
  367. return observer:onCompleted()
  368. end
  369. return self:subscribe(onNext, onError, onCompleted)
  370. end)
  371. end
  372. --- Returns an Observable that intercepts any errors from the previous and replace them with values
  373. -- produced by a new Observable.
  374. -- @arg {function|Observable} handler - An Observable or a function that returns an Observable to
  375. -- replace the source Observable in the event of an error.
  376. -- @returns {Observable}
  377. function Observable:catch(handler)
  378. handler = handler and (type(handler) == 'function' and handler or util.constant(handler))
  379. return Observable.create(function(observer)
  380. local subscription
  381. local function onNext(...)
  382. return observer:onNext(...)
  383. end
  384. local function onError(e)
  385. if not handler then
  386. return observer:onCompleted()
  387. end
  388. local success, _continue = pcall(handler, e)
  389. if success and _continue then
  390. if subscription then subscription:unsubscribe() end
  391. _continue:subscribe(observer)
  392. else
  393. observer:onError(success and e or _continue)
  394. end
  395. end
  396. local function onCompleted()
  397. observer:onCompleted()
  398. end
  399. subscription = self:subscribe(onNext, onError, onCompleted)
  400. return subscription
  401. end)
  402. end
  403. --- Returns a new Observable that runs a combinator function on the most recent values from a set
  404. -- of Observables whenever any of them produce a new value. The results of the combinator function
  405. -- are produced by the new Observable.
  406. -- @arg {Observable...} observables - One or more Observables to combine.
  407. -- @arg {function} combinator - A function that combines the latest result from each Observable and
  408. -- returns a single value.
  409. -- @returns {Observable}
  410. function Observable:combineLatest(...)
  411. local sources = {...}
  412. local combinator = table.remove(sources)
  413. if type(combinator) ~= 'function' then
  414. table.insert(sources, combinator)
  415. combinator = function(...) return ... end
  416. end
  417. table.insert(sources, 1, self)
  418. return Observable.create(function(observer)
  419. local latest = {}
  420. local pending = {util.unpack(sources)}
  421. local completed = {}
  422. local subscription = {}
  423. local function onNext(i)
  424. return function(value)
  425. latest[i] = value
  426. pending[i] = nil
  427. if not next(pending) then
  428. util.tryWithObserver(observer, function()
  429. observer:onNext(combinator(util.unpack(latest)))
  430. end)
  431. end
  432. end
  433. end
  434. local function onError(e)
  435. return observer:onError(e)
  436. end
  437. local function onCompleted(i)
  438. return function()
  439. table.insert(completed, i)
  440. if #completed == #sources then
  441. observer:onCompleted()
  442. end
  443. end
  444. end
  445. for i = 1, #sources do
  446. subscription[i] = sources[i]:subscribe(onNext(i), onError, onCompleted(i))
  447. end
  448. return Subscription.create(function ()
  449. for i = 1, #sources do
  450. if subscription[i] then subscription[i]:unsubscribe() end
  451. end
  452. end)
  453. end)
  454. end
  455. --- Returns a new Observable that produces the values of the first with falsy values removed.
  456. -- @returns {Observable}
  457. function Observable:compact()
  458. return self:filter(util.identity)
  459. end
  460. --- Returns a new Observable that produces the values produced by all the specified Observables in
  461. -- the order they are specified.
  462. -- @arg {Observable...} sources - The Observables to concatenate.
  463. -- @returns {Observable}
  464. function Observable:concat(other, ...)
  465. if not other then return self end
  466. local others = {...}
  467. return Observable.create(function(observer)
  468. local function onNext(...)
  469. return observer:onNext(...)
  470. end
  471. local function onError(message)
  472. return observer:onError(message)
  473. end
  474. local function onCompleted()
  475. return observer:onCompleted()
  476. end
  477. local function chain()
  478. return other:concat(util.unpack(others)):subscribe(onNext, onError, onCompleted)
  479. end
  480. return self:subscribe(onNext, onError, chain)
  481. end)
  482. end
  483. --- Returns a new Observable that produces a single boolean value representing whether or not the
  484. -- specified value was produced by the original.
  485. -- @arg {*} value - The value to search for. == is used for equality testing.
  486. -- @returns {Observable}
  487. function Observable:contains(value)
  488. return Observable.create(function(observer)
  489. local subscription
  490. local function onNext(...)
  491. local args = util.pack(...)
  492. if #args == 0 and value == nil then
  493. observer:onNext(true)
  494. if subscription then subscription:unsubscribe() end
  495. return observer:onCompleted()
  496. end
  497. for i = 1, #args do
  498. if args[i] == value then
  499. observer:onNext(true)
  500. if subscription then subscription:unsubscribe() end
  501. return observer:onCompleted()
  502. end
  503. end
  504. end
  505. local function onError(e)
  506. return observer:onError(e)
  507. end
  508. local function onCompleted()
  509. observer:onNext(false)
  510. return observer:onCompleted()
  511. end
  512. subscription = self:subscribe(onNext, onError, onCompleted)
  513. return subscription
  514. end)
  515. end
  516. --- Returns an Observable that produces a single value representing the number of values produced
  517. -- by the source value that satisfy an optional predicate.
  518. -- @arg {function=} predicate - The predicate used to match values.
  519. function Observable:count(predicate)
  520. predicate = predicate or util.constant(true)
  521. return Observable.create(function(observer)
  522. local count = 0
  523. local function onNext(...)
  524. util.tryWithObserver(observer, function(...)
  525. if predicate(...) then
  526. count = count + 1
  527. end
  528. end, ...)
  529. end
  530. local function onError(e)
  531. return observer:onError(e)
  532. end
  533. local function onCompleted()
  534. observer:onNext(count)
  535. observer:onCompleted()
  536. end
  537. return self:subscribe(onNext, onError, onCompleted)
  538. end)
  539. end
  540. --- Returns a new throttled Observable that waits to produce values until a timeout has expired, at
  541. -- which point it produces the latest value from the source Observable. Whenever the source
  542. -- Observable produces a value, the timeout is reset.
  543. -- @arg {number|function} time - An amount in milliseconds to wait before producing the last value.
  544. -- @arg {Scheduler} scheduler - The scheduler to run the Observable on.
  545. -- @returns {Observable}
  546. function Observable:debounce(time, scheduler)
  547. time = time or 0
  548. return Observable.create(function(observer)
  549. local debounced = {}
  550. local function wrap(key)
  551. return function(...)
  552. local value = util.pack(...)
  553. if debounced[key] then
  554. debounced[key]:unsubscribe()
  555. end
  556. local values = util.pack(...)
  557. debounced[key] = scheduler:schedule(function()
  558. return observer[key](observer, util.unpack(values))
  559. end, time)
  560. end
  561. end
  562. local subscription = self:subscribe(wrap('onNext'), wrap('onError'), wrap('onCompleted'))
  563. return Subscription.create(function()
  564. if subscription then subscription:unsubscribe() end
  565. for _, timeout in pairs(debounced) do
  566. timeout:unsubscribe()
  567. end
  568. end)
  569. end)
  570. end
  571. --- Returns a new Observable that produces a default set of items if the source Observable produces
  572. -- no values.
  573. -- @arg {*...} values - Zero or more values to produce if the source completes without emitting
  574. -- anything.
  575. -- @returns {Observable}
  576. function Observable:defaultIfEmpty(...)
  577. local defaults = util.pack(...)
  578. return Observable.create(function(observer)
  579. local hasValue = false
  580. local function onNext(...)
  581. hasValue = true
  582. observer:onNext(...)
  583. end
  584. local function onError(e)
  585. observer:onError(e)
  586. end
  587. local function onCompleted()
  588. if not hasValue then
  589. observer:onNext(util.unpack(defaults))
  590. end
  591. observer:onCompleted()
  592. end
  593. return self:subscribe(onNext, onError, onCompleted)
  594. end)
  595. end
  596. --- Returns a new Observable that produces the values of the original delayed by a time period.
  597. -- @arg {number|function} time - An amount in milliseconds to delay by, or a function which returns
  598. -- this value.
  599. -- @arg {Scheduler} scheduler - The scheduler to run the Observable on.
  600. -- @returns {Observable}
  601. function Observable:delay(time, scheduler)
  602. time = type(time) ~= 'function' and util.constant(time) or time
  603. return Observable.create(function(observer)
  604. local actions = {}
  605. local function delay(key)
  606. return function(...)
  607. local arg = util.pack(...)
  608. local handle = scheduler:schedule(function()
  609. observer[key](observer, util.unpack(arg))
  610. end, time())
  611. table.insert(actions, handle)
  612. end
  613. end
  614. local subscription = self:subscribe(delay('onNext'), delay('onError'), delay('onCompleted'))
  615. return Subscription.create(function()
  616. if subscription then subscription:unsubscribe() end
  617. for i = 1, #actions do
  618. actions[i]:unsubscribe()
  619. end
  620. end)
  621. end)
  622. end
  623. --- Returns a new Observable that produces the values from the original with duplicates removed.
  624. -- @returns {Observable}
  625. function Observable:distinct()
  626. return Observable.create(function(observer)
  627. local values = {}
  628. local function onNext(x)
  629. if not values[x] then
  630. observer:onNext(x)
  631. end
  632. values[x] = true
  633. end
  634. local function onError(e)
  635. return observer:onError(e)
  636. end
  637. local function onCompleted()
  638. return observer:onCompleted()
  639. end
  640. return self:subscribe(onNext, onError, onCompleted)
  641. end)
  642. end
  643. --- Returns an Observable that only produces values from the original if they are different from
  644. -- the previous value.
  645. -- @arg {function} comparator - A function used to compare 2 values. If unspecified, == is used.
  646. -- @returns {Observable}
  647. function Observable:distinctUntilChanged(comparator)
  648. comparator = comparator or util.eq
  649. return Observable.create(function(observer)
  650. local first = true
  651. local currentValue = nil
  652. local function onNext(value, ...)
  653. local values = util.pack(...)
  654. util.tryWithObserver(observer, function()
  655. if first or not comparator(value, currentValue) then
  656. observer:onNext(value, util.unpack(values))
  657. currentValue = value
  658. first = false
  659. end
  660. end)
  661. end
  662. local function onError(message)
  663. return observer:onError(message)
  664. end
  665. local function onCompleted()
  666. return observer:onCompleted()
  667. end
  668. return self:subscribe(onNext, onError, onCompleted)
  669. end)
  670. end
  671. --- Returns an Observable that produces the nth element produced by the source Observable.
  672. -- @arg {number} index - The index of the item, with an index of 1 representing the first.
  673. -- @returns {Observable}
  674. function Observable:elementAt(index)
  675. if not index or type(index) ~= 'number' then
  676. error('Expected a number')
  677. end
  678. return Observable.create(function(observer)
  679. local subscription
  680. local i = 1
  681. local function onNext(...)
  682. if i == index then
  683. observer:onNext(...)
  684. observer:onCompleted()
  685. if subscription then
  686. subscription:unsubscribe()
  687. end
  688. else
  689. i = i + 1
  690. end
  691. end
  692. local function onError(e)
  693. return observer:onError(e)
  694. end
  695. local function onCompleted()
  696. return observer:onCompleted()
  697. end
  698. subscription = self:subscribe(onNext, onError, onCompleted)
  699. return subscription
  700. end)
  701. end
  702. --- Returns a new Observable that only produces values of the first that satisfy a predicate.
  703. -- @arg {function} predicate - The predicate used to filter values.
  704. -- @returns {Observable}
  705. function Observable:filter(predicate)
  706. predicate = predicate or util.identity
  707. return Observable.create(function(observer)
  708. local function onNext(...)
  709. util.tryWithObserver(observer, function(...)
  710. if predicate(...) then
  711. return observer:onNext(...)
  712. end
  713. end, ...)
  714. end
  715. local function onError(e)
  716. return observer:onError(e)
  717. end
  718. local function onCompleted()
  719. return observer:onCompleted()
  720. end
  721. return self:subscribe(onNext, onError, onCompleted)
  722. end)
  723. end
  724. --- Returns a new Observable that produces the first value of the original that satisfies a
  725. -- predicate.
  726. -- @arg {function} predicate - The predicate used to find a value.
  727. function Observable:find(predicate)
  728. predicate = predicate or util.identity
  729. return Observable.create(function(observer)
  730. local function onNext(...)
  731. util.tryWithObserver(observer, function(...)
  732. if predicate(...) then
  733. observer:onNext(...)
  734. return observer:onCompleted()
  735. end
  736. end, ...)
  737. end
  738. local function onError(message)
  739. return observer:onError(message)
  740. end
  741. local function onCompleted()
  742. return observer:onCompleted()
  743. end
  744. return self:subscribe(onNext, onError, onCompleted)
  745. end)
  746. end
  747. --- Returns a new Observable that only produces the first result of the original.
  748. -- @returns {Observable}
  749. function Observable:first()
  750. return self:take(1)
  751. end
  752. --- Returns a new Observable that transform the items emitted by an Observable into Observables,
  753. -- then flatten the emissions from those into a single Observable
  754. -- @arg {function} callback - The function to transform values from the original Observable.
  755. -- @returns {Observable}
  756. function Observable:flatMap(callback)
  757. callback = callback or util.identity
  758. return self:map(callback):flatten()
  759. end
  760. --- Returns a new Observable that uses a callback to create Observables from the values produced by
  761. -- the source, then produces values from the most recent of these Observables.
  762. -- @arg {function=identity} callback - The function used to convert values to Observables.
  763. -- @returns {Observable}
  764. function Observable:flatMapLatest(callback)
  765. callback = callback or util.identity
  766. return Observable.create(function(observer)
  767. local innerSubscription
  768. local function onNext(...)
  769. observer:onNext(...)
  770. end
  771. local function onError(e)
  772. return observer:onError(e)
  773. end
  774. local function onCompleted()
  775. return observer:onCompleted()
  776. end
  777. local function subscribeInner(...)
  778. if innerSubscription then
  779. innerSubscription:unsubscribe()
  780. end
  781. return util.tryWithObserver(observer, function(...)
  782. innerSubscription = callback(...):subscribe(onNext, onError)
  783. end, ...)
  784. end
  785. local subscription = self:subscribe(subscribeInner, onError, onCompleted)
  786. return Subscription.create(function()
  787. if innerSubscription then
  788. innerSubscription:unsubscribe()
  789. end
  790. if subscription then
  791. subscription:unsubscribe()
  792. end
  793. end)
  794. end)
  795. end
  796. --- Returns a new Observable that subscribes to the Observables produced by the original and
  797. -- produces their values.
  798. -- @returns {Observable}
  799. function Observable:flatten()
  800. return Observable.create(function(observer)
  801. local subscriptions = {}
  802. local function onError(message)
  803. return observer:onError(message)
  804. end
  805. local function onNext(observable)
  806. local function innerOnNext(...)
  807. observer:onNext(...)
  808. end
  809. local subscription = observable:subscribe(innerOnNext, onError, util.noop)
  810. subscriptions[#subscriptions + 1] = subscription
  811. end
  812. local function onCompleted()
  813. return observer:onCompleted()
  814. end
  815. subscriptions[#subscriptions + 1] = self:subscribe(onNext, onError, onCompleted)
  816. return Subscription.create(function ()
  817. for i = 1, #subscriptions do
  818. subscriptions[i]:unsubscribe()
  819. end
  820. end)
  821. end)
  822. end
  823. --- Returns an Observable that terminates when the source terminates but does not produce any
  824. -- elements.
  825. -- @returns {Observable}
  826. function Observable:ignoreElements()
  827. return Observable.create(function(observer)
  828. local function onError(message)
  829. return observer:onError(message)
  830. end
  831. local function onCompleted()
  832. return observer:onCompleted()
  833. end
  834. return self:subscribe(nil, onError, onCompleted)
  835. end)
  836. end
  837. --- Returns a new Observable that only produces the last result of the original.
  838. -- @returns {Observable}
  839. function Observable:last()
  840. return Observable.create(function(observer)
  841. local value
  842. local empty = true
  843. local function onNext(...)
  844. value = {...}
  845. empty = false
  846. end
  847. local function onError(e)
  848. return observer:onError(e)
  849. end
  850. local function onCompleted()
  851. if not empty then
  852. observer:onNext(util.unpack(value or {}))
  853. end
  854. return observer:onCompleted()
  855. end
  856. return self:subscribe(onNext, onError, onCompleted)
  857. end)
  858. end
  859. --- Returns a new Observable that produces the values of the original transformed by a function.
  860. -- @arg {function} callback - The function to transform values from the original Observable.
  861. -- @returns {Observable}
  862. function Observable:map(callback)
  863. return Observable.create(function(observer)
  864. callback = callback or util.identity
  865. local function onNext(...)
  866. return util.tryWithObserver(observer, function(...)
  867. return observer:onNext(callback(...))
  868. end, ...)
  869. end
  870. local function onError(e)
  871. return observer:onError(e)
  872. end
  873. local function onCompleted()
  874. return observer:onCompleted()
  875. end
  876. return self:subscribe(onNext, onError, onCompleted)
  877. end)
  878. end
  879. --- Returns a new Observable that produces the maximum value produced by the original.
  880. -- @returns {Observable}
  881. function Observable:max()
  882. return self:reduce(math.max)
  883. end
  884. --- Returns a new Observable that produces the values produced by all the specified Observables in
  885. -- the order they are produced.
  886. -- @arg {Observable...} sources - One or more Observables to merge.
  887. -- @returns {Observable}
  888. function Observable:merge(...)
  889. local sources = {...}
  890. table.insert(sources, 1, self)
  891. return Observable.create(function(observer)
  892. local completed = {}
  893. local subscriptions = {}
  894. local function onNext(...)
  895. return observer:onNext(...)
  896. end
  897. local function onError(message)
  898. return observer:onError(message)
  899. end
  900. local function onCompleted(i)
  901. return function()
  902. table.insert(completed, i)
  903. if #completed == #sources then
  904. observer:onCompleted()
  905. end
  906. end
  907. end
  908. for i = 1, #sources do
  909. subscriptions[i] = sources[i]:subscribe(onNext, onError, onCompleted(i))
  910. end
  911. return Subscription.create(function ()
  912. for i = 1, #sources do
  913. if subscriptions[i] then subscriptions[i]:unsubscribe() end
  914. end
  915. end)
  916. end)
  917. end
  918. --- Returns a new Observable that produces the minimum value produced by the original.
  919. -- @returns {Observable}
  920. function Observable:min()
  921. return self:reduce(math.min)
  922. end
  923. --- Returns an Observable that produces the values of the original inside tables.
  924. -- @returns {Observable}
  925. function Observable:pack()
  926. return self:map(util.pack)
  927. end
  928. --- Returns two Observables: one that produces values for which the predicate returns truthy for,
  929. -- and another that produces values for which the predicate returns falsy.
  930. -- @arg {function} predicate - The predicate used to partition the values.
  931. -- @returns {Observable}
  932. -- @returns {Observable}
  933. function Observable:partition(predicate)
  934. return self:filter(predicate), self:reject(predicate)
  935. end
  936. --- Returns a new Observable that produces values computed by extracting the given keys from the
  937. -- tables produced by the original.
  938. -- @arg {string...} keys - The key to extract from the table. Multiple keys can be specified to
  939. -- recursively pluck values from nested tables.
  940. -- @returns {Observable}
  941. function Observable:pluck(key, ...)
  942. if not key then return self end
  943. if type(key) ~= 'string' and type(key) ~= 'number' then
  944. return Observable.throw('pluck key must be a string')
  945. end
  946. return Observable.create(function(observer)
  947. local function onNext(t)
  948. return observer:onNext(t[key])
  949. end
  950. local function onError(e)
  951. return observer:onError(e)
  952. end
  953. local function onCompleted()
  954. return observer:onCompleted()
  955. end
  956. return self:subscribe(onNext, onError, onCompleted)
  957. end):pluck(...)
  958. end
  959. --- Returns a new Observable that produces a single value computed by accumulating the results of
  960. -- running a function on each value produced by the original Observable.
  961. -- @arg {function} accumulator - Accumulates the values of the original Observable. Will be passed
  962. -- the return value of the last call as the first argument and the
  963. -- current values as the rest of the arguments.
  964. -- @arg {*} seed - A value to pass to the accumulator the first time it is run.
  965. -- @returns {Observable}
  966. function Observable:reduce(accumulator, seed)
  967. return Observable.create(function(observer)
  968. local result = seed
  969. local first = true
  970. local function onNext(...)
  971. if first and seed == nil then
  972. result = ...
  973. first = false
  974. else
  975. return util.tryWithObserver(observer, function(...)
  976. result = accumulator(result, ...)
  977. end, ...)
  978. end
  979. end
  980. local function onError(e)
  981. return observer:onError(e)
  982. end
  983. local function onCompleted()
  984. observer:onNext(result)
  985. return observer:onCompleted()
  986. end
  987. return self:subscribe(onNext, onError, onCompleted)
  988. end)
  989. end
  990. --- Returns a new Observable that produces values from the original which do not satisfy a
  991. -- predicate.
  992. -- @arg {function} predicate - The predicate used to reject values.
  993. -- @returns {Observable}
  994. function Observable:reject(predicate)
  995. predicate = predicate or util.identity
  996. return Observable.create(function(observer)
  997. local function onNext(...)
  998. util.tryWithObserver(observer, function(...)
  999. if not predicate(...) then
  1000. return observer:onNext(...)
  1001. end
  1002. end, ...)
  1003. end
  1004. local function onError(e)
  1005. return observer:onError(e)
  1006. end
  1007. local function onCompleted()
  1008. return observer:onCompleted()
  1009. end
  1010. return self:subscribe(onNext, onError, onCompleted)
  1011. end)
  1012. end
  1013. --- Returns an Observable that restarts in the event of an error.
  1014. -- @arg {number=} count - The maximum number of times to retry. If left unspecified, an infinite
  1015. -- number of retries will be attempted.
  1016. -- @returns {Observable}
  1017. function Observable:retry(count)
  1018. return Observable.create(function(observer)
  1019. local subscription
  1020. local retries = 0
  1021. local function onNext(...)
  1022. return observer:onNext(...)
  1023. end
  1024. local function onCompleted()
  1025. return observer:onCompleted()
  1026. end
  1027. local function onError(message)
  1028. if subscription then
  1029. subscription:unsubscribe()
  1030. end
  1031. retries = retries + 1
  1032. if count and retries > count then
  1033. return observer:onError(message)
  1034. end
  1035. subscription = self:subscribe(onNext, onError, onCompleted)
  1036. end
  1037. return self:subscribe(onNext, onError, onCompleted)
  1038. end)
  1039. end
  1040. --- Returns a new Observable that produces its most recent value every time the specified observable
  1041. -- produces a value.
  1042. -- @arg {Observable} sampler - The Observable that is used to sample values from this Observable.
  1043. -- @returns {Observable}
  1044. function Observable:sample(sampler)
  1045. if not sampler then error('Expected an Observable') end
  1046. return Observable.create(function(observer)
  1047. local latest = {}
  1048. local function setLatest(...)
  1049. latest = util.pack(...)
  1050. end
  1051. local function onNext()
  1052. if #latest > 0 then
  1053. return observer:onNext(util.unpack(latest))
  1054. end
  1055. end
  1056. local function onError(message)
  1057. return observer:onError(message)
  1058. end
  1059. local function onCompleted()
  1060. return observer:onCompleted()
  1061. end
  1062. local sourceSubscription = self:subscribe(setLatest, onError)
  1063. local sampleSubscription = sampler:subscribe(onNext, onError, onCompleted)
  1064. return Subscription.create(function()
  1065. if sourceSubscription then sourceSubscription:unsubscribe() end
  1066. if sampleSubscription then sampleSubscription:unsubscribe() end
  1067. end)
  1068. end)
  1069. end
  1070. --- Returns a new Observable that produces values computed by accumulating the results of running a
  1071. -- function on each value produced by the original Observable.
  1072. -- @arg {function} accumulator - Accumulates the values of the original Observable. Will be passed
  1073. -- the return value of the last call as the first argument and the
  1074. -- current values as the rest of the arguments. Each value returned
  1075. -- from this function will be emitted by the Observable.
  1076. -- @arg {*} seed - A value to pass to the accumulator the first time it is run.
  1077. -- @returns {Observable}
  1078. function Observable:scan(accumulator, seed)
  1079. return Observable.create(function(observer)
  1080. local result = seed
  1081. local first = true
  1082. local function onNext(...)
  1083. if first and seed == nil then
  1084. result = ...
  1085. first = false
  1086. else
  1087. return util.tryWithObserver(observer, function(...)
  1088. result = accumulator(result, ...)
  1089. observer:onNext(result)
  1090. end, ...)
  1091. end
  1092. end
  1093. local function onError(e)
  1094. return observer:onError(e)
  1095. end
  1096. local function onCompleted()
  1097. return observer:onCompleted()
  1098. end
  1099. return self:subscribe(onNext, onError, onCompleted)
  1100. end)
  1101. end
  1102. --- Returns a new Observable that skips over a specified number of values produced by the original
  1103. -- and produces the rest.
  1104. -- @arg {number=1} n - The number of values to ignore.
  1105. -- @returns {Observable}
  1106. function Observable:skip(n)
  1107. n = n or 1
  1108. return Observable.create(function(observer)
  1109. local i = 1
  1110. local function onNext(...)
  1111. if i > n then
  1112. observer:onNext(...)
  1113. else
  1114. i = i + 1
  1115. end
  1116. end
  1117. local function onError(e)
  1118. return observer:onError(e)
  1119. end
  1120. local function onCompleted()
  1121. return observer:onCompleted()
  1122. end
  1123. return self:subscribe(onNext, onError, onCompleted)
  1124. end)
  1125. end
  1126. --- Returns an Observable that omits a specified number of values from the end of the original
  1127. -- Observable.
  1128. -- @arg {number} count - The number of items to omit from the end.
  1129. -- @returns {Observable}
  1130. function Observable:skipLast(count)
  1131. if not count or type(count) ~= 'number' then
  1132. error('Expected a number')
  1133. end
  1134. local buffer = {}
  1135. return Observable.create(function(observer)
  1136. local function emit()
  1137. if #buffer > count and buffer[1] then
  1138. local values = table.remove(buffer, 1)
  1139. observer:onNext(util.unpack(values))
  1140. end
  1141. end
  1142. local function onNext(...)
  1143. emit()
  1144. table.insert(buffer, util.pack(...))
  1145. end
  1146. local function onError(message)
  1147. return observer:onError(message)
  1148. end
  1149. local function onCompleted()
  1150. emit()
  1151. return observer:onCompleted()
  1152. end
  1153. return self:subscribe(onNext, onError, onCompleted)
  1154. end)
  1155. end
  1156. --- Returns a new Observable that skips over values produced by the original until the specified
  1157. -- Observable produces a value.
  1158. -- @arg {Observable} other - The Observable that triggers the production of values.
  1159. -- @returns {Observable}
  1160. function Observable:skipUntil(other)
  1161. return Observable.create(function(observer)
  1162. local triggered = false
  1163. local function trigger()
  1164. triggered = true
  1165. end
  1166. other:subscribe(trigger, trigger, trigger)
  1167. local function onNext(...)
  1168. if triggered then
  1169. observer:onNext(...)
  1170. end
  1171. end
  1172. local function onError()
  1173. if triggered then
  1174. observer:onError()
  1175. end
  1176. end
  1177. local function onCompleted()
  1178. if triggered then
  1179. observer:onCompleted()
  1180. end
  1181. end
  1182. return self:subscribe(onNext, onError, onCompleted)
  1183. end)
  1184. end
  1185. --- Returns a new Observable that skips elements until the predicate returns falsy for one of them.
  1186. -- @arg {function} predicate - The predicate used to continue skipping values.
  1187. -- @returns {Observable}
  1188. function Observable:skipWhile(predicate)
  1189. predicate = predicate or util.identity
  1190. return Observable.create(function(observer)
  1191. local skipping = true
  1192. local function onNext(...)
  1193. if skipping then
  1194. util.tryWithObserver(observer, function(...)
  1195. skipping = predicate(...)
  1196. end, ...)
  1197. end
  1198. if not skipping then
  1199. return observer:onNext(...)
  1200. end
  1201. end
  1202. local function onError(message)
  1203. return observer:onError(message)
  1204. end
  1205. local function onCompleted()
  1206. return observer:onCompleted()
  1207. end
  1208. return self:subscribe(onNext, onError, onCompleted)
  1209. end)
  1210. end
  1211. --- Returns a new Observable that produces the specified values followed by all elements produced by
  1212. -- the source Observable.
  1213. -- @arg {*...} values - The values to produce before the Observable begins producing values
  1214. -- normally.
  1215. -- @returns {Observable}
  1216. function Observable:startWith(...)
  1217. local values = util.pack(...)
  1218. return Observable.create(function(observer)
  1219. observer:onNext(util.unpack(values))
  1220. return self:subscribe(observer)
  1221. end)
  1222. end
  1223. --- Returns an Observable that produces a single value representing the sum of the values produced
  1224. -- by the original.
  1225. -- @returns {Observable}
  1226. function Observable:sum()
  1227. return self:reduce(function(x, y) return x + y end, 0)
  1228. end
  1229. --- Given an Observable that produces Observables, returns an Observable that produces the values
  1230. -- produced by the most recently produced Observable.
  1231. -- @returns {Observable}
  1232. function Observable:switch()
  1233. return Observable.create(function(observer)
  1234. local innerSubscription
  1235. local function onNext(...)
  1236. return observer:onNext(...)
  1237. end
  1238. local function onError(message)
  1239. return observer:onError(message)
  1240. end
  1241. local function onCompleted()
  1242. return observer:onCompleted()
  1243. end
  1244. local function switch(source)
  1245. if innerSubscription then
  1246. innerSubscription:unsubscribe()
  1247. end
  1248. innerSubscription = source:subscribe(onNext, onError, nil)
  1249. end
  1250. local subscription = self:subscribe(switch, onError, onCompleted)
  1251. return Subscription.create(function()
  1252. if innerSubscription then
  1253. innerSubscription:unsubscribe()
  1254. end
  1255. if subscription then
  1256. subscription:unsubscribe()
  1257. end
  1258. end)
  1259. end)
  1260. end
  1261. --- Returns a new Observable that only produces the first n results of the original.
  1262. -- @arg {number=1} n - The number of elements to produce before completing.
  1263. -- @returns {Observable}
  1264. function Observable:take(n)
  1265. n = n or 1
  1266. return Observable.create(function(observer)
  1267. if n <= 0 then
  1268. observer:onCompleted()
  1269. return
  1270. end
  1271. local i = 1
  1272. local function onNext(...)
  1273. observer:onNext(...)
  1274. i = i + 1
  1275. if i > n then
  1276. observer:onCompleted()
  1277. end
  1278. end
  1279. local function onError(e)
  1280. return observer:onError(e)
  1281. end
  1282. local function onCompleted()
  1283. return observer:onCompleted()
  1284. end
  1285. return self:subscribe(onNext, onError, onCompleted)
  1286. end)
  1287. end
  1288. --- Returns an Observable that produces a specified number of elements from the end of a source
  1289. -- Observable.
  1290. -- @arg {number} count - The number of elements to produce.
  1291. -- @returns {Observable}
  1292. function Observable:takeLast(count)
  1293. if not count or type(count) ~= 'number' then
  1294. error('Expected a number')
  1295. end
  1296. return Observable.create(function(observer)
  1297. local buffer = {}
  1298. local function onNext(...)
  1299. table.insert(buffer, util.pack(...))
  1300. if #buffer > count then
  1301. table.remove(buffer, 1)
  1302. end
  1303. end
  1304. local function onError(message)
  1305. return observer:onError(message)
  1306. end
  1307. local function onCompleted()
  1308. for i = 1, #buffer do
  1309. observer:onNext(util.unpack(buffer[i]))
  1310. end
  1311. return observer:onCompleted()
  1312. end
  1313. return self:subscribe(onNext, onError, onCompleted)
  1314. end)
  1315. end
  1316. --- Returns a new Observable that completes when the specified Observable fires.
  1317. -- @arg {Observable} other - The Observable that triggers completion of the original.
  1318. -- @returns {Observable}
  1319. function Observable:takeUntil(other)
  1320. return Observable.create(function(observer)
  1321. local function onNext(...)
  1322. return observer:onNext(...)
  1323. end
  1324. local function onError(e)
  1325. return observer:onError(e)
  1326. end
  1327. local function onCompleted()
  1328. return observer:onCompleted()
  1329. end
  1330. other:subscribe(onCompleted, onCompleted, onCompleted)
  1331. return self:subscribe(onNext, onError, onCompleted)
  1332. end)
  1333. end
  1334. --- Returns a new Observable that produces elements until the predicate returns falsy.
  1335. -- @arg {function} predicate - The predicate used to continue production of values.
  1336. -- @returns {Observable}
  1337. function Observable:takeWhile(predicate)
  1338. predicate = predicate or util.identity
  1339. return Observable.create(function(observer)
  1340. local taking = true
  1341. local function onNext(...)
  1342. if taking then
  1343. util.tryWithObserver(observer, function(...)
  1344. taking = predicate(...)
  1345. end, ...)
  1346. if taking then
  1347. return observer:onNext(...)
  1348. else
  1349. return observer:onCompleted()
  1350. end
  1351. end
  1352. end
  1353. local function onError(message)
  1354. return observer:onError(message)
  1355. end
  1356. local function onCompleted()
  1357. return observer:onCompleted()
  1358. end
  1359. return self:subscribe(onNext, onError, onCompleted)
  1360. end)
  1361. end
  1362. --- Runs a function each time this Observable has activity. Similar to subscribe but does not
  1363. -- create a subscription.
  1364. -- @arg {function=} onNext - Run when the Observable produces values.
  1365. -- @arg {function=} onError - Run when the Observable encounters a problem.
  1366. -- @arg {function=} onCompleted - Run when the Observable completes.
  1367. -- @returns {Observable}
  1368. function Observable:tap(_onNext, _onError, _onCompleted)
  1369. _onNext = _onNext or util.noop
  1370. _onError = _onError or util.noop
  1371. _onCompleted = _onCompleted or util.noop
  1372. return Observable.create(function(observer)
  1373. local function onNext(...)
  1374. util.tryWithObserver(observer, function(...)
  1375. _onNext(...)
  1376. end, ...)
  1377. return observer:onNext(...)
  1378. end
  1379. local function onError(message)
  1380. util.tryWithObserver(observer, function()
  1381. _onError(message)
  1382. end)
  1383. return observer:onError(message)
  1384. end
  1385. local function onCompleted()
  1386. util.tryWithObserver(observer, function()
  1387. _onCompleted()
  1388. end)
  1389. return observer:onCompleted()
  1390. end
  1391. return self:subscribe(onNext, onError, onCompleted)
  1392. end)
  1393. end
  1394. --- Returns an Observable that unpacks the tables produced by the original.
  1395. -- @returns {Observable}
  1396. function Observable:unpack()
  1397. return self:map(util.unpack)
  1398. end
  1399. --- Returns an Observable that takes any values produced by the original that consist of multiple
  1400. -- return values and produces each value individually.
  1401. -- @returns {Observable}
  1402. function Observable:unwrap()
  1403. return Observable.create(function(observer)
  1404. local function onNext(...)
  1405. local values = {...}
  1406. for i = 1, #values do
  1407. observer:onNext(values[i])
  1408. end
  1409. end
  1410. local function onError(message)
  1411. return observer:onError(message)
  1412. end
  1413. local function onCompleted()
  1414. return observer:onCompleted()
  1415. end
  1416. return self:subscribe(onNext, onError, onCompleted)
  1417. end)
  1418. end
  1419. --- Returns an Observable that produces a sliding window of the values produced by the original.
  1420. -- @arg {number} size - The size of the window. The returned observable will produce this number
  1421. -- of the most recent values as multiple arguments to onNext.
  1422. -- @returns {Observable}
  1423. function Observable:window(size)
  1424. if not size or type(size) ~= 'number' then
  1425. error('Expected a number')
  1426. end
  1427. return Observable.create(function(observer)
  1428. local window = {}
  1429. local function onNext(value)
  1430. table.insert(window, value)
  1431. if #window >= size then
  1432. observer:onNext(util.unpack(window))
  1433. table.remove(window, 1)
  1434. end
  1435. end
  1436. local function onError(message)
  1437. return observer:onError(message)
  1438. end
  1439. local function onCompleted()
  1440. return observer:onCompleted()
  1441. end
  1442. return self:subscribe(onNext, onError, onCompleted)
  1443. end)
  1444. end
  1445. --- Returns an Observable that produces values from the original along with the most recently
  1446. -- produced value from all other specified Observables. Note that only the first argument from each
  1447. -- source Observable is used.
  1448. -- @arg {Observable...} sources - The Observables to include the most recent values from.
  1449. -- @returns {Observable}
  1450. function Observable:with(...)
  1451. local sources = {...}
  1452. return Observable.create(function(observer)
  1453. local latest = setmetatable({}, {__len = util.constant(#sources)})
  1454. local subscriptions = {}
  1455. local function setLatest(i)
  1456. return function(value)
  1457. latest[i] = value
  1458. end
  1459. end
  1460. local function onNext(value)
  1461. return observer:onNext(value, util.unpack(latest))
  1462. end
  1463. local function onError(e)
  1464. return observer:onError(e)
  1465. end
  1466. local function onCompleted()
  1467. return observer:onCompleted()
  1468. end
  1469. for i = 1, #sources do
  1470. subscriptions[i] = sources[i]:subscribe(setLatest(i), util.noop, util.noop)
  1471. end
  1472. subscriptions[#sources + 1] = self:subscribe(onNext, onError, onCompleted)
  1473. return Subscription.create(function ()
  1474. for i = 1, #sources + 1 do
  1475. if subscriptions[i] then subscriptions[i]:unsubscribe() end
  1476. end
  1477. end)
  1478. end)
  1479. end
  1480. --- Returns an Observable that merges the values produced by the source Observables by grouping them
  1481. -- by their index. The first onNext event contains the first value of all of the sources, the
  1482. -- second onNext event contains the second value of all of the sources, and so on. onNext is called
  1483. -- a number of times equal to the number of values produced by the Observable that produces the
  1484. -- fewest number of values.
  1485. -- @arg {Observable...} sources - The Observables to zip.
  1486. -- @returns {Observable}
  1487. function Observable.zip(...)
  1488. local sources = util.pack(...)
  1489. local count = #sources
  1490. return Observable.create(function(observer)
  1491. local values = {}
  1492. local active = {}
  1493. local subscriptions = {}
  1494. for i = 1, count do
  1495. values[i] = {n = 0}
  1496. active[i] = true
  1497. end
  1498. local function onNext(i)
  1499. return function(value)
  1500. table.insert(values[i], value)
  1501. values[i].n = values[i].n + 1
  1502. local ready = true
  1503. for i = 1, count do
  1504. if values[i].n == 0 then
  1505. ready = false
  1506. break
  1507. end
  1508. end
  1509. if ready then
  1510. local payload = {}
  1511. for i = 1, count do
  1512. payload[i] = table.remove(values[i], 1)
  1513. values[i].n = values[i].n - 1
  1514. end
  1515. observer:onNext(util.unpack(payload))
  1516. end
  1517. end
  1518. end
  1519. local function onError(message)
  1520. return observer:onError(message)
  1521. end
  1522. local function onCompleted(i)
  1523. return function()
  1524. active[i] = nil
  1525. if not next(active) or values[i].n == 0 then
  1526. return observer:onCompleted()
  1527. end
  1528. end
  1529. end
  1530. for i = 1, count do
  1531. subscriptions[i] = sources[i]:subscribe(onNext(i), onError, onCompleted(i))
  1532. end
  1533. return Subscription.create(function()
  1534. for i = 1, count do
  1535. if subscriptions[i] then subscriptions[i]:unsubscribe() end
  1536. end
  1537. end)
  1538. end)
  1539. end
  1540. --- @class ImmediateScheduler
  1541. -- @description Schedules Observables by running all operations immediately.
  1542. local ImmediateScheduler = {}
  1543. ImmediateScheduler.__index = ImmediateScheduler
  1544. ImmediateScheduler.__tostring = util.constant('ImmediateScheduler')
  1545. --- Creates a new ImmediateScheduler.
  1546. -- @returns {ImmediateScheduler}
  1547. function ImmediateScheduler.create()
  1548. return setmetatable({}, ImmediateScheduler)
  1549. end
  1550. --- Schedules a function to be run on the scheduler. It is executed immediately.
  1551. -- @arg {function} action - The function to execute.
  1552. function ImmediateScheduler:schedule(action)
  1553. action()
  1554. end
  1555. --- @class CooperativeScheduler
  1556. -- @description Manages Observables using coroutines and a virtual clock that must be updated
  1557. -- manually.
  1558. local CooperativeScheduler = {}
  1559. CooperativeScheduler.__index = CooperativeScheduler
  1560. CooperativeScheduler.__tostring = util.constant('CooperativeScheduler')
  1561. --- Creates a new CooperativeScheduler.
  1562. -- @arg {number=0} currentTime - A time to start the scheduler at.
  1563. -- @returns {CooperativeScheduler}
  1564. function CooperativeScheduler.create(currentTime)
  1565. local self = {
  1566. tasks = {},
  1567. currentTime = currentTime or 0
  1568. }
  1569. return setmetatable(self, CooperativeScheduler)
  1570. end
  1571. --- Schedules a function to be run after an optional delay. Returns a subscription that will stop
  1572. -- the action from running.
  1573. -- @arg {function} action - The function to execute. Will be converted into a coroutine. The
  1574. -- coroutine may yield execution back to the scheduler with an optional
  1575. -- number, which will put it to sleep for a time period.
  1576. -- @arg {number=0} delay - Delay execution of the action by a virtual time period.
  1577. -- @returns {Subscription}
  1578. function CooperativeScheduler:schedule(action, delay)
  1579. local task = {
  1580. thread = coroutine.create(action),
  1581. due = self.currentTime + (delay or 0)
  1582. }
  1583. table.insert(self.tasks, task)
  1584. return Subscription.create(function()
  1585. return self:unschedule(task)
  1586. end)
  1587. end
  1588. function CooperativeScheduler:unschedule(task)
  1589. for i = 1, #self.tasks do
  1590. if self.tasks[i] == task then
  1591. table.remove(self.tasks, i)
  1592. end
  1593. end
  1594. end
  1595. --- Triggers an update of the CooperativeScheduler. The clock will be advanced and the scheduler
  1596. -- will run any coroutines that are due to be run.
  1597. -- @arg {number=0} delta - An amount of time to advance the clock by. It is common to pass in the
  1598. -- time in seconds or milliseconds elapsed since this function was last
  1599. -- called.
  1600. function CooperativeScheduler:update(delta)
  1601. self.currentTime = self.currentTime + (delta or 0)
  1602. local i = 1
  1603. while i <= #self.tasks do
  1604. local task = self.tasks[i]
  1605. if self.currentTime >= task.due then
  1606. local success, delay = coroutine.resume(task.thread)
  1607. if coroutine.status(task.thread) == 'dead' then
  1608. table.remove(self.tasks, i)
  1609. else
  1610. task.due = math.max(task.due + (delay or 0), self.currentTime)
  1611. i = i + 1
  1612. end
  1613. if not success then
  1614. error(delay)
  1615. end
  1616. else
  1617. i = i + 1
  1618. end
  1619. end
  1620. end
  1621. --- Returns whether or not the CooperativeScheduler's queue is empty.
  1622. function CooperativeScheduler:isEmpty()
  1623. return not next(self.tasks)
  1624. end
  1625. --- @class TimeoutScheduler
  1626. -- @description A scheduler that uses luvit's timer library to schedule events on an event loop.
  1627. local TimeoutScheduler = {}
  1628. TimeoutScheduler.__index = TimeoutScheduler
  1629. TimeoutScheduler.__tostring = util.constant('TimeoutScheduler')
  1630. --- Creates a new TimeoutScheduler.
  1631. -- @returns {TimeoutScheduler}
  1632. function TimeoutScheduler.create()
  1633. return setmetatable({}, TimeoutScheduler)
  1634. end
  1635. --- Schedules an action to run at a future point in time.
  1636. -- @arg {function} action - The action to run.
  1637. -- @arg {number=0} delay - The delay, in milliseconds.
  1638. -- @returns {Subscription}
  1639. function TimeoutScheduler:schedule(action, delay, ...)
  1640. local timer = require 'timer'
  1641. local subscription
  1642. local handle = timer.setTimeout(delay, action, ...)
  1643. return Subscription.create(function()
  1644. timer.clearTimeout(handle)
  1645. end)
  1646. end
  1647. --- @class Subject
  1648. -- @description Subjects function both as an Observer and as an Observable. Subjects inherit all
  1649. -- Observable functions, including subscribe. Values can also be pushed to the Subject, which will
  1650. -- be broadcasted to any subscribed Observers.
  1651. local Subject = setmetatable({}, Observable)
  1652. Subject.__index = Subject
  1653. Subject.__tostring = util.constant('Subject')
  1654. --- Creates a new Subject.
  1655. -- @returns {Subject}
  1656. function Subject.create()
  1657. local self = {
  1658. observers = {},
  1659. stopped = false
  1660. }
  1661. return setmetatable(self, Subject)
  1662. end
  1663. --- Creates a new Observer and attaches it to the Subject.
  1664. -- @arg {function|table} onNext|observer - A function called when the Subject produces a value or
  1665. -- an existing Observer to attach to the Subject.
  1666. -- @arg {function} onError - Called when the Subject terminates due to an error.
  1667. -- @arg {function} onCompleted - Called when the Subject completes normally.
  1668. function Subject:subscribe(onNext, onError, onCompleted)
  1669. local observer
  1670. if util.isa(onNext, Observer) then
  1671. observer = onNext
  1672. else
  1673. observer = Observer.create(onNext, onError, onCompleted)
  1674. end
  1675. table.insert(self.observers, observer)
  1676. return Subscription.create(function()
  1677. for i = 1, #self.observers do
  1678. if self.observers[i] == observer then
  1679. table.remove(self.observers, i)
  1680. return
  1681. end
  1682. end
  1683. end)
  1684. end
  1685. --- Pushes zero or more values to the Subject. They will be broadcasted to all Observers.
  1686. -- @arg {*...} values
  1687. function Subject:onNext(...)
  1688. if not self.stopped then
  1689. for i = #self.observers, 1, -1 do
  1690. self.observers[i]:onNext(...)
  1691. end
  1692. end
  1693. end
  1694. --- Signal to all Observers that an error has occurred.
  1695. -- @arg {string=} message - A string describing what went wrong.
  1696. function Subject:onError(message)
  1697. if not self.stopped then
  1698. for i = #self.observers, 1, -1 do
  1699. self.observers[i]:onError(message)
  1700. end
  1701. self.stopped = true
  1702. end
  1703. end
  1704. --- Signal to all Observers that the Subject will not produce any more values.
  1705. function Subject:onCompleted()
  1706. if not self.stopped then
  1707. for i = #self.observers, 1, -1 do
  1708. self.observers[i]:onCompleted()
  1709. end
  1710. self.stopped = true
  1711. end
  1712. end
  1713. Subject.__call = Subject.onNext
  1714. --- @class AsyncSubject
  1715. -- @description AsyncSubjects are subjects that produce either no values or a single value. If
  1716. -- multiple values are produced via onNext, only the last one is used. If onError is called, then
  1717. -- no value is produced and onError is called on any subscribed Observers. If an Observer
  1718. -- subscribes and the AsyncSubject has already terminated, the Observer will immediately receive the
  1719. -- value or the error.
  1720. local AsyncSubject = setmetatable({}, Observable)
  1721. AsyncSubject.__index = AsyncSubject
  1722. AsyncSubject.__tostring = util.constant('AsyncSubject')
  1723. --- Creates a new AsyncSubject.
  1724. -- @returns {AsyncSubject}
  1725. function AsyncSubject.create()
  1726. local self = {
  1727. observers = {},
  1728. stopped = false,
  1729. value = nil,
  1730. errorMessage = nil
  1731. }
  1732. return setmetatable(self, AsyncSubject)
  1733. end
  1734. --- Creates a new Observer and attaches it to the AsyncSubject.
  1735. -- @arg {function|table} onNext|observer - A function called when the AsyncSubject produces a value
  1736. -- or an existing Observer to attach to the AsyncSubject.
  1737. -- @arg {function} onError - Called when the AsyncSubject terminates due to an error.
  1738. -- @arg {function} onCompleted - Called when the AsyncSubject completes normally.
  1739. function AsyncSubject:subscribe(onNext, onError, onCompleted)
  1740. local observer
  1741. if util.isa(onNext, Observer) then
  1742. observer = onNext
  1743. else
  1744. observer = Observer.create(onNext, onError, onCompleted)
  1745. end
  1746. if self.value then
  1747. observer:onNext(util.unpack(self.value))
  1748. observer:onCompleted()
  1749. return
  1750. elseif self.errorMessage then
  1751. observer:onError(self.errorMessage)
  1752. return
  1753. end
  1754. table.insert(self.observers, observer)
  1755. return Subscription.create(function()
  1756. for i = 1, #self.observers do
  1757. if self.observers[i] == observer then
  1758. table.remove(self.observers, i)
  1759. return
  1760. end
  1761. end
  1762. end)
  1763. end
  1764. --- Pushes zero or more values to the AsyncSubject.
  1765. -- @arg {*...} values
  1766. function AsyncSubject:onNext(...)
  1767. if not self.stopped then
  1768. self.value = util.pack(...)
  1769. end
  1770. end
  1771. --- Signal to all Observers that an error has occurred.
  1772. -- @arg {string=} message - A string describing what went wrong.
  1773. function AsyncSubject:onError(message)
  1774. if not self.stopped then
  1775. self.errorMessage = message
  1776. for i = 1, #self.observers do
  1777. self.observers[i]:onError(self.errorMessage)
  1778. end
  1779. self.stopped = true
  1780. end
  1781. end
  1782. --- Signal to all Observers that the AsyncSubject will not produce any more values.
  1783. function AsyncSubject:onCompleted()
  1784. if not self.stopped then
  1785. for i = 1, #self.observers do
  1786. if self.value then
  1787. self.observers[i]:onNext(util.unpack(self.value))
  1788. end
  1789. self.observers[i]:onCompleted()
  1790. end
  1791. self.stopped = true
  1792. end
  1793. end
  1794. AsyncSubject.__call = AsyncSubject.onNext
  1795. --- @class BehaviorSubject
  1796. -- @description A Subject that tracks its current value. Provides an accessor to retrieve the most
  1797. -- recent pushed value, and all subscribers immediately receive the latest value.
  1798. local BehaviorSubject = setmetatable({}, Subject)
  1799. BehaviorSubject.__index = BehaviorSubject
  1800. BehaviorSubject.__tostring = util.constant('BehaviorSubject')
  1801. --- Creates a new BehaviorSubject.
  1802. -- @arg {*...} value - The initial values.
  1803. -- @returns {BehaviorSubject}
  1804. function BehaviorSubject.create(...)
  1805. local self = {
  1806. observers = {},
  1807. stopped = false
  1808. }
  1809. if select('#', ...) > 0 then
  1810. self.value = util.pack(...)
  1811. end
  1812. return setmetatable(self, BehaviorSubject)
  1813. end
  1814. --- Creates a new Observer and attaches it to the BehaviorSubject. Immediately broadcasts the most
  1815. -- recent value to the Observer.
  1816. -- @arg {function} onNext - Called when the BehaviorSubject produces a value.
  1817. -- @arg {function} onError - Called when the BehaviorSubject terminates due to an error.
  1818. -- @arg {function} onCompleted - Called when the BehaviorSubject completes normally.
  1819. function BehaviorSubject:subscribe(onNext, onError, onCompleted)
  1820. local observer
  1821. if util.isa(onNext, Observer) then
  1822. observer = onNext
  1823. else
  1824. observer = Observer.create(onNext, onError, onCompleted)
  1825. end
  1826. local subscription = Subject.subscribe(self, observer)
  1827. if self.value then
  1828. observer:onNext(util.unpack(self.value))
  1829. end
  1830. return subscription
  1831. end
  1832. --- Pushes zero or more values to the BehaviorSubject. They will be broadcasted to all Observers.
  1833. -- @arg {*...} values
  1834. function BehaviorSubject:onNext(...)
  1835. self.value = util.pack(...)
  1836. return Subject.onNext(self, ...)
  1837. end
  1838. --- Returns the last value emitted by the BehaviorSubject, or the initial value passed to the
  1839. -- constructor if nothing has been emitted yet.
  1840. -- @returns {*...}
  1841. function BehaviorSubject:getValue()
  1842. if self.value ~= nil then
  1843. return util.unpack(self.value)
  1844. end
  1845. end
  1846. BehaviorSubject.__call = BehaviorSubject.onNext
  1847. --- @class ReplaySubject
  1848. -- @description A Subject that provides new Subscribers with some or all of the most recently
  1849. -- produced values upon subscription.
  1850. local ReplaySubject = setmetatable({}, Subject)
  1851. ReplaySubject.__index = ReplaySubject
  1852. ReplaySubject.__tostring = util.constant('ReplaySubject')
  1853. --- Creates a new ReplaySubject.
  1854. -- @arg {number=} bufferSize - The number of values to send to new subscribers. If nil, an infinite
  1855. -- buffer is used (note that this could lead to memory issues).
  1856. -- @returns {ReplaySubject}
  1857. function ReplaySubject.create(n)
  1858. local self = {
  1859. observers = {},
  1860. stopped = false,
  1861. buffer = {},
  1862. bufferSize = n
  1863. }
  1864. return setmetatable(self, ReplaySubject)
  1865. end
  1866. --- Creates a new Observer and attaches it to the ReplaySubject. Immediately broadcasts the most
  1867. -- contents of the buffer to the Observer.
  1868. -- @arg {function} onNext - Called when the ReplaySubject produces a value.
  1869. -- @arg {function} onError - Called when the ReplaySubject terminates due to an error.
  1870. -- @arg {function} onCompleted - Called when the ReplaySubject completes normally.
  1871. function ReplaySubject:subscribe(onNext, onError, onCompleted)
  1872. local observer
  1873. if util.isa(onNext, Observer) then
  1874. observer = onNext
  1875. else
  1876. observer = Observer.create(onNext, onError, onCompleted)
  1877. end
  1878. local subscription = Subject.subscribe(self, observer)
  1879. for i = 1, #self.buffer do
  1880. observer:onNext(util.unpack(self.buffer[i]))
  1881. end
  1882. return subscription
  1883. end
  1884. --- Pushes zero or more values to the ReplaySubject. They will be broadcasted to all Observers.
  1885. -- @arg {*...} values
  1886. function ReplaySubject:onNext(...)
  1887. table.insert(self.buffer, util.pack(...))
  1888. if self.bufferSize and #self.buffer > self.bufferSize then
  1889. table.remove(self.buffer, 1)
  1890. end
  1891. return Subject.onNext(self, ...)
  1892. end
  1893. ReplaySubject.__call = ReplaySubject.onNext
  1894. Observable.wrap = Observable.buffer
  1895. Observable['repeat'] = Observable.replicate
  1896. return {
  1897. util = util,
  1898. Subscription = Subscription,
  1899. Observer = Observer,
  1900. Observable = Observable,
  1901. ImmediateScheduler = ImmediateScheduler,
  1902. CooperativeScheduler = CooperativeScheduler,
  1903. TimeoutScheduler = TimeoutScheduler,
  1904. Subject = Subject,
  1905. AsyncSubject = AsyncSubject,
  1906. BehaviorSubject = BehaviorSubject,
  1907. ReplaySubject = ReplaySubject
  1908. }