cleanup + experimenting...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-11-03 16:32:56 +03:00
parent 52c7aed234
commit 836f79ec88
2 changed files with 98 additions and 22 deletions

View File

@ -16,36 +16,27 @@ var CooperativePromise =
module.CooperativePromise =
Promise.cooperative =
object.Constructor('CooperativePromise', Promise, {
// XXX do we actually need this???
__promise: null,
get isSet(){
return !this.__resolve && !this.__reject },
set: function(promise){
if(this.__promise === null){
// setting a non-promise...
if(!this.isSet){
// non-promise...
if(promise.catch == null && promise.then == null){
Object.defineProperty(this, '__promise', {
value: false,
enumerable: false,
})
this.__resolve(promise)
// setting a promise...
// promise...
} else {
Object.defineProperty(this, '__promise', {
value: promise,
enumerable: false,
})
// connect the base and the set promises...
promise.catch(this.__reject.bind(this))
promise.then(this.__resolve.bind(this)) }
// cleanup...
delete this.__resolve
delete this.__reject
} else {
throw new Error('Setting a cooperative promise twice') } },
return this }
// err: already set...
throw new Error('CooperativePromise.set(..): can not set twice') },
__new__: function(_, func){
var methods = {}
@ -53,10 +44,23 @@ object.Constructor('CooperativePromise', Promise, {
function(resolve, reject){
methods.resolve = resolve
methods.reject = reject
func
&& func.call(this, ...arguments)
} ], CooperativePromise)
if(func){
return func.call(this, ...arguments) } } ],
CooperativePromise)
/*/ if we are fulfilled before being set, we are set :)
// XXX for some reason this breaks either .__new__(..) if called
// outside of setTimeout(..) or hangs the promise on resolve
// if inside...
setTimeout(function(){
obj.finally(function(){
delete obj.__resolve
delete obj.__reject
}) }, 0)
//*/
// XXX revise...
// XXX can we avoid creating these???
// ...one way to do this is to create a local .set(..)
// that whould reference them through closure...
Object.defineProperties(obj, {
__resolve: {
value: methods.resolve,
@ -69,6 +73,78 @@ object.Constructor('CooperativePromise', Promise, {
configurable: true,
},
})
return obj },
/*
__init__: function(){
// if we are fulfilled before being set, we are set :)
this.finally(function(){
delete this.__resolve
delete this.__reject
}.bind(this)) },
//*/
})
// XXX EXPERIMENTAL -- this hides internal state (.__resolve(..) / .__reject(..))
// ...not sure if we actually need to do this...
var _CooperativePromise =
module._CooperativePromise =
//Promise.cooperative =
object.Constructor('_CooperativePromise', Promise, {
get isSet(){
return this.set() },
//set: function(){},
__new__: function(_, func){
// internal state...
// NOTE: when promise is set this will be set to false...
var methods = {}
// instance...
var obj = Reflect.construct(_CooperativePromise.__proto__, [
function(resolve, reject){
methods.resolve = resolve
methods.reject = reject
// NOTE: this is here mostly for promise compatibilty...
if(func){
// XXX this can resolve/reject a promise -- need to
// keep things consistent...
return func.call(this, ...arguments) } } ],
_CooperativePromise)
// if we are fulfilled before being set, we are set :)
// XXX for some reason this breaks either .__new__(..) if called
// outside of setTimeout(..) or hangs the promise on resolve
// if inside...
setTimeout(function(){
obj.finally(function(){
methods = false }) }, 0)
// create instance .set(..)
Object.defineProperty(obj, 'set', {
value: function(promise){
// get state...
if(arguments.length == 0){
return !!methods }
if(methods){
// non-promise...
if(promise.catch == null && promise.then == null){
methods.resolve(promise)
// promise...
} else {
// connect the base and the set promises...
promise.catch(methods.reject.bind(this))
promise.then(methods.resolve.bind(this)) }
methods = false
return this }
// err: already set...
throw new Error('CooperativePromise.set(..): can not set twice') },
enumerable: false,
configurable: true,
})
return obj },
})

View File

@ -1,6 +1,6 @@
{
"name": "ig-types",
"version": "3.0.2",
"version": "3.0.3",
"description": "Generic JavaScript types and type extensions...",
"main": "main.js",
"scripts": {