Skip to content

Commit d461eae

Browse files
authored
Fix exports (#371)
* fix(throwerror): fix throwerror.ts file name * fix(exports): fix missing .js extensions in includes and ignoreelements * chore(dependencies): update dependencies * fix(exports): make top-level exports match the directory names * fix lint * add node v22.x to CI matrix * remove esm from the build * don't redirect stderr to /dev/null
1 parent e32fc16 commit d461eae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+893
-743
lines changed

.github/workflows/bundle.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ jobs:
1818
- {bundler: rollup, target: ix}
1919
- {bundler: webpack, target: ix}
2020
steps:
21-
- name: Setup node v20.x
21+
- name: Setup node v22.x
2222
uses: actions/setup-node@v4
2323
with:
24-
node-version: 20.x
24+
node-version: 22.x
2525
- name: Checkout
2626
uses: actions/checkout@v4
2727
with:
2828
persist-credentials: false
2929

3030
- name: Construct cache keys
3131
run: |
32-
echo node_modules_key='["${{ runner.os }}", "node_modules", "20.x", "${{ hashFiles('package.json', 'yarn.lock') }}"]' >> $GITHUB_ENV;
33-
echo targets_key='["${{ runner.os }}", "targets", "20.x", "ix", "", "${{ hashFiles('package.json', 'yarn.lock', 'tsconfig.json', 'src/**/*', 'tsconfigs/**/*') }}"]' >> $GITHUB_ENV;
32+
echo node_modules_key='["${{ runner.os }}", "node_modules", "22.x", "${{ hashFiles('package.json', 'yarn.lock') }}"]' >> $GITHUB_ENV;
33+
echo targets_key='["${{ runner.os }}", "targets", "22.x", "ix", "", "${{ hashFiles('package.json', 'yarn.lock', 'tsconfig.json', 'src/**/*', 'tsconfigs/**/*') }}"]' >> $GITHUB_ENV;
3434
3535
- name: Cache targets
3636
uses: actions/cache@v4

.github/workflows/lint.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ jobs:
88
name: Lint
99
runs-on: ubuntu-22.04
1010
steps:
11-
- name: Setup node v20.x
11+
- name: Setup node v22.x
1212
uses: actions/setup-node@v4
1313
with:
14-
node-version: 20.x
14+
node-version: 22.x
1515

1616
- name: Checkout
1717
uses: actions/checkout@v4
@@ -20,7 +20,7 @@ jobs:
2020

2121
- name: Construct cache keys
2222
run: |
23-
echo node_modules_key='["${{ runner.os }}", "node_modules", "20.x", "${{ hashFiles('package.json', 'yarn.lock') }}"]' >> $GITHUB_ENV;
23+
echo node_modules_key='["${{ runner.os }}", "node_modules", "22.x", "${{ hashFiles('package.json', 'yarn.lock') }}"]' >> $GITHUB_ENV;
2424
2525
- name: Cache node_modules
2626
uses: actions/cache@v4

.github/workflows/test.yml

+44-7
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
node: [16.x, 18.x, 20.x]
13+
node: [16.x, 18.x, 20.x, 22.x]
1414
target: [es5, es2015, esnext]
1515
module: [cjs, esm, umd]
1616
include:
1717
- {node: 16.x, target: ix}
1818
- {node: 18.x, target: ix}
1919
- {node: 20.x, target: ix}
20-
- {node: 20.x, target: src, args: --coverage}
20+
- {node: 22.x, target: ix}
21+
- {node: 22.x, target: src, args: --coverage}
2122
steps:
2223
- name: Setup node v${{ matrix.node }}
2324
uses: actions/setup-node@v4
@@ -98,6 +99,8 @@ jobs:
9899
t: "${{ matrix.target }}"
99100
m: "${{ matrix.module }}"
100101
run: |
102+
set -e;
103+
101104
targetdir="./targets${t:+/${t}}${m:+/${m}}";
102105
pkg_name="$(jq -r '.name' "${targetdir}/package.json")";
103106
pkg_type="$(jq -r '.type' "${targetdir}/package.json")";
@@ -108,16 +111,50 @@ jobs:
108111
cd "${_tmp}/node_modules/${pkg_name}";
109112
npm i;
110113
cd "${_tmp}/";
114+
115+
import_paths=(
116+
"${pkg_name}"
117+
"${pkg_name}/Ix"
118+
"${pkg_name}/Ix.iterable"
119+
"${pkg_name}/Ix.iterable.operators"
120+
"${pkg_name}/Ix.asynciterable"
121+
"${pkg_name}/Ix.asynciterable.operators"
122+
"${pkg_name}/iterable/index"
123+
"${pkg_name}/iterable/operators"
124+
"${pkg_name}/iterable/operators/index"
125+
"${pkg_name}/asynciterable/index"
126+
"${pkg_name}/asynciterable/operators"
127+
"${pkg_name}/asynciterable/operators/index"
128+
);
129+
130+
test_import_esm() {
131+
local path;
132+
for path in "${import_paths[@]}"; do
133+
node --input-type=module -e "import '${path}'";
134+
done
135+
}
136+
137+
test_import_cjs() {
138+
local path;
139+
for path in "${import_paths[@]}"; do
140+
node --input-type=commonjs -e "require('${path}')";
141+
done
142+
}
143+
111144
set -x;
112145
if test "${pkg_type}" = "module"; then
113146
# Test importing as ESModule
114-
node --input-type=module -e "import '${pkg_name}'";
147+
test_import_esm;
148+
elif test "$m" = umd; then
149+
# Test importing UMD as both CommonJS and ESM
150+
test_import_cjs;
151+
test_import_esm;
115152
else
116-
# Test importing as CommonJS
117-
node --input-type=commonjs -e "require('${pkg_name}')";
118-
# Test importing CommonJS module but allow it to fail
119-
node --input-type=module -e "import '${pkg_name}'" || true;
153+
# Test importing others as both CommonJS and ESM, but allow ESM to fail
154+
test_import_cjs;
155+
test_import_esm || true;
120156
fi
121157
set +x;
158+
122159
cd /;
123160
rm -rf "${_tmp}";

docs/asynciterable/converting.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Very often we have an existing data structure that we wish to convert to an asyn
1717
The `as` method converts directly to an async-iterable, whereas with `from` method allows us to modify the collection as it is created, mimicking the the [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) method.
1818

1919
```typescript
20-
import { as, from } from 'ix/Ix.asynciterable';
20+
import { as, from } from 'ix/asynciterable';
2121

2222
// As with Array and Set
2323
const result1 = as([1, 2, 3]); // From array
@@ -52,7 +52,7 @@ IxJS also gives seamless support for Observables, for those that implement the `
5252

5353
```typescript
5454
import { observableOf } from 'rxjs';
55-
import { as } from 'ix/Ix.asynciterable';
55+
import { as } from 'ix/asynciterable';
5656

5757
const source = observableOf(1, 2, 3);
5858
const results = as(source);
@@ -67,7 +67,7 @@ for await (const item of results) {
6767
Streams and AsyncIterables go hand in hand as a pull to push model. DOM Streams are a newer concept, bringing streaming capabilities into the browser, and with IxJS, we can then convert those DOM streams into AsyncIterables using the `fromDOMStream` method.
6868

6969
```typescript
70-
import { fromDOMStream } from 'ix/Ix.asynciterable';
70+
import { fromDOMStream } from 'ix/asynciterable';
7171

7272
const response = await fetch('someurl');
7373

@@ -97,7 +97,7 @@ We can then introduce IxJS by using the `fromNodeStream` which allows us then to
9797

9898
```typescript
9999
import * as fs from 'fs';
100-
import { fromNodeStream } from 'ix/Ix.node';
100+
import { fromNodeStream } from 'ix/node';
101101

102102
const readable = fs.createReadStream('tmp.txt', {encoding: 'utf8'});
103103
const source = fromNodeStream(readable);
@@ -111,9 +111,9 @@ Or we can use `asAsyncIterable()` to take advantage of Node Streams' fluent `pip
111111

112112
```typescript
113113
import * as fs from 'fs';
114-
import { map } from 'ix/Ix.asynciterable.operators';
115-
import { flatMap } from 'ix/Ix.asynciterable.operators';
116-
import { asAsyncIterable } from 'ix/Ix.node';
114+
import { map } from 'ix/asynciterable/operators';
115+
import { flatMap } from 'ix/asynciterable/operators';
116+
import { asAsyncIterable } from 'ix/node';
117117

118118
const source = fs
119119
.createReadStream('tmp.txt', {encoding: 'utf8'})
@@ -134,7 +134,7 @@ Although we traditionally think of events being push only such as Subject/Observ
134134

135135
```typescript
136136
import { EventEmitter } from 'events';
137-
import { fromEvent } from 'ix/Ix.asynciterable';
137+
import { fromEvent } from 'ix/asynciterable';
138138

139139
function getEvents() {
140140
const emitter = new EventEmitter();
@@ -160,7 +160,7 @@ The other type of binding is `fromEventPattern` which allows you to have an add
160160

161161
```typescript
162162
import { EventEmitter } from 'events';
163-
import { fromEventPattern } from 'ix/Ix.asynciterable';
163+
import { fromEventPattern } from 'ix/asynciterable';
164164

165165
function getEvents() {
166166
const emitter = new EventEmitter();

docs/asynciterable/creating.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ let value, done;
4949
Very rarely will we ever need to create these async-iterables by hand, however, if you need a collection that you can add to as well as iterate, we have the `AsyncSink` class. This class serves as a basis for some of our operators such as binding to events and DOM and Node.js streams.
5050

5151
```typescript
52-
import { AsyncSink } from 'ix/Ix.asynciterable';
52+
import { AsyncSink } from 'ix/asynciterable';
5353

5454
const sink = new AsyncSink();
5555
sink.write(1);
@@ -75,7 +75,7 @@ let value, done;
7575
Now that we know the basics, we can take the async-iterable from above and create an AsyncIterable from the source using the `create` method. This takes in a function which takes in an optional `AbortSignal` for cancellation, and you return the the `[Symbol.asyncIterator]` method implementation. It's up to you whether to cancel based upon the incoming `AbortSignal`, whether to throw an `AbortError` or not.
7676

7777
```typescript
78-
import { create } from 'ix/Ix.asynciterable';
78+
import { create } from 'ix/asynciterable';
7979

8080
const source = {
8181
data: [1, 2, 3],
@@ -104,7 +104,7 @@ for await (const item of results) {
104104
Understanding the basics gets us so far, but we want to be able to easily create async-iterable sequences, for example, from known values. To do this, we have the `of` factory function which takes any number of arguments and converts those arguments into an async-iterable sequence. This implementation mimicks that of [`Array.of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of)
105105

106106
```typescript
107-
import { of } from 'ix/Ix.asynciterable';
107+
import { of } from 'ix/asynciterable';
108108

109109
const source = of(1, 2, 3, 4, 5);
110110

@@ -118,7 +118,7 @@ for await (const item of source) {
118118
There may be cases when you want to return an empty sequence, when iterated will always say it is complete. For that, we have the `empty` method.
119119

120120
```typescript
121-
import { empty } from 'ix/Ix.asynciterable';
121+
import { empty } from 'ix/asynciterable';
122122

123123
const source = empty();
124124

@@ -130,7 +130,7 @@ const { value, done } = it.next();
130130
There may also be cases where you never want the sequence to return. In the case of `never`, it can be used in places like `race` where the other sequence will always win.
131131

132132
```typescript
133-
import { never, of, race } from 'ix/Ix.asynciterable';
133+
import { never, of, race } from 'ix/asynciterable';
134134

135135
const source = race(of(1), never());
136136

@@ -148,7 +148,7 @@ let value, done;
148148
Another way we can create async-iterable sequences is with a range. For example, if we want 10 numbers starting at 1, we can use the `range` factory method to call `range(1, 10)`.
149149

150150
```typescript
151-
import { range } from 'ix/Ix.asynciterable';
151+
import { range } from 'ix/asynciterable';
152152

153153
const source = range(1, 10);
154154

@@ -174,7 +174,7 @@ for (
174174
The `generate` method has the same parameters as this for loop, as in our example here.
175175

176176
```typescript
177-
import { generate } from 'ix/Ix.asynciterable';
177+
import { generate } from 'ix/asynciterable';
178178

179179
const source = generate(
180180
0, // Initial State
@@ -191,7 +191,7 @@ for await (const item of source) {
191191
In addition to the `generate` method, we have the `generateTime` which adds a time element to the sequence to delay in milliseconds between results.
192192

193193
```typescript
194-
import { generate } from 'ix/Ix.asynciterable';
194+
import { generate } from 'ix/asynciterable';
195195

196196
const source = generate(
197197
0, // Initial State
@@ -211,7 +211,7 @@ for await (const item of source) {
211211
There are many factory functions that carry over from RxJS over to IxJS including `interval` where we can yield a value at a specified interval. For example, we can loop through a sequence, yielding a value every 1 second.
212212

213213
```typescript
214-
import { interval } from 'ix/Ix.asynciterable';
214+
import { interval } from 'ix/asynciterable';
215215

216216
const source = interval(1000 /* ms */);
217217

docs/readme.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ The Interactive Extensions for JavaScript (IxJS) is a set of methods on top of `
77
Starting in ES6, the [`Symbol.iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator) method was introduced to allow for iteration over collections such as `Array`, `Map`, `Set` and even ``Generator`. IxJS introduces a number of creation factories and operators that operate on these `Iterable` collections lazily. Each factory can be imported from `'ix/iterable'` and operators from `'ix/iterable/operators'` such as the following creating an iterable via `of` and then transforming each item using the `map` operator. You can then iterate over the resulting collection using [`for ... of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) syntax, or the use of the `forEach` method.
88

99
```typescript
10-
import { of } from 'ix/Ix.iterable';
11-
import { map } from 'ix/Ix.iterable.operators';
10+
import { of } from 'ix/iterable';
11+
import { map } from 'ix/iterable/operators';
1212

1313
const source = of(1, 2, 3, 4, 5);
1414
const result = source.pipe(
@@ -23,7 +23,7 @@ for (const item of result) {
2323
Alternatively, you can program using dot-notation where we add methods to the `IterableX` object so we can program in a fluent style. We can bring in only the factories operators we need, therefore not needing to bring in the entire library with all its operators. The factories can be brought in via `'ix/add/iterable/<name>'` and operators via `'ix/add/iterable-operators/<name>'`, where `name` is replaced with the factory or operator of your choice.
2424

2525
```typescript
26-
import { IterableX as Iterable } from 'ix/Ix.iterable';
26+
import { IterableX as Iterable } from 'ix/iterable';
2727

2828
// Add factory and operators
2929
import 'ix/add/iterable/of';
@@ -66,11 +66,11 @@ That's only the beginning with IxJS and each section below covers more in detail
6666

6767
## AsyncIterable
6868

69-
In ES2018, the concept of asynchronous iteration was introduced, which allowed the same kind of iteration we had in ES6, but for asynchronous sequences using the [`Symbol.asyncIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) method for things such as asynchronous generators. IxJS here introduces a whole set of factories and operators on async iterables to serve as a standard class library, covering the same operators as `Iterable`, but also adding in asynchronous operations such as `race`, but also time based operations as well. Each factory such as `from`, an `of` can be imported via `'ix/Ix.asynciterable'` as well as operators such as `map` and `filter` can be imported via `'ix/Ix.asynciterable.operators'`. Once created, uou can then iterate over the resulting collection using [`for await ... of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) syntax, or the use of the `forEach` method.
69+
In ES2018, the concept of asynchronous iteration was introduced, which allowed the same kind of iteration we had in ES6, but for asynchronous sequences using the [`Symbol.asyncIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) method for things such as asynchronous generators. IxJS here introduces a whole set of factories and operators on async iterables to serve as a standard class library, covering the same operators as `Iterable`, but also adding in asynchronous operations such as `race`, but also time based operations as well. Each factory such as `from`, an `of` can be imported via `'ix/asynciterable'` as well as operators such as `map` and `filter` can be imported via `'ix/asynciterable/operators'`. Once created, uou can then iterate over the resulting collection using [`for await ... of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) syntax, or the use of the `forEach` method.
7070

7171
```typescript
72-
import { as } from 'ix/Ix.asynciterable';
73-
import { map } from 'ix/Ix.asynciterable.operators';
72+
import { as } from 'ix/asynciterable';
73+
import { map } from 'ix/asynciterable/operators';
7474

7575
const soureFactory = async function*() {
7676
yield 1;
@@ -92,8 +92,8 @@ for await (const item of results) {
9292
The [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for the web brought in a new way to think about getting data using Promises instead of the legacy `XMLHttpRequest` API. With this also brought in the idea of cancellation via the [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) and [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal), also known as the Abort API. IxJS also supports this with a number of async aggregate operations such as `first`, `last` accepting an `AbortSignal` but also introducing `AbortSignal` support to pass through the entire chain. This section gives a very brief introduction for support but is documented later on below.
9393

9494
```typescript
95-
import { as, last } from 'ix/Ix.asynciterable';
96-
import { map, withAbort } from 'ix/Ix.asynciterable.operators';
95+
import { as, last } from 'ix/asynciterable';
96+
import { map, withAbort } from 'ix/asynciterable/operators';
9797

9898
const sourceFactory = async function*() {
9999
yield 1;
@@ -123,7 +123,7 @@ for await (const item of result) {
123123
If you prefer the fluent style of method chaining, IxJS also supports this for async-iterables via the `AsyncIterableX` object. Then you can add the factories or operators of your choosing without bringing in the entire library. The factories can be brought in via `'ix/add/asynciterable/<name>'` and operators via `'ix/add/asynciterable-operators/<name>'`, where `name` is replaced with the factory or operator of your choice.
124124

125125
```typescript
126-
import { AsyncIterableX as AsyncIterable } from 'ix/Ix.asynciterable';
126+
import { AsyncIterableX as AsyncIterable } from 'ix/asynciterable';
127127
import 'ix/add/asynciterable/as';
128128
import 'ix/add/asynciterable/last';
129129
import 'ix/add/asynciterable-operators/map';

gulp/bundle-task.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ export const esbuildTask = ((cache) => memoizeTask(cache, function pkgEsbuild(ta
4949
].reduce((aliases, ext) => {
5050
return [
5151
'Ix',
52-
'Ix.dom',
53-
'Ix.node',
54-
'Ix.iterable',
55-
'Ix.asynciterable',
56-
'Ix.iterable.operators',
57-
'Ix.asynciterable.operators'
52+
'dom',
53+
'node',
54+
'iterable',
55+
'asynciterable',
56+
'iterable/operators',
57+
'asynciterable/operators'
5858
].reduce((aliases, entrypoint) => ({
5959
...aliases,
6060
[`ix/${entrypoint}.${ext}`]: Path.join(pkgDir, `${entrypoint}.${ext}`)
@@ -135,7 +135,7 @@ export const webpackTask = ((cache) => memoizeTask(cache, function pkgWebpack(ta
135135
]
136136
},
137137
resolve: {
138-
extensions: ['.mjs', '.cjs', '.js'],
138+
extensions: ['.mjs', '.js'],
139139
alias: { 'ix': pkgDir }
140140
},
141141
stats: 'errors-only',

0 commit comments

Comments
 (0)