Skip to content

Instantly share code, notes, and snippets.

@conartist6
Created May 11, 2024 15:23
Show Gist options
  • Save conartist6/ebcb1b0b37bf24f4d75de7924443f8b2 to your computer and use it in GitHub Desktop.
Save conartist6/ebcb1b0b37bf24f4d75de7924443f8b2 to your computer and use it in GitHub Desktop.
StreamIterable
export const getStreamIterator = (obj) => {
return obj[Symbol.for('@@streamIterator')]?.() || obj[Symbol.iterator]?.();
};
export class SyncGenerator {
constructor(embeddedGenerator) {
if (!embeddedGenerator.next) throw new Error();
this.generator = embeddedGenerator;
}
next(value) {
const step = this.generator.next(value);
if (step instanceof Promise) {
throw new Error('invalid embedded generator');
}
if (step.done) {
return { value: undefined, done: true };
} else if (step.value instanceof Promise) {
throw new Error('sync generators cannot resolve promises');
} else {
const { value } = step;
return { value, done: false };
}
}
return(value) {
const step = this.generator.return(value);
if (step instanceof Promise) {
throw new Error('invalid embedded generator');
}
if (step.value instanceof Promise) {
throw new Error('sync generators cannot resolve promises');
}
return step;
}
[Symbol.iterator]() {
return this;
}
}
export class AsyncGenerator {
constructor(embeddedGenerator) {
this.generator = embeddedGenerator;
}
next(value) {
const step = this.generator.next(value);
if (step instanceof Promise) {
throw new Error('invalid embedded generator');
}
if (step.done) {
return Promise.resolve({ value: undefined, done: true });
} else if (step.value instanceof Promise) {
return step.value.then((value) => {
return this.next(value);
});
} else {
const { value } = step;
return Promise.resolve({ value, done: false });
}
}
return(value) {
const result = this.generator.return(value);
if (result instanceof Promise) {
throw new Error('sync generators cannot resolve promises');
}
return result;
}
[Symbol.asyncIterator]() {
return this;
}
}
export class StreamGenerator {
constructor(embeddedGenerator) {
this.generator = embeddedGenerator;
}
next(value) {
const step = this.generator.next(value);
if (step.done) {
return { value: undefined, done: true };
} else if (step.value instanceof Promise) {
return step.value.then((value) => {
return this.next(value);
});
} else {
const { value } = step;
return { value, done: false };
}
}
return(value) {
return this.generator.return(value);
}
[Symbol.for('@@streamIterator')]() {
return this;
}
}
export class StreamIterable {
constructor(embeddedStreamIterable) {
this.iterable = embeddedStreamIterable;
}
[Symbol.iterator]() {
return new SyncGenerator(this.iterable);
}
[Symbol.asyncIterator]() {
return new AsyncGenerator(this.iterable);
}
[Symbol.for('@@streamIterator')]() {
return new StreamGenerator(this.iterable);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment