Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SIA-R70 #839

Closed
wants to merge 11 commits into from
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/integrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
os: [ubuntu-latest, windows-latest]
node: [14, 16]
runs-on: ${{ matrix.os }}
env:
NODE_OPTIONS: "--max-old-space-size=4096"
steps:
- uses: actions/[email protected]
- uses: actions/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- run: >
yarn workspaces foreach
--no-private
--topological-dev
--topological
npm publish --tolerate-republish
- uses: actions/[email protected]
env:
Expand Down
18 changes: 0 additions & 18 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,12 @@ Items that are related, such as breaking changes, new features, or changes to ex

## [Unreleased]

## [0.20.0](../../compare/v0.19.0...v0.20.0) (2021-07-09)

In addition to the changes listed below, this release adjusts the compile target from `es2018` to `es2020`.

### Added

- [@siteimprove/alfa-rules](packages/alfa-rules): Implementations of SIA-R54, SIA-R55, and SIA-R78 are now available. ([#834](../../pull/834), [#835](../../pull/835), [#854](../../pull/854))

- [@siteimprove/alfa-scraper](packages/alfa-scraper): The `Scraper#scrape()` methods now accepts an `archive` option for storing an archive of the page scraped. ([#840](../../pull/840))

- [@siteimprove/alfa-cli](packages/alfa-cli): Two new flags, `--archive` and `--archive-format`, are now available in the `alfa scrape` command for storing an archive of the page scraped. ([#840](../../pull/840))

- [@siteimprove/alfa-hash](packages/alfa-hash): `Hash#writeBigInt()`, `Hash#writeBigInt64()`, `Hash#writeBigUint64()`, `Hash#writeUndefined()`, `Hash#writeNull()`,`Hash#writeObject()`, and `Hash#writeSymbol()` are now available. ([#853](../../pull/853))

### Fixed

- [@siteimprove/alfa-aria](packages/alfa-aria): A bug in how names were computed for subtrees and implicitly referenced `<label>` elements has been fixed. ([#808](../../issues/808), [#859](../../pull/859))

- [@siteimprove/alfa-rules](packages/alfa-rules): The contrast ratios output in messages from SIA-R66 and SIA-R69 are now correctly listed as `<bright>:<dark>` rather than `<dark>:<bright>`.

- [@siteimprove/alfa-rules](packages/alfa-rules): SIA-R56 is now correctly exported and available for audits. ([#850](../../pull/850))

- [@siteimprove/alfa-rules](packages/alfa-rules): `isClipped()` now considers elements with a height or width of 0 as clipping if overflow causes scrolling. It now also checks if the ancestors of an element might cause it to clip. ([#731](../../issues/731), [#774](../../issues/774), [#827](../../pull/827), [#848](../../pull/848))

## [0.19.0](../../compare/v0.18.0...v0.19.0) (2021-06-15)

### Breaking
Expand Down
56 changes: 25 additions & 31 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,7 @@ In Alfa, JSON serialization is often used as a means of asserting the structure

We've already seen quite a bit about the `@siteimprove/alfa-map` package and its `Map<K, V>` class. The `Map<K, V>` class is, however, just one out of several collections used throughout Alfa. In this section, we'll provide an overview of the most common collections and their intended use. As with any data structures, they each have their own strengths and weaknesses to be mindful of when choosing a collection for a given task.

#### `Collection.Indexed<T>`

##### `List<T>`
#### `List<T>`

The `List<T>` class provides an implementation of a [persistent][] [vector trie][] for storing a list of values of type `T`. It provides effectively constant time `#append()`, `#set()`, and `#get()`.

Expand All @@ -415,67 +413,63 @@ For values, `List<T>` uses an implementation of `Equatable`, when available. Tha

- You're only interested in a few values of the list, which might be better served by the `Sequence<T>` class.

##### `Sequence<T>`
#### `Map<K, V>`

The `Sequence<T>` class provides an implementation of a [persistent][] [lazy][] list for storing a possibly infinite sequence of values of type `T`. By virtue of being lazy, it provides mostly constant time operations as no computations are actually performed until the corresponding values are requested.
The `Map<K, V>` class provides an implementation of a [persistent][] [hash trie][] for associating unique keys of type `K` with values of type `V`. It provides effectively constant time `#set()`, `#has()`, `#get()`, and `#delete()`.

**Do use when:**
For keys, `Map<K, V>` uses implementations of `Equatable` and `Hashable`, when available. That is, two keys `a` and `b` are considered the same key if `a.hash().equals(b.hash())` and `a.equals(b)`.

- You're performing sequence operations on an arbitrary and possible infinite `Iterable<T>`. This includes generator functions, which can be beneficial to wrap in a `Sequence<T>`.
For values, `Map<K, V>` uses an implementation of `Equatable`, when available. That is, no modifications are made when updating the value of a key with the current value `a` and the new value `b` if `a.equals(b)`.

- You're working with a sequence of values that don't all need to be determined at once. Using `Sequence<T>`, such sequences can be constructed in constant time and only the needed values yielded as necessary.
**Do use when:**

- You're performing sequence operations where eager evaluation would lead to suboptimal performance, such as `#map()` followed by `#find()`. With eager evaluation, `#map()` will be applied to _every_ value of the sequence, even those _after_ the value returned by `#find()`. With lazy evaluation, `#map()` will only be applied _up to and including_ the value returned by `#find()`.
- Your keys have custom equivalence and hashing constraints.

**Don't use when:**

- You're often modifying the sequence which for each modification, with the exception of prepends, is done in time proportional to the number of values yielded by the sequence.
- You're working with performance critical code, which may be better served by the builtin `Map<K, V>` or `WeakMap<K, V>` class.

##### `Slice<T>`
#### `Set<T>`

The `Slice<T>` class provides an implementation of a [persistent][] [copy-on-write][] array for storing values of type `T`. It provides constant time `#get()`, `#has()`, and `#slice()`.
The `Set<T>` class provides an implementation of a [persistent][] [hash trie][] for storing a set of unique values of type `K`. It provides effectively constant time `#add()`, `#has()`, and `#delete()`.

For values, `Set<T>` uses implementations of `Equatable` and `Hashable`, when available. That is, two values `a` and `b` are considered the same value if `a.hash().equals(b.hash())` and `a.equals(b)`.

**Do use when:**

- You're working with increasingly smaller portions of a backing array, such as when parsing a list of tokens.
- Your values have custom equivalence and hashing constraints.

**Don't use when:**

- You're working with performance critical code, which may be better served by manually tracking a pointer into the backing array.

#### `Collection.Keyed<K, V>`

##### `Map<K, V>`

The `Map<K, V>` class provides an implementation of a [persistent][] [hash trie][] for associating unique keys of type `K` with values of type `V`. It provides effectively constant time `#set()`, `#has()`, `#get()`, and `#delete()`.
- You're working with performance critical code, which may be better served by the builtin `Set<T>` or `WeakSet<T>` class.

For keys, `Map<K, V>` uses implementations of `Equatable` and `Hashable`, when available. That is, two keys `a` and `b` are considered the same key if `a.hash().equals(b.hash())` and `a.equals(b)`.
#### `Sequence<T>`

For values, `Map<K, V>` uses an implementation of `Equatable`, when available. That is, no modifications are made when updating the value of a key with the current value `a` and the new value `b` if `a.equals(b)`.
The `Sequence<T>` class provides an implementation of a [persistent][] [lazy][] list for storing a possibly infinite sequence of values of type `T`. By virtue of being lazy, it provides mostly constant time operations as no computations are actually performed until the corresponding values are requested.

**Do use when:**

- Your keys have custom equivalence and hashing constraints.
- You're performing sequence operations on an arbitrary and possible infinite `Iterable<T>`. This includes generator functions, which can be beneficial to wrap in a `Sequence<T>`.

**Don't use when:**
- You're working with a sequence of values that don't all need to be determined at once. Using `Sequence<T>`, such sequences can be constructed in constant time and only the needed values yielded as necessary.

- You're working with performance critical code, which may be better served by the builtin `Map<K, V>` or `WeakMap<K, V>` class.
- You're performing sequence operations where eager evaluation would lead to suboptimal performance, such as `#map()` followed by `#find()`. With eager evaluation, `#map()` will be applied to _every_ value of the sequence, even those _after_ the value returned by `#find()`. With lazy evaluation, `#map()` will only be applied _up to and including_ the value returned by `#find()`.

#### `Collection.Unkeyed<T>`
**Don't use when:**

##### `Set<T>`
- You're often modifying the sequence which for each modification, with the exception of prepends, is done in time proportional to the number of values yielded by the sequence.

The `Set<T>` class provides an implementation of a [persistent][] [hash trie][] for storing a set of unique values of type `K`. It provides effectively constant time `#add()`, `#has()`, and `#delete()`.
#### `Slice<T>`

For values, `Set<T>` uses implementations of `Equatable` and `Hashable`, when available. That is, two values `a` and `b` are considered the same value if `a.hash().equals(b.hash())` and `a.equals(b)`.
The `Slice<T>` class provides an implementation of a [persistent][] [copy-on-write][] array for storing values of type `T`. It provides constant time `#get()`, `#has()`, and `#slice()`.

**Do use when:**

- Your values have custom equivalence and hashing constraints.
- You're working with increasingly smaller portions of a backing array, such as when parsing a list of tokens.

**Don't use when:**

- You're working with performance critical code, which may be better served by the builtin `Set<T>` or `WeakSet<T>` class.
- You're working with performance critical code, which may be better served by manually tracking a pointer into the backing array.

[abstract relational comparison]: https://tc39.es/ecma262/#sec-abstract-relational-comparison
[copy-on-write]: https://en.wikipedia.org/wiki/Copy-on-write
Expand Down
2 changes: 1 addition & 1 deletion docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Alfa uses the currently experimental [Yarn release workflow](https://yarnpkg.com
```console
$ yarn workspaces foreach \
--no-private \
--topological-dev \
--topological \
version --deferred <patch | minor | major>
```

Expand Down
14 changes: 5 additions & 9 deletions docs/review/api/alfa-act.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

```ts

import { Applicative } from '@siteimprove/alfa-applicative';
import * as earl from '@siteimprove/alfa-earl';
import { Equatable } from '@siteimprove/alfa-equatable';
import { Functor } from '@siteimprove/alfa-functor';
Expand All @@ -28,7 +27,7 @@ export class Audit<I, T = unknown, Q = never> {
evaluate(performance?: Performance<Audit.Event<I, T, Q>>): Future<Iterable_2<Outcome<I, T, Q>>>;
// (undocumented)
static of<I, T = unknown, Q = never>(input: I, rules: Iterable_2<Rule<I, T, Q>>, oracle?: Oracle<I, T, Q>): Audit<I, T, Q>;
}
}

// @public (undocumented)
export namespace Audit {
Expand Down Expand Up @@ -73,7 +72,7 @@ export class Cache {
static empty(): Cache;
// (undocumented)
get<I, T, Q>(rule: Rule<I, T, Q>, ifMissing: Thunk<Future<Iterable<Outcome<I, T, Q>>>>): Future<Iterable<Outcome<I, T, Q>>>;
}
}

// @public (undocumented)
export class Diagnostic implements Equatable, Serializable<Diagnostic.JSON> {
Expand Down Expand Up @@ -383,17 +382,13 @@ export namespace Outcome {
}

// @public (undocumented)
export class Question<Q, S, A, T = A> implements Functor<T>, Applicative<T>, Monad<T>, Serializable<Question.JSON<Q, S>> {
export class Question<Q, S, A, T = A> implements Functor<T>, Monad<T>, Serializable<Question.JSON<Q, S>> {
protected constructor(uri: string, type: Q, subject: S, message: string, quester: Mapper<A, T>);
// (undocumented)
answer(answer: A): T;
// (undocumented)
apply<U>(mapper: Question<Q, S, A, Mapper<T, U>>): Question<Q, S, A, U>;
// (undocumented)
flatMap<U>(mapper: Mapper<T, Question<Q, S, A, U>>): Question<Q, S, A, U>;
// (undocumented)
flatten<Q, S, A, T>(this: Question<Q, S, A, Question<Q, S, A, T>>): Question<Q, S, A, T>;
// (undocumented)
map<U>(mapper: Mapper<T, U>): Question<Q, S, A, U>;
// (undocumented)
get message(): string;
Expand All @@ -407,7 +402,7 @@ export class Question<Q, S, A, T = A> implements Functor<T>, Applicative<T>, Mon
get type(): Q;
// (undocumented)
get uri(): string;
}
}

// @public (undocumented)
export namespace Question {
Expand Down Expand Up @@ -644,4 +639,5 @@ export namespace Tag {
}
}


```
6 changes: 2 additions & 4 deletions docs/review/api/alfa-applicative.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@

```ts

import { Functor } from '@siteimprove/alfa-functor';
import { Mapper } from '@siteimprove/alfa-mapper';

// @public (undocumented)
export interface Applicative<T> extends Functor<T> {
export interface Applicative<T> {
// (undocumented)
apply<U>(mapper: Applicative<Mapper<T, U>>): Applicative<U>;
// (undocumented)
map<U>(mapper: Mapper<T, U>): Applicative<U>;
}


```
8 changes: 5 additions & 3 deletions docs/review/api/alfa-array.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ namespace Array_2 {
// (undocumented)
function append<T>(array: Array_2<T>, value: T): Array_2<T>;
// (undocumented)
function apply<T, U>(array: ReadonlyArray<T>, mapper: ReadonlyArray<Mapper<T, U>>): Array_2<U>;
function apply<T, U>(iterable: ReadonlyArray<T>, mapper: ReadonlyArray<Mapper<T, U>>): Array_2<U>;
// (undocumented)
function clone<T extends Clone<T>>(array: ReadonlyArray<T>): Array_2<T>;
// (undocumented)
function collect<T, U>(array: ReadonlyArray<T>, mapper: Mapper<T, Option<U>, [index: number]>): Array_2<U>;
// (undocumented)
function collectFirst<T, U>(array: ReadonlyArray<T>, mapper: Mapper<T, Option<U>, [index: number]>): Option<U>;
// (undocumented)
function compare<T extends Comparable<U>, U = T>(a: ReadonlyArray<T>, b: Iterable_2<U>): Comparison;
function compare<T extends Comparable<T>>(a: ReadonlyArray<T>, b: Iterable_2<T>): Comparison;
// (undocumented)
function compareWith<T, U = T>(a: ReadonlyArray<T>, b: Iterable_2<U>, comparer: Comparer<T, U, [index: number]>): Comparison;
function compareWith<T>(a: ReadonlyArray<T>, b: Iterable_2<T>, comparer: Comparer<T>): Comparison;
// (undocumented)
function concat<T>(array: ReadonlyArray<T>, ...iterables: Array_2<Iterable_2<T>>): Array_2<T>;
// (undocumented)
Expand Down Expand Up @@ -134,6 +134,8 @@ namespace Array_2 {
// (undocumented)
function zip<T, U = T>(array: ReadonlyArray<T>, iterable: Iterable_2<U>): Array_2<[T, U]>;
}

export { Array_2 as Array }


```
9 changes: 4 additions & 5 deletions docs/review/api/alfa-branched.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ export class Branched<T, B = never> implements Collection<T>, Iterable_2<[T, Ite
// (undocumented)
flatMap<U>(mapper: Mapper<T, Branched<U, B>, [Iterable_2<B>]>): Branched<U, B>;
// (undocumented)
flatten<T, B>(this: Branched<Branched<T, B>, B>): Branched<T, B>;
// (undocumented)
forEach(callback: Callback<T, void, [Iterable_2<B>]>): void;
// (undocumented)
hash(hash: Hash): void;
Expand Down Expand Up @@ -77,7 +75,7 @@ export class Branched<T, B = never> implements Collection<T>, Iterable_2<[T, Ite
toArray(): Array<[T, Array<B>]>;
// (undocumented)
toJSON(): Branched.JSON<T, B>;
}
}

// @public (undocumented)
export namespace Branched {
Expand All @@ -87,15 +85,16 @@ export namespace Branched {
export function isBranched<T, B = never>(value: unknown): value is Branched<T, B>;
// (undocumented)
export type JSON<T, B = never> = Array<[
Serializable.ToJSON<T>,
Array<Serializable.ToJSON<B>>
Serializable.ToJSON<T>,
Array<Serializable.ToJSON<B>>
]>;
// (undocumented)
export function sequence<T, B>(values: Iterable_2<Branched<T, B>>): Branched<Iterable_2<T>, B>;
// (undocumented)
export function traverse<T, U, B>(values: Iterable_2<T>, mapper: Mapper<T, Branched<U, B>, [index: number]>): Branched<Iterable_2<U>, B>;
}


// (No @packageDocumentation comment for this package)

```
Loading