Comparing version 0.0.14 to 0.1.0
@@ -25,1 +25,11 @@ export interface IDefer<T> { | ||
export declare function makeBroadcastStream<T>(): IBroadcastStream<T>; | ||
export interface ISingleStream<T> extends AsyncIterable<T> { | ||
next(value: T): void; | ||
throw(error: unknown): void; | ||
done(): void; | ||
} | ||
export declare function makeSingleStream<T>(): ISingleStream<T>; |
160
index.js
@@ -1,11 +0,14 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.makeBroadcastStream = void 0; | ||
'use strict' | ||
Object.defineProperty(exports, '__esModule', {value: true}) | ||
exports.default = makeDefer | ||
exports.makeBroadcastStream = makeBroadcastStream | ||
exports.makeSingleStream = makeSingleStream | ||
function makeDefer() { | ||
let resolve = undefined; | ||
let reject = undefined; | ||
let resolve = undefined | ||
let reject = undefined | ||
const promise = new Promise((rs, rj) => { | ||
resolve = rs; | ||
reject = rj; | ||
}); | ||
resolve = rs | ||
reject = rj | ||
}) | ||
return { | ||
@@ -15,9 +18,9 @@ resolve, | ||
promise | ||
}; | ||
} | ||
} | ||
exports.default = makeDefer; | ||
function makeBroadcastStream() { | ||
const listeners = []; | ||
let done = false; | ||
let defer = makeDefer(); | ||
const listeners = [] | ||
let done = false | ||
let defer = makeDefer() | ||
return { | ||
@@ -27,59 +30,124 @@ [Symbol.asyncIterator]() { | ||
async next() { | ||
const value = await defer.promise; | ||
defer = makeDefer(); | ||
return value; | ||
if (done) | ||
return {value: undefined, done: true} | ||
const value = await defer.promise | ||
defer = makeDefer() | ||
return value | ||
}, | ||
async return(value) { | ||
return { value: undefined, done: true }; | ||
return {value: undefined, done: true} | ||
}, | ||
async throw(e) { | ||
return { value: undefined, done: true }; | ||
return {value: undefined, done: true} | ||
} | ||
}; | ||
} | ||
}, | ||
listen(onNext, { onError, onDone } = {}) { | ||
if (done) | ||
throw new Error('Cannot listen after done'); | ||
const listener = { onNext, onError, onDone }; | ||
listeners.push(listener); | ||
listen(onNext, {onError, onDone} = {}) { | ||
if (done) { | ||
onDone?.() | ||
return () => { | ||
} | ||
} | ||
const listener = {onNext, onError, onDone} | ||
listeners.push(listener) | ||
return function removeListener() { | ||
const idx = listeners.lastIndexOf(listener); | ||
const idx = listeners.lastIndexOf(listener) | ||
if (idx >= 0) | ||
listeners.splice(idx, 1); | ||
}; | ||
listeners.splice(idx, 1) | ||
} | ||
}, | ||
next(value) { | ||
if (done) | ||
throw new Error('Cannot next after done'); | ||
defer.resolve({ value, done: false }); | ||
for (const { onNext } of listeners) | ||
return | ||
defer.resolve({value, done: false}) | ||
for (const {onNext} of listeners) | ||
try { | ||
onNext(value); | ||
onNext(value) | ||
} catch { | ||
} | ||
catch { } | ||
}, | ||
throw(error) { | ||
if (done) | ||
throw new Error('Cannot throw after done'); | ||
done = true; | ||
defer.reject(error); | ||
for (const { onError } of listeners) | ||
return | ||
done = true | ||
defer.reject(error) | ||
for (const {onError} of listeners) | ||
try { | ||
onError?.(error); | ||
onError?.(error) | ||
} catch { | ||
} | ||
catch { } | ||
}, | ||
done() { | ||
if (done) | ||
throw new Error('Cannot done after done'); | ||
done = true; | ||
defer.resolve({ value: undefined, done: true }); | ||
for (const { onDone } of listeners) | ||
return | ||
done = true | ||
defer.resolve({value: undefined, done: true}) | ||
for (const {onDone} of listeners) | ||
try { | ||
onDone?.(); | ||
onDone?.() | ||
} catch { | ||
} | ||
catch { } | ||
}, | ||
}; | ||
} | ||
} | ||
exports.makeBroadcastStream = makeBroadcastStream; | ||
function makeSingleStream() { | ||
// at least one of chunk or defers is empty, all the time | ||
const chunk = [] | ||
const defers = [] | ||
let done = false | ||
let error | ||
return { | ||
[Symbol.asyncIterator]() { | ||
return { | ||
async next() { | ||
if (chunk.length) | ||
return chunk.shift() | ||
if (done) { | ||
if (error) | ||
throw error | ||
return {value: undefined, done: true} | ||
} | ||
// chunk must currently be empty, it is safe to make defers non-empty | ||
const defer = makeDefer() | ||
defers.push(defer) | ||
return defer.promise | ||
}, | ||
async return(value) { | ||
return {value: undefined, done: true} | ||
}, | ||
async throw(e) { | ||
return {value: undefined, done: true} | ||
} | ||
} | ||
}, | ||
next(value) { | ||
if (done) | ||
return | ||
if (defers.length) { | ||
const defer = defers.shift() | ||
defer.resolve({value, done: false}) | ||
return | ||
} | ||
// defers must currently be empty, it is safe to make chunk non-empty | ||
chunk.push({value, done: false}) | ||
}, | ||
throw(err) { | ||
if (done) | ||
return | ||
done = true | ||
error = err | ||
for (const defer of defers) | ||
defer.reject(err) | ||
defers.length = 0 | ||
}, | ||
done() { | ||
if (done) | ||
return | ||
done = true | ||
for (const defer of defers) | ||
defer.resolve({value: undefined, done: true}) | ||
defers.length = 0 | ||
}, | ||
} | ||
} |
{ | ||
"name": "jdefer", | ||
"version": "0.0.14", | ||
"version": "0.1.0", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/tranvansang/jdefer", |
@@ -13,2 +13,4 @@ # Javascript promise defer library | ||
In 2024: recommended using [`Promise.withResolvers()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers). | ||
```typescript | ||
@@ -15,0 +17,0 @@ import makeDefer from 'jdefer' |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8727
313
68