mirror of
https://github.com/flynx/stoppable.js.git
synced 2025-10-29 02:40:08 +00:00
initial code migrated from object.js...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
156e4b1704
commit
777bc53dd0
19
package.json
Normal file
19
package.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "ig-stoppable",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Utility library implementing tooling to make stoppable functions...",
|
||||||
|
"main": "stoppable.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/flynx/stoppable.js.git"
|
||||||
|
},
|
||||||
|
"author": "Alex A. Naanou",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/flynx/stoppable.js/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/flynx/stoppable.js#readme"
|
||||||
|
}
|
||||||
144
stoppable.js
Normal file
144
stoppable.js
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
*
|
||||||
|
* stoppable.js
|
||||||
|
*
|
||||||
|
* Utility library implementing tooling to make stoppable functions...
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Repo and docs:
|
||||||
|
* https://github.com/flynx/stoppable.js
|
||||||
|
*
|
||||||
|
*
|
||||||
|
***********************************************/ /* c8 ignore next 2 */
|
||||||
|
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
||||||
|
(function(require){ var module={} // make module AMD/node compatible...
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// helpers...
|
||||||
|
|
||||||
|
var Generator =
|
||||||
|
(function*(){}).constructor
|
||||||
|
|
||||||
|
var AsyncGenerator =
|
||||||
|
(async function*(){}).constructor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
var STOP =
|
||||||
|
module.STOP =
|
||||||
|
function(value){
|
||||||
|
return {
|
||||||
|
__proto__: STOP.prototype,
|
||||||
|
doc: 'stop iteration.',
|
||||||
|
value,
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Wrap a callable in a STOP handler
|
||||||
|
//
|
||||||
|
// stoppable(func)
|
||||||
|
// -> func
|
||||||
|
//
|
||||||
|
// stoppable(gen)
|
||||||
|
// -> gen
|
||||||
|
//
|
||||||
|
// stoppable(asyncgen)
|
||||||
|
// -> asyncgen
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The client callable can be one of:
|
||||||
|
// - function
|
||||||
|
// - generator
|
||||||
|
// - async generator
|
||||||
|
//
|
||||||
|
// The returned callable will be of the same type as the input callable.
|
||||||
|
//
|
||||||
|
// The wrapper handles STOP slightly differently if the client is a
|
||||||
|
// function or if it is a generator / async generator:
|
||||||
|
// - function
|
||||||
|
// STOP returned / thrown
|
||||||
|
// -> return undefined
|
||||||
|
// STOP(value) returned / thrown
|
||||||
|
// -> return value
|
||||||
|
// - generator / async generator
|
||||||
|
// STOP yielded / thrown
|
||||||
|
// -> iteration stops
|
||||||
|
// STOP(value) yielded / thrown
|
||||||
|
// -> value yielded and iteration stops
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// NOTE: this repeats the same code at lest twice, not sure yet how to avoid
|
||||||
|
// this...
|
||||||
|
var stoppable =
|
||||||
|
module.stoppable =
|
||||||
|
function(func){
|
||||||
|
return Object.assign(
|
||||||
|
func instanceof Generator ?
|
||||||
|
// NOTE: the only difference between Generator/AsyncGenerator
|
||||||
|
// versions of this is the async keyword -- keep them
|
||||||
|
// in sync...
|
||||||
|
function*(){
|
||||||
|
try{
|
||||||
|
for(var res of func.call(this, ...arguments)){
|
||||||
|
if(res === module.STOP){
|
||||||
|
return }
|
||||||
|
if(res instanceof module.STOP){
|
||||||
|
yield res.value
|
||||||
|
return }
|
||||||
|
yield res }
|
||||||
|
} catch(err){
|
||||||
|
if(err === module.STOP){
|
||||||
|
return
|
||||||
|
} else if(err instanceof module.STOP){
|
||||||
|
yield err.value
|
||||||
|
return }
|
||||||
|
throw err } }
|
||||||
|
: func instanceof AsyncGenerator ?
|
||||||
|
// NOTE: the only difference between Generator/AsyncGenerator
|
||||||
|
// versions of this is the async keyword -- keep them
|
||||||
|
// in sync...
|
||||||
|
async function*(){
|
||||||
|
try{
|
||||||
|
for(var res of func.call(this, ...arguments)){
|
||||||
|
if(res === module.STOP){
|
||||||
|
return }
|
||||||
|
if(res instanceof module.STOP){
|
||||||
|
yield res.value
|
||||||
|
return }
|
||||||
|
yield res }
|
||||||
|
} catch(err){
|
||||||
|
if(err === module.STOP){
|
||||||
|
return
|
||||||
|
} else if(err instanceof module.STOP){
|
||||||
|
yield err.value
|
||||||
|
return }
|
||||||
|
throw err } }
|
||||||
|
: function(){
|
||||||
|
try{
|
||||||
|
var res = func.call(this, ...arguments)
|
||||||
|
// NOTE: this is here for uniformity...
|
||||||
|
if(res === module.STOP){
|
||||||
|
return }
|
||||||
|
if(res instanceof module.STOP){
|
||||||
|
return res.value }
|
||||||
|
return res
|
||||||
|
} catch(err){
|
||||||
|
if(err === module.STOP){
|
||||||
|
return
|
||||||
|
} else if(err instanceof module.STOP){
|
||||||
|
return err.value }
|
||||||
|
throw err } },
|
||||||
|
{ toString: function(){
|
||||||
|
return func.toString() }, }) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* vim:set ts=4 sw=4 nowrap : */ return module })
|
||||||
Loading…
x
Reference in New Issue
Block a user