Spec-Zone.ru › Immutable.js

Коллекция

Collection представляет собой набор записей (ключ, значение), по которым можно итерироваться, и является базовым классом для всех коллекций в immutable, позволяя им использовать все методы Collection (например, map и filter).

type Collection<K, V> extends ValueObject

Обсуждение

Примечание: Коллекция всегда итерируется в одном и том же порядке, однако этот порядок не всегда может быть однозначно определён, как это происходит в случае с Map и Set.

Collection — это абстрактный базовый класс для конкретных структур данных. Его нельзя создать напрямую.

Реализации должны расширять один из подклассов, Collection.Keyed, Collection.Indexed, или Collection.Set.

Создание

Collection()

Collection<I>(collection: I): I
Collection<T>(collection: Iterable<T> | ArrayLike<T>): Collection.Indexed<T>
Collection<V>(obj: {[key: string]: V}): Collection.Keyed<string, V>
Collection<K, V>(): Collection<K, V>

Равенство значений

equals()

Возвращает true, если эта и другая Collection имеют равенство значений, как определено в Immutable.is().

equals(other: unknown): boolean

Переопределяет

ValueObject#equals()

Обсуждение

Примечание: Это эквивалентно Immutable.is(this, other), но предоставлено для возможности цепочечных выражений.

hashCode()

Вычисляет и возвращает хешированную идентичность этой Collection.

hashCode(): number

Переопределяет

ValueObject#hashCode()

Обсуждение

Хеш-код Collection используется для определения потенциального равенства и применяется при добавлении в Set или в качестве ключа в Map, что позволяет выполнять поиск с помощью другого экземпляра.

const a = List([ 1, 2, 3 ]);
const b = List([ 1, 2, 3 ]);
assert.notStrictEqual(a, b); // different instances
const set = Set([ a ]);
assert.equal(set.has(b), true);run it

Если у двух значений одинаковый хеш-код, они не гарантированно равны. Если у двух значений разные хеш-коды, они не могут быть равны.

Чтение значений

get()

get<NSV>(key: K, notSetValue: NSV): V | NSV
get(key: K): V | undefined

has()

Возвращает true, если ключ существует в этой Collection, используя Immutable.is для определения равенства.

has(key: K): boolean

includes()

Возвращает true, если значение существует в этой Collection, используя Immutable.is для определения равенства.

includes(value: V): boolean

Псевдоним

contains()

first()

Если Collection не пуста, возвращает первый элемент Collection. Если Collection пуста, возвращает необязательное значение по умолчанию, если оно предоставлено; в противном случае возвращает undefined.

first<NSV>(notSetValue?: NSV): V | NSV

last()

Если Collection не пуста, возвращает последний элемент Collection. Если Collection пуста, возвращает необязательное значение по умолчанию, если оно предоставлено; в противном случае возвращает undefined.

last<NSV>(notSetValue?: NSV): V | NSV

Чтение глубоких значений

getIn()

Возвращает значение, найденное по пути ключей или индексов через вложенные коллекции.

getIn(searchKeyPath: Iterable<unknown>, notSetValue?: unknown): unknown

Обсуждение

const { Map, List } = require('immutable')
const deepData = Map({ x: List([ Map({ y: 123 }) ]) });
deepData.getIn(['x', 0, 'y']) // 123run it

Простые JavaScript объекты или массивы могут быть вложены внутри Immutable.js Collection, и getIn() может получить доступ к этим значениям:

const { Map, List } = require('immutable')
const deepData = Map({ x: [ { y: 123 } ] });
deepData.getIn(['x', 0, 'y']) // 123run it

hasIn()

Возвращает true, если результат следования по пути ключей или индексов через вложенные коллекции приводит к установленному значению.

hasIn(searchKeyPath: Iterable<unknown>): boolean

Постоянные изменения

update()

Это может быть очень полезно как способ «цеплять» обычную функцию в последовательность методов. RxJS называет это «let», а lodash — «thru».

update<R>(updater: (value: this) => R): R

Обсуждение

Например, чтобы подсчитать сумму Seq после применения map и filter:

const { Seq } = require('immutable')

function sum(collection) {
  return collection.reduce((sum, x) => sum + x, 0)
}
Seq([ 1, 2, 3 ])
  .map(x => x + 1)
  .filter(x => x % 2 === 0)
  .update(sum)
// 6run it

Преобразование в типы JavaScript

toJS()

Глубоко преобразует эту Collection в эквивалентный native JavaScript массив или объект.

toJS(): Array<DeepCopy<V>> | {[key: string]: DeepCopy<V>}

Обсуждение

Collection.Indexed, и Collection.Set становятся Array, в то время как Collection.Keyed становятся Object, преобразуя ключи в строки.

toJSON()

Поверхностно преобразует эту Collection в эквивалентный native JavaScript массив или объект.

toJSON(): Array<V> | {[key: string]: V}

Обсуждение

Collection.Indexed, и Collection.Set становятся Array, в то время как Collection.Keyed становятся Object, преобразуя ключи в строки.

toArray()

Поверхностно преобразует эту коллекцию в массив.

toArray(): Array<V> | Array<[K, V]>

Обсуждение

Collection.Indexed, и Collection.Set создают массив значений. Collection.Keyed создают массив пар [ключ, значение].

toObject()

Поверхностно преобразует эту Collection в объект.

toObject(): {[key: string]: V}

Обсуждение

Преобразует ключи в строки.

Преобразование в коллекции

toMap()

Преобразует эту Collection в Map. Бросает исключение, если ключи не хешируемы.

toMap(): Map<K, V>

Обсуждение

Примечание: Это эквивалентно Map(this.toKeyedSeq()), но предоставлено для удобства и возможности цепочечных выражений.

toOrderedMap()

Преобразует эту Collection в Map, сохраняя порядок итерации.

toOrderedMap(): OrderedMap<K, V>

Обсуждение

Примечание: Это эквивалентно OrderedMap(this.toKeyedSeq()), но предоставлено для удобства и возможности цепочечных выражений.

toSet()

Преобразует эту Collection в Set, отбрасывая ключи. Бросает исключение, если значения не хешируемы.

toSet(): Set<V>

Обсуждение

Примечание: Это эквивалентно Set(this), но предоставлено для возможности цепочечных выражений.

toOrderedSet()

Преобразует эту Collection в Set, сохраняя порядок итерации и отбрасывая ключи.

toOrderedSet(): OrderedSet<V>

Обсуждение

Примечание: Это эквивалентно OrderedSet(this.valueSeq()), но предоставлено для удобства и возможности цепочечных выражений.

toList()

Преобразует эту Collection в List, отбрасывая ключи.

toList(): List<V>

Обсуждение

Это аналогично List(collection), но предоставлено для возможности цепочечных выражений. Однако, при вызове на Map или других коллекциях с ключами, collection.toList() отбрасывает ключи и создаёт список только значений, в то время как List(collection) создаёт список кортежей пар.

const { Map, List } = require('immutable')
var myMap = Map({ a: 'Apple', b: 'Banana' })
List(myMap) // List [ [ "a", "Apple" ], [ "b", "Banana" ] ]
myMap.toList() // List [ "Apple", "Banana" ]run it

toStack()

Преобразует эту Collection в Stack, отбрасывая ключи. Бросает исключение, если значения не хешируемы.

toStack(): Stack<V>

Обсуждение

Примечание: Это эквивалентно Stack(this), но предоставлено для возможности цепочечных выражений.

Преобразование в Seq

toSeq()

Преобразует эту Collection в Seq того же типа (индексированный, с ключами или множество).

toSeq(): Seq<K, V>

toKeyedSeq()

Возвращает Seq.Keyed из этой Collection, где индексы обрабатываются как ключи.

toKeyedSeq(): Seq.Keyed<K, V>

Обсуждение

Это полезно, если вы хотите работать с Collection.Indexed и сохранить пары [индекс, значение].

Возвращаемый Seq будет иметь тот же порядок итерации, что и эта Collection.

const { Seq } = require('immutable')
const indexedSeq = Seq([ 'A', 'B', 'C' ])
// Seq [ "A", "B", "C" ]
indexedSeq.filter(v => v === 'B')
// Seq [ "B" ]
const keyedSeq = indexedSeq.toKeyedSeq()
// Seq { 0: "A", 1: "B", 2: "C" }
keyedSeq.filter(v => v === 'B')
// Seq { 1: "B" }run it

toIndexedSeq()

Возвращает Seq.Indexed из значений этой Collection, отбрасывая ключи.

toIndexedSeq(): Seq.Indexed<V>

toSetSeq()

Возвращает Seq.Set из значений этой Collection, отбрасывая ключи.

toSetSeq(): Seq.Set<V>

Итераторы

keys()

Итератор ключей этой Collection.

keys(): IterableIterator<K>

Обсуждение

Примечание: это вернёт итератор ES6, который не поддерживает алгоритмы последовательностей Immutable.js. Используйте keySeq вместо этого, если это то, что вам нужно.

values()

Итератор значений этой Collection.

values(): IterableIterator<V>

Обсуждение

Примечание: это вернёт итератор ES6, который не поддерживает алгоритмы последовательностей Immutable.js. Используйте valueSeq вместо этого, если это то, что вам нужно.

entries()

Итератор пар [ключ, значение] этой Collection в виде кортежей [ key, value ].

entries(): IterableIterator<[K, V]>

Обсуждение

Примечание: это вернёт итератор ES6, который не поддерживает алгоритмы последовательностей Immutable.js. Используйте entrySeq вместо этого, если это то, что вам нужно.

[Symbol.iterator]()

[Symbol.iterator](): IterableIterator<unknown>

Коллекции (Seq)

keySeq()

Возвращает новый Seq.Indexed ключей этой Collection, отбрасывая значения.

keySeq(): Seq.Indexed<K>

valueSeq()

Возвращает Seq.Indexed значений этой Collection, отбрасывая ключи.

valueSeq(): Seq.Indexed<V>

entrySeq()

Возвращает новый Seq.Indexed кортежей [ключ, значение].

entrySeq(): Seq.Indexed<[K, V]>

Алгоритмы последовательностей

map()

Возвращает новую коллекцию того же типа со значениями, прошедшими через функцию mapper.

map<M>(mapper: (value: V, key: K, iter: this) => M,context?: unknown): Collection<K, M>

Обсуждение

const { Collection } = require('immutable')
Collection({ a: 1, b: 2 }).map(x => 10 * x)
// Seq { "a": 10, "b": 20 }run it

Примечание: map() всегда возвращает новый экземпляр, даже если на каждом шаге генерировалось одинаковое значение.

filter()

filter<F>(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): Collection<K, F>
filter(predicate: (value: V, key: K, iter: this) => unknown,context?: unknown): this

filterNot()

Возвращает новую коллекцию того же типа только с записями, для которых функция predicate возвращает false.

filterNot(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): this

Обсуждение

const { Map } = require('immutable')
Map({ a: 1, b: 2, c: 3, d: 4}).filterNot(x => x % 2 === 0)
// Map { "a": 1, "c": 3 }run it

Примечание: filterNot() всегда возвращает новый экземпляр, даже если в результате не отфильтровано ни одного значения.

partition()

partition<F, C>(predicate: (this: C, value: V, key: K, iter: this) => boolean,context?: C): [Collection<K, V>, Collection<K, F>]
partition<C>(predicate: (this: C, value: V, key: K, iter: this) => unknown,context?: C): [this, this]

reverse()

Возвращает новую коллекцию того же типа в обратном порядке.

reverse(): this

sort()

Возвращает новую коллекцию того же типа, содержащую те же записи, устойчиво отсортированные с использованием comparator.

sort(comparator?: (valueA: V, valueB: V) => number): this

Обсуждение

Если comparator не предоставлен, используется по умолчанию компаратор, применяющий < и >.

comparator(valueA, valueB):

  • Возвращает 0 если элементы не должны быть поменяны местами.
  • Возвращает -1 (или любое отрицательное число), если valueA предшествует valueB
  • Возвращает 1 (или любое положительное число), если valueA следует за valueB
  • Является чистым, т.е. всегда возвращает одно и то же значение для одной и той же пары значений.

При сортировке коллекций, не имеющих определенного порядка, возвращаются их упорядоченные эквиваленты. Например, map.sort() возвращает OrderedMap.

const { Map } = require('immutable')
Map({ "c": 3, "a": 1, "b": 2 }).sort((a, b) => {
  if (a < b) { return -1; }
  if (a > b) { return 1; }
  if (a === b) { return 0; }
});
// OrderedMap { "a": 1, "b": 2, "c": 3 }run it

Примечание: sort() всегда возвращает новый экземпляр, даже если исходный уже был отсортирован.

Примечание: Это всегда операция с немедленным выполнением.

sortBy()

Как sort, но также принимает comparatorValueMapper, что позволяет сортировать более сложными способами:

sortBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C,comparator?: (valueA: C, valueB: C) => number): this

Обсуждение

const { Map } = require('immutable')
const beattles = Map({
  John: { name: "Lennon" },
  Paul: { name: "McCartney" },
  George: { name: "Harrison" },
  Ringo: { name: "Starr" },
});
beattles.sortBy(member => member.name);run it

Примечание: sortBy() всегда возвращает новый экземпляр, даже если исходный уже был отсортирован.

Примечание: Это всегда операция с немедленным выполнением.

groupBy()

Возвращает Collection.Keyed из Collection.Keyeds, сгруппированных по возвращаемому значению функции grouper.

groupBy<G>(grouper: (value: V, key: K, iter: this) => G,context?: unknown): Seq.Keyed<G, Collection<K, V>>

Обсуждение

Примечание: Это всегда операция с немедленным выполнением.

const { List, Map } = require('immutable')
const listOfMaps = List([
  Map({ v: 0 }),
  Map({ v: 1 }),
  Map({ v: 1 }),
  Map({ v: 0 }),
  Map({ v: 2 })
])
const groupsOfMaps = listOfMaps.groupBy(x => x.get('v'))
// Map {
//   0: List [ Map{ "v": 0 }, Map { "v": 0 } ],
//   1: List [ Map{ "v": 1 }, Map { "v": 1 } ],
//   2: List [ Map{ "v": 2 } ],
// }run it

Побочные эффекты

forEach()

Функция sideEffect выполняется для каждой записи в коллекции.

forEach(sideEffect: (value: V, key: K, iter: this) => unknown,context?: unknown): number

Обсуждение

В отличие от Array#forEach, если любой вызов sideEffect возвращает false, итерация остановится. Возвращает количество итерированных записей (включая последнюю итерацию, которая вернула false).

Создание подмножеств

slice()

Возвращает новую коллекцию того же типа, представляющую часть этой коллекции с начала до, но не включая, конца.

slice(begin?: number, end?: number): this

Обсуждение

Если begin отрицательно, оно отсчитывается от конца коллекции. Например, slice(-2) возвращает коллекцию из двух последних записей. Если не указано, новая коллекция начнётся с начала этой коллекции.

Если end отрицательно, оно отсчитывается от конца коллекции. Например, slice(0, -1) возвращает коллекцию, за исключением последней записи. Если не указано, новая коллекция будет продолжаться до конца этой коллекции.

Если запрашиваемый срез эквивалентен текущей коллекции, возвращается сама коллекция.

rest()

Возвращает новую коллекцию того же типа, содержащую все записи, кроме первой.

rest(): this

butLast()

Возвращает новую коллекцию того же типа, содержащую все записи, кроме последней.

butLast(): this

skip()

Возвращает новую коллекцию того же типа, исключая первые amount записи из этой коллекции.

skip(amount: number): this

skipLast()

Возвращает новую коллекцию того же типа, исключая последние amount записи из этой коллекции.

skipLast(amount: number): this

skipWhile()

Возвращает новую коллекцию того же типа, содержащую записи, начиная с момента, когда predicate впервые вернёт false.

skipWhile(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): this

Обсуждение

const { List } = require('immutable')
List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
  .skipWhile(x => x.match(/g/))
// List [ "cat", "hat", "god" ]run it

skipUntil()

Возвращает новую коллекцию того же типа, содержащую записи, начиная с момента, когда predicate впервые вернёт true.

skipUntil(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): this

Обсуждение

const { List } = require('immutable')
List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
  .skipUntil(x => x.match(/hat/))
// List [ "hat", "god" ]run it

take()

Возвращает новую коллекцию того же типа, содержащую первые amount записи из этой коллекции.

take(amount: number): this

takeLast()

Возвращает новую коллекцию того же типа, содержащую последние amount записи из этой коллекции.

takeLast(amount: number): this

takeWhile()

Возвращает новую коллекцию того же типа, содержащую записи из этой коллекции, пока predicate возвращает true.

takeWhile(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): this

Обсуждение

const { List } = require('immutable')
List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
  .takeWhile(x => x.match(/o/))
// List [ "dog", "frog" ]run it

takeUntil()

Возвращает новую коллекцию того же типа, содержащую записи из этой коллекции, пока predicate возвращает false.

takeUntil(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): this

Обсуждение

const { List } = require('immutable')
List([ 'dog', 'frog', 'cat', 'hat', 'god' ])
  .takeUntil(x => x.match(/at/))
// List [ "dog", "frog" ]run it

Комбинирование

concat()

Возвращает новую коллекцию того же типа со значениями и подобными коллекциями, конкатенированными с этой.

concat(...valuesOrCollections: Array<unknown>): Collection<unknown, unknown>

Обсуждение

Для Seqs все записи будут присутствовать в результирующем Seq, даже если у них одинаковые ключи.

flatten()

flatten(depth?: number): Collection<unknown, unknown>
flatten(shallow?: boolean): Collection<unknown, unknown>

flatMap()

Выполняет плоское отображение коллекции, возвращая коллекцию того же типа.

flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>,context?: unknown): Collection<K, M>
flatMap<KM, VM>(mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>,context?: unknown): Collection<KM, VM>

Обсуждение

Аналогично collection.map(...).flatten(true). Используется только для словарей.

Сведение значения

reduce()

reduce<R>(reducer: (reduction: R, value: V, key: K, iter: this) => R,initialReduction: R,context?: unknown): R
reduce<R>(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R

reduceRight()

reduceRight<R>(reducer: (reduction: R, value: V, key: K, iter: this) => R,initialReduction: R,context?: unknown): R
reduceRight<R>(reducer: (reduction: V | R, value: V, key: K, iter: this) => R): R

every()

Истина, если predicate возвращает true для всех записей в коллекции.

every(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): boolean

some()

Истина, если predicate возвращает true для любой записи в коллекции.

some(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): boolean

join()

Объединяет значения в строку, вставляя разделитель между каждым. По умолчанию разделитель ",".

join(separator?: string): string

isEmpty()

Возвращает true, если эта коллекция не содержит значений.

isEmpty(): boolean

Обсуждение

Для некоторых ленивых Seq, isEmpty может потребоваться выполнить итерацию, чтобы определить пустоту. Будет выполнена не более одной итерации.

count()

count(): number
count(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): number

countBy()

Возвращает Seq.Keyed подсчётов, сгруппированных по возвращаемому значению функции grouper.

countBy<G>(grouper: (value: V, key: K, iter: this) => G,context?: unknown): Map<G, number>

Обсуждение

Примечание: Это не ленивая операция.

Поиск значения

find()

Возвращает первое значение, для которого predicate возвращает true.

find(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown,notSetValue?: V): V | undefined

findLast()

Возвращает последнее значение, для которого predicate возвращает true.

findLast(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown,notSetValue?: V): V | undefined

Обсуждение

Примечание: predicate будет вызываться для каждой записи в обратном порядке.

findEntry()

Возвращает первую запись [ключ, значение], для которой predicate возвращает true.

findEntry(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown,notSetValue?: V): [K, V] | undefined

findLastEntry()

Возвращает последнюю запись [ключ, значение], для которой predicate возвращает true.

findLastEntry(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown,notSetValue?: V): [K, V] | undefined

Обсуждение

Примечание: predicate будет вызываться для каждой записи в обратном порядке.

findKey()

Возвращает ключ, для которого predicate возвращает true.

findKey(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): K | undefined

findLastKey()

Возвращает последний ключ, для которого predicate возвращает true.

findLastKey(predicate: (value: V, key: K, iter: this) => boolean,context?: unknown): K | undefined

Обсуждение

Примечание: predicate будет вызываться для каждой записи в обратном порядке.

END_OF_DOCUMENT_MARKER

keyOf()

Возвращает ключ, связанный со значением поиска, или undefined.

keyOf(searchValue: V): K | undefined

lastKeyOf()

Возвращает последний ключ, связанный со значением поиска, или undefined.

lastKeyOf(searchValue: V): K | undefined

max()

Возвращает максимальное значение в этом наборе. Если какие-либо значения сравнимы по величине, будет возвращено первое из них.

max(comparator?: (valueA: V, valueB: V) => number): V | undefined

Обсуждение

comparator используется так же, как Collection#sort. Если он не задан, используется по умолчанию >.

Если два значения считаются эквивалентными, будет возвращено первое из них. В противном случае, max будет работать независимо от порядка ввода, при условии, что компаратор коммутативен. По умолчанию > коммутативен только тогда, когда типы не отличаются.

Если comparator возвращает 0, и любое из значений равно NaN, undefined или null, будет возвращено это значение.

maxBy()

Аналогично max, но также принимает comparatorValueMapper, что позволяет сравнивать значения более сложными способами:

maxBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C,comparator?: (valueA: C, valueB: C) => number): V | undefined

Обсуждение

const { List, } = require('immutable');
const l = List([
  { name: 'Bob', avgHit: 1 },
  { name: 'Max', avgHit: 3 },
  { name: 'Lili', avgHit: 2 } ,
]);
l.maxBy(i => i.avgHit); // will output { name: 'Max', avgHit: 3 }run it

min()

Возвращает минимальное значение в этом наборе. Если какие-либо значения сравнимы по величине, будет возвращено первое из них.

min(comparator?: (valueA: V, valueB: V) => number): V | undefined

Обсуждение

comparator используется так же, как Collection#sort. Если он не задан, используется по умолчанию <.

Если два значения считаются эквивалентными, будет возвращено первое из них. В противном случае, min будет работать независимо от порядка ввода, при условии, что компаратор коммутативен. По умолчанию < коммутативен только тогда, когда типы не отличаются.

Если comparator возвращает 0, и любое из значений равно NaN, undefined или null, будет возвращено это значение.

minBy()

Аналогично min, но также принимает comparatorValueMapper, что позволяет сравнивать значения более сложными способами:

minBy<C>(comparatorValueMapper: (value: V, key: K, iter: this) => C,comparator?: (valueA: C, valueB: C) => number): V | undefined

Обсуждение

const { List, } = require('immutable');
const l = List([
  { name: 'Bob', avgHit: 1 },
  { name: 'Max', avgHit: 3 },
  { name: 'Lili', avgHit: 2 } ,
]);
l.minBy(i => i.avgHit); // will output { name: 'Bob', avgHit: 1 }run it

Сравнение

isSubset()

True, если iter содержит каждое значение в этом наборе.

isSubset(iter: Iterable<V>): boolean

isSuperset()

True, если этот набор содержит каждое значение в iter.

isSuperset(iter: Iterable<V>): boolean
Данная документация сгенерирована из immutable.d.ts. Приветствуются pull запросы и вопросы.

© 2014–present, Lee Byron and other contributors
Licensed under the 3-clause BSD License.
https://immutable-js.com/docs/v4.2.1/Collection/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API