Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { ReflectionKind, DeclarationReflection, } from "../../models/reflections/index.js";
import { ReferenceType } from "../../models/types.js";
import { ConverterComponent } from "../components.js";
import { ApplicationEvents } from "../../application-events.js";
import { ConverterEvents } from "../converter-events.js";
/**
* Responsible for adding `implementedBy` / `implementedFrom`
*/
export class TypePlugin extends ConverterComponent {
reflections = new Set();
constructor(owner) {
super(owner);
this.owner.on(ConverterEvents.RESOLVE, this.onResolve.bind(this));
this.owner.on(ConverterEvents.RESOLVE_END, this.onResolveEnd.bind(this));
this.owner.on(ConverterEvents.END, () => this.reflections.clear());
this.application.on(ApplicationEvents.REVIVE, this.onRevive.bind(this), 100);
}
onRevive(project) {
for (const id in project.reflections) {
this.resolve(project, project.reflections[id]);
}
this.finishResolve(project);
this.reflections.clear();
}
onResolve(context, reflection) {
this.resolve(context.project, reflection);
}
resolve(project, reflection) {
if (!(reflection instanceof DeclarationReflection))
return;
if (reflection.kindOf(ReflectionKind.ClassOrInterface)) {
this.postpone(reflection);
walk(reflection.implementedTypes, (target) => {
this.postpone(target);
target.implementedBy ||= [];
if (!target.implementedBy.some((t) => t.reflection === reflection)) {
target.implementedBy.push(ReferenceType.createResolvedReference(reflection.name, reflection, project));
}
});
walk(reflection.extendedTypes, (target) => {
this.postpone(target);
target.extendedBy ||= [];
if (!target.extendedBy.some((t) => t.reflection === reflection)) {
target.extendedBy.push(ReferenceType.createResolvedReference(reflection.name, reflection, project));
}
});
}
function walk(types, callback) {
if (!types) {
return;
}
types.forEach((type) => {
if (!(type instanceof ReferenceType)) {
return;
}
if (!type.reflection ||
!(type.reflection instanceof DeclarationReflection)) {
return;
}
callback(type.reflection);
});
}
}
postpone(reflection) {
this.reflections.add(reflection);
}
onResolveEnd(context) {
this.finishResolve(context.project);
}
finishResolve(project) {
this.reflections.forEach((reflection) => {
if (reflection.implementedBy) {
reflection.implementedBy.sort((a, b) => {
if (a.name === b.name) {
return 0;
}
return a.name > b.name ? 1 : -1;
});
}
let root;
let hierarchy;
function push(types) {
const level = { types: types };
if (hierarchy) {
hierarchy.next = level;
hierarchy = level;
}
else {
root = hierarchy = level;
}
}
if (reflection.extendedTypes) {
push(reflection.extendedTypes);
}
push([
ReferenceType.createResolvedReference(reflection.name, reflection, project),
]);
hierarchy.isTarget = true;
if (reflection.extendedBy) {
push(reflection.extendedBy);
}
// No point setting up a hierarchy if there is no hierarchy to display
if (root.next) {
reflection.typeHierarchy = root;
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

var testArray = function testArray(t, actual, expected, msg) {
t.deepEqual(actual, expected, msg);
t.equal(actual.length, expected.length, 'expected ' + expected.length + ', got ' + actual.length);
};

module.exports = function (flat, t) {
t.test('flattens', function (st) {
testArray(st, flat([1, [2], [[3]], [[['four']]]]), [1, 2, [3], [['four']]], 'missing depth only flattens 1 deep');

testArray(st, flat([1, [2], [[3]], [[['four']]]], 1), [1, 2, [3], [['four']]], 'depth of 1 only flattens 1 deep');
st.notDeepEqual(flat([1, [2], [[3]], [[['four']]]], 1), [1, 2, 3, ['four']], 'depth of 1 only flattens 1 deep: sanity check');

testArray(st, flat([1, [2], [[3]], [[['four']]]], 2), [1, 2, 3, ['four']], 'depth of 2 only flattens 2 deep');
st.notDeepEqual(flat([1, [2], [[3]], [[['four']]]], 2), [1, 2, 3, 'four'], 'depth of 2 only flattens 2 deep: sanity check');

testArray(st, flat([1, [2], [[3]], [[['four']]]], 3), [1, 2, 3, 'four'], 'depth of 3 only flattens 3 deep');
testArray(st, flat([1, [2], [[3]], [[['four']]]], Infinity), [1, 2, 3, 'four'], 'depth of Infinity flattens all the way');

st.end();
});

t.test('sparse arrays', function (st) {
// eslint-disable-next-line no-sparse-arrays
st.deepEqual(flat([, [1]]), flat([[], [1]]), 'an array hole is treated the same as an empty array');

st.end();
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# es-iterator-helpers <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][npm-badge-png]][package-url]

An ESnext spec-compliant sync iterator helpers shim/polyfill/replacement that works as far down as ES3.

This package implements the [es-shim API](https://github.com/es-shims/api) “multi” interface. It works in an ES3-supported environment and complies with the [iterator helpers spec](https://tc39.es/proposal-iterator-helpers/) and the [iterator sequencing spec](https://tc39.es/proposal-iterator-sequencing/).

Because the `Iterator.prototype` methods depend on a receiver (the `this` value), the main export in each subdirectory takes the iterator to operate on as the first argument.

The main export of the package itself is simply an array of the available directory names. It’s sole intended use is for build tooling and testing.

## Supported things

- [`Iterator` constructor](https://tc39.es/proposal-iterator-helpers/#sec-iterator-constructor)
- [`Iterator.prototype`](https://tc39.es/proposal-iterator-helpers/#sec-iterator.prototype)
- [`Iterator.concat`](https://tc39.es/proposal-iterator-sequencing/)
- [`Iterator.from`](https://tc39.es/proposal-iterator-helpers/#sec-iterator.from)
- [`Iterator.zip`](https://tc39.es/proposal-joint-iteration/#sec-iterator.zip)
- [`Iterator.zipKeyed`](https://tc39.es/proposal-joint-iteration/#sec-iterator.zipkeyed)
- [`Iterator.prototype.constructor`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.constructor)
- [`Iterator.prototype.drop`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.drop)
- [`Iterator.prototype.every`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.every)
- [`Iterator.prototype.filter`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.filter)
- [`Iterator.prototype.find`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.find)
- [`Iterator.prototype.flatMap`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.flatmap)
- [`Iterator.prototype.forEach`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.foreach)
- [`Iterator.prototype.map`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.map)
- [`Iterator.prototype.reduce`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.reduce)
- [`Iterator.prototype.some`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.some)
- [`Iterator.prototype.take`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.take)
- [`Iterator.prototype.toArray`](https://tc39.es/proposal-iterator-helpers/#sec-iteratorprototype.toarray)

## Environments where this is needed

- node v22, Chrome >= v122: has a [bug](https://issues.chromium.org/issues/336839115)
- node < v22, Chrome < v122, Safari <= v17.1, Firefox <= v125: not implemented
- all environments lack Iterator.concat, Iterator.zip, Iterator.zipKeyed

## Getting started

```sh
npm install --save es-iterator-helpers
```

## Usage/Examples

Using explicit imports:

```js
const map = require('es-iterator-helpers/Iterator.prototype.map');
const toArray = require('es-iterator-helpers/Iterator.prototype.toArray');
const assert = require('assert');

const iterator = [1, 2, 3].values();

const mapped = map(iterator, (x) => x + 10);
assert.deepEqual(
mapped.next(),
{
done: false,
value: 11,
}
);
assert.deepEqual(
toArray(mapped),
[12, 13]
);
```

Shim using `require`:

```js
require('es-iterator-helpers/auto'); // shim all of the methods

require('es-iterator-helpers/Iterator.prototype.map/auto'); // shim the “map” method
```

Shim using `import` syntax:

[](#preventEval)
```js
import 'es-iterator-helpers/auto'; // shim all of the methods

import 'es-iterator-helpers/Iterator.prototype.map/auto'; // shim the “map” method
```

## Tests
Simply clone the repo, `npm install`, and run `npm test`

[package-url]: https://npmjs.org/package/es-iterator-helpers
[npm-version-svg]: https://versionbadg.es/es-shims/iterator-helpers.svg
[deps-svg]: https://david-dm.org/es-shims/iterator-helpers.svg
[deps-url]: https://david-dm.org/es-shims/iterator-helpers
[dev-deps-svg]: https://david-dm.org/es-shims/iterator-helpers/dev-status.svg
[dev-deps-url]: https://david-dm.org/es-shims/iterator-helpers#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/es-iterator-helpers.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/es-iterator-helpers.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/es-iterator-helpers.svg
[downloads-url]: https://npm-stat.com/charts.html?package=es-iterator-helpers
[codecov-image]: https://codecov.io/gh/es-shims/iterator-helpers/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/es-shims/iterator-helpers/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/iterator-helpers
[actions-url]: https://github.com/es-shims/iterator-helpers/actions
Loading
Loading