Comparing version 6.3.2 to 6.3.3-canary-c160e1d
# wonka | ||
## 6.3.3-canary-c160e1d | ||
### Patch Changes | ||
- Improve compatibility of `fromAsyncIterable` and `toAsyncIterable`. The `toAsyncIterable` will now output an object that's both an `AsyncIterator` and an `AsyncIterable`. Both helpers will now use a polyfill for `Symbol.asyncIterator` to improve compatibility with the Hermes engine and Babel transpilation | ||
Submitted by [@kitten](https://github.com/kitten) (See [#165](https://github.com/0no-co/wonka/pull/165)) | ||
## 6.3.2 | ||
@@ -4,0 +11,0 @@ |
@@ -204,2 +204,7 @@ /** | ||
/** Async Iterable/Iterator after having converted a {@link Source}. | ||
* @see {@link toAsyncIterable} for a helper that creates this structure. | ||
*/ | ||
interface SourceIterable<T> extends AsyncIterator<T>, AsyncIterable<T> {} | ||
/** Helper creating a Source from a factory function when it's subscribed to. | ||
@@ -245,3 +250,3 @@ * @param produce - A factory function returning a {@link Source}. | ||
*/ | ||
declare function fromAsyncIterable<T>(iterable: AsyncIterable<T>): Source<T>; | ||
declare function fromAsyncIterable<T>(iterable: AsyncIterable<T> | AsyncIterator<T>): Source<T>; | ||
/** Converts an Iterable to a Source that pulls and issues values from it as requested. | ||
@@ -1141,3 +1146,3 @@ * @see {@link fromAsyncIterable | `fromAsyncIterable`} for the AsyncIterable version of this helper. | ||
*/ | ||
declare const toAsyncIterable: <T>(source: Source<T>) => AsyncIterable<T>; | ||
declare const toAsyncIterable: <T>(source: Source<T>) => SourceIterable<T>; | ||
/** Subscribes to a given source and collects all synchronous values into an array. | ||
@@ -1250,7 +1255,2 @@ * @param source - A {@link Source}. | ||
declare global { | ||
interface SymbolConstructor { | ||
readonly observable: symbol; | ||
} | ||
} | ||
/** A definition of the ES Observable Subscription type that is returned by | ||
@@ -1257,0 +1257,0 @@ * {@link Observable.subscribe} |
@@ -23,2 +23,6 @@ Object.defineProperty(exports, "__esModule", { | ||
var asyncIteratorSymbol = () => "function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"; | ||
var observableSymbol = () => "function" == typeof Symbol && Symbol.observable || "@@observable"; | ||
var identity = e => e; | ||
@@ -328,3 +332,3 @@ | ||
return r => { | ||
var t = e[Symbol.asyncIterator](); | ||
var t = e[asyncIteratorSymbol()] && e[asyncIteratorSymbol()]() || e; | ||
var i = !1; | ||
@@ -537,4 +541,2 @@ var s = !1; | ||
var observableSymbol = () => Symbol.observable || "@@observable"; | ||
exports.buffer = function buffer(r) { | ||
@@ -1262,47 +1264,58 @@ return t => i => { | ||
exports.toAsyncIterable = r => ({ | ||
[Symbol.asyncIterator]() { | ||
var i = []; | ||
var s = !1; | ||
var a = e; | ||
var f; | ||
r((e => { | ||
if (s) {} else if (0 === e) { | ||
if (f) { | ||
f = f(t); | ||
} | ||
s = !0; | ||
} else if (0 === e.tag) { | ||
(a = e[0])(0); | ||
} else if (f) { | ||
f = f({ | ||
value: e[0], | ||
done: !1 | ||
}); | ||
} else { | ||
i.push(e[0]); | ||
exports.toAsyncIterable = r => { | ||
var i = []; | ||
var s = !1; | ||
var a = !1; | ||
var f = !1; | ||
var n = e; | ||
var l; | ||
return { | ||
async next() { | ||
if (!a) { | ||
a = !0; | ||
r((e => { | ||
if (s) {} else if (0 === e) { | ||
if (l) { | ||
l = l(t); | ||
} | ||
s = !0; | ||
} else if (0 === e.tag) { | ||
f = !0; | ||
(n = e[0])(0); | ||
} else { | ||
f = !1; | ||
if (l) { | ||
l = l({ | ||
value: e[0], | ||
done: !1 | ||
}); | ||
} else { | ||
i.push(e[0]); | ||
} | ||
} | ||
})); | ||
} | ||
})); | ||
return { | ||
async next() { | ||
if (s && !i.length) { | ||
return t; | ||
} else if (!s && i.length <= 1) { | ||
a(0); | ||
} | ||
return i.length ? { | ||
value: i.shift(), | ||
done: !1 | ||
} : new Promise((e => f = e)); | ||
}, | ||
async return() { | ||
if (!s) { | ||
f = a(1); | ||
} | ||
s = !0; | ||
if (s && !i.length) { | ||
return t; | ||
} else if (!s && !f && i.length <= 1) { | ||
f = !0; | ||
n(0); | ||
} | ||
}; | ||
} | ||
}); | ||
return i.length ? { | ||
value: i.shift(), | ||
done: !1 | ||
} : new Promise((e => l = e)); | ||
}, | ||
async return() { | ||
if (!s) { | ||
l = n(1); | ||
} | ||
s = !0; | ||
return t; | ||
}, | ||
[asyncIteratorSymbol()]() { | ||
return this; | ||
} | ||
}; | ||
}; | ||
@@ -1309,0 +1322,0 @@ exports.toCallbag = function toCallbag(e) { |
{ | ||
"name": "wonka", | ||
"description": "A tiny but capable push & pull stream library for TypeScript and Flow", | ||
"version": "6.3.2", | ||
"version": "6.3.3-canary-c160e1d", | ||
"author": "0no.co <hi@0no.co>", | ||
@@ -12,5 +12,5 @@ "source": "./src/index.ts", | ||
".": { | ||
"types": "./dist/wonka.d.ts", | ||
"import": "./dist/wonka.mjs", | ||
"require": "./dist/wonka.js", | ||
"types": "./dist/wonka.d.ts", | ||
"source": "./src/index.ts" | ||
@@ -68,4 +68,4 @@ }, | ||
"devDependencies": { | ||
"@changesets/cli": "^2.26.0", | ||
"@changesets/get-github-info": "0.5.0", | ||
"@changesets/cli": "^2.26.2", | ||
"@changesets/get-github-info": "0.5.2", | ||
"@rollup/plugin-buble": "^1.0.1", | ||
@@ -72,0 +72,0 @@ "@rollup/plugin-commonjs": "^23.0.3", |
@@ -247,15 +247,15 @@ import { describe, it, expect, vi } from 'vitest'; | ||
const asyncIterator = sinks.toAsyncIterable(source)[Symbol.asyncIterator](); | ||
const next$ = asyncIterator.next(); | ||
sink!(push(0)); | ||
expect(await next$).toEqual({ value: 0, done: false }); | ||
expect(pulls).toBe(1); | ||
sink!(push(0)); | ||
expect(await asyncIterator.next()).toEqual({ value: 0, done: false }); | ||
expect(pulls).toBe(2); | ||
sink!(push(1)); | ||
expect(await asyncIterator.next()).toEqual({ value: 1, done: false }); | ||
expect(pulls).toBe(3); | ||
expect(pulls).toBe(2); | ||
sink!(SignalKind.End); | ||
expect(await asyncIterator.next()).toEqual({ done: true }); | ||
expect(pulls).toBe(3); | ||
expect(pulls).toBe(2); | ||
}); | ||
@@ -277,2 +277,3 @@ | ||
const asyncIterator = sinks.toAsyncIterable(source)[Symbol.asyncIterator](); | ||
const next$ = asyncIterator.next(); | ||
@@ -284,3 +285,3 @@ sink!(push(0)); | ||
expect(pulls).toBe(1); | ||
expect(await asyncIterator.next()).toEqual({ value: 0, done: false }); | ||
expect(await next$).toEqual({ value: 0, done: false }); | ||
expect(await asyncIterator.next()).toEqual({ value: 1, done: false }); | ||
@@ -304,2 +305,3 @@ expect(await asyncIterator.next()).toEqual({ done: true }); | ||
const asyncIterator = sinks.toAsyncIterable(source)[Symbol.asyncIterator](); | ||
asyncIterator.next(); | ||
expect(pulls).toBe(1); | ||
@@ -337,5 +339,6 @@ | ||
const asyncIterator = sinks.toAsyncIterable(source)[Symbol.asyncIterator](); | ||
const next$ = asyncIterator.next(); | ||
sink!(push(0)); | ||
expect(await asyncIterator.next()).toEqual({ value: 0, done: false }); | ||
expect(await next$).toEqual({ value: 0, done: false }); | ||
expect(await asyncIterator.return!()).toEqual({ done: true }); | ||
@@ -342,0 +345,0 @@ |
import { TalkbackFn, TeardownFn, Start, Push, SignalKind } from './types'; | ||
declare global { | ||
interface SymbolConstructor { | ||
readonly observable: symbol; | ||
} | ||
} | ||
/** Placeholder {@link TeardownFn | teardown functions} that's a no-op. | ||
@@ -42,1 +48,22 @@ * @see {@link TeardownFn} for the definition and usage of teardowns. | ||
} | ||
/** Returns the well-known symbol specifying the default AsyncIterator. | ||
* @internal | ||
*/ | ||
export const asyncIteratorSymbol = (): typeof Symbol.asyncIterator => | ||
(typeof Symbol === 'function' && Symbol.asyncIterator) || ('@@asyncIterator' as any); | ||
/** Returns the well-known symbol specifying the default ES Observable. | ||
* @privateRemarks | ||
* This symbol is used to mark an object as a default ES Observable. By the specification, an object | ||
* that abides by the default Observable implementation must carry a method set to this well-known | ||
* symbol that returns the Observable implementation. It's common for this object to be an | ||
* Observable itself and return itself on this method. | ||
* | ||
* @see {@link https://github.com/0no-co/wonka/issues/122} for notes on the intercompatibility | ||
* between Observable implementations. | ||
* | ||
* @internal | ||
*/ | ||
export const observableSymbol = (): typeof Symbol.observable => | ||
(typeof Symbol === 'function' && Symbol.observable) || ('@@observable' as any); |
import { Source, SignalKind, TalkbackKind } from './types'; | ||
import { push, start, talkbackPlaceholder } from './helpers'; | ||
import { push, start, talkbackPlaceholder, observableSymbol } from './helpers'; | ||
declare global { | ||
interface SymbolConstructor { | ||
readonly observable: symbol; | ||
} | ||
} | ||
/** A definition of the ES Observable Subscription type that is returned by | ||
@@ -121,17 +115,2 @@ * {@link Observable.subscribe} | ||
/** Returns the well-known symbol specifying the default ES Observable. | ||
* @privateRemarks | ||
* This symbol is used to mark an object as a default ES Observable. By the specification, an object | ||
* that abides by the default Observable implementation must carry a method set to this well-known | ||
* symbol that returns the Observable implementation. It's common for this object to be an | ||
* Observable itself and return itself on this method. | ||
* | ||
* @see {@link https://github.com/0no-co/wonka/issues/122} for notes on the intercompatibility | ||
* between Observable implementations. | ||
* | ||
* @internal | ||
*/ | ||
const observableSymbol = (): typeof Symbol.observable => | ||
Symbol.observable || ('@@observable' as any); | ||
/** Converts an ES Observable to a {@link Source}. | ||
@@ -138,0 +117,0 @@ * @param input - The {@link ObservableLike} object that will be converted. |
@@ -1,3 +0,3 @@ | ||
import { Source, Subscription, TalkbackKind, SignalKind } from './types'; | ||
import { talkbackPlaceholder } from './helpers'; | ||
import { Source, Subscription, TalkbackKind, SignalKind, SourceIterable } from './types'; | ||
import { talkbackPlaceholder, asyncIteratorSymbol } from './helpers'; | ||
@@ -127,46 +127,57 @@ /** Creates a subscription to a given source and invokes a `subscriber` callback for each value. | ||
*/ | ||
export const toAsyncIterable = <T>(source: Source<T>): AsyncIterable<T> => ({ | ||
[Symbol.asyncIterator](): AsyncIterator<T> { | ||
const buffer: T[] = []; | ||
export const toAsyncIterable = <T>(source: Source<T>): SourceIterable<T> => { | ||
const buffer: T[] = []; | ||
let ended = false; | ||
let talkback = talkbackPlaceholder; | ||
let next: ((value: IteratorResult<T>) => void) | void; | ||
let ended = false; | ||
let started = false; | ||
let pulled = false; | ||
let talkback = talkbackPlaceholder; | ||
let next: ((value: IteratorResult<T>) => void) | void; | ||
source(signal => { | ||
if (ended) { | ||
/*noop*/ | ||
} else if (signal === SignalKind.End) { | ||
if (next) next = next(doneResult); | ||
ended = true; | ||
} else if (signal.tag === SignalKind.Start) { | ||
(talkback = signal[0])(TalkbackKind.Pull); | ||
} else if (next) { | ||
next = next({ value: signal[0], done: false }); | ||
} else { | ||
buffer.push(signal[0]); | ||
return { | ||
async next(): Promise<IteratorResult<T>> { | ||
if (!started) { | ||
started = true; | ||
source(signal => { | ||
if (ended) { | ||
/*noop*/ | ||
} else if (signal === SignalKind.End) { | ||
if (next) next = next(doneResult); | ||
ended = true; | ||
} else if (signal.tag === SignalKind.Start) { | ||
pulled = true; | ||
(talkback = signal[0])(TalkbackKind.Pull); | ||
} else { | ||
pulled = false; | ||
if (next) { | ||
next = next({ value: signal[0], done: false }); | ||
} else { | ||
buffer.push(signal[0]); | ||
} | ||
} | ||
}); | ||
} | ||
}); | ||
return { | ||
async next(): Promise<IteratorResult<T>> { | ||
if (ended && !buffer.length) { | ||
return doneResult; | ||
} else if (!ended && buffer.length <= 1) { | ||
talkback(TalkbackKind.Pull); | ||
} | ||
return buffer.length | ||
? { value: buffer.shift()!, done: false } | ||
: new Promise(resolve => (next = resolve)); | ||
}, | ||
async return(): Promise<IteratorReturnResult<void>> { | ||
if (!ended) next = talkback(TalkbackKind.Close); | ||
ended = true; | ||
if (ended && !buffer.length) { | ||
return doneResult; | ||
}, | ||
}; | ||
}, | ||
}); | ||
} else if (!ended && !pulled && buffer.length <= 1) { | ||
pulled = true; | ||
talkback(TalkbackKind.Pull); | ||
} | ||
return buffer.length | ||
? { value: buffer.shift()!, done: false } | ||
: new Promise(resolve => (next = resolve)); | ||
}, | ||
async return(): Promise<IteratorReturnResult<void>> { | ||
if (!ended) next = talkback(TalkbackKind.Close); | ||
ended = true; | ||
return doneResult; | ||
}, | ||
[asyncIteratorSymbol()](): SourceIterable<T> { | ||
return this; | ||
}, | ||
}; | ||
}; | ||
/** Subscribes to a given source and collects all synchronous values into an array. | ||
@@ -173,0 +184,0 @@ * @param source - A {@link Source}. |
import { Source, Sink, SignalKind, TalkbackKind, Observer, Subject, TeardownFn } from './types'; | ||
import { push, start, talkbackPlaceholder, teardownPlaceholder } from './helpers'; | ||
import { | ||
push, | ||
start, | ||
talkbackPlaceholder, | ||
teardownPlaceholder, | ||
asyncIteratorSymbol, | ||
} from './helpers'; | ||
import { share } from './operators'; | ||
@@ -48,5 +54,7 @@ | ||
*/ | ||
export function fromAsyncIterable<T>(iterable: AsyncIterable<T>): Source<T> { | ||
export function fromAsyncIterable<T>(iterable: AsyncIterable<T> | AsyncIterator<T>): Source<T> { | ||
return sink => { | ||
const iterator = iterable[Symbol.asyncIterator](); | ||
const iterator: AsyncIterator<T> = | ||
(iterable[asyncIteratorSymbol()] && iterable[asyncIteratorSymbol()]()) || iterable; | ||
let ended = false; | ||
@@ -53,0 +61,0 @@ let looping = false; |
@@ -203,1 +203,6 @@ /** | ||
} | ||
/** Async Iterable/Iterator after having converted a {@link Source}. | ||
* @see {@link toAsyncIterable} for a helper that creates this structure. | ||
*/ | ||
export interface SourceIterable<T> extends AsyncIterator<T>, AsyncIterable<T> {} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
306437
8785
2