tutuca 0.9.39 → 0.9.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tutuca-cli.js +92 -39
- package/dist/tutuca-dev.js +18 -0
- package/dist/tutuca-dev.min.js +1 -1
- package/package.json +6 -7
- package/skill/immutable-js/SKILL.md +79 -0
- package/skill/immutable-js/references/collection.md +346 -0
- package/skill/immutable-js/references/conversions.md +99 -0
- package/skill/immutable-js/references/deep-updates.md +172 -0
- package/skill/immutable-js/references/equality.md +95 -0
- package/skill/immutable-js/references/list.md +266 -0
- package/skill/immutable-js/references/map.md +300 -0
- package/skill/immutable-js/references/predicates.md +93 -0
- package/skill/immutable-js/references/range-repeat.md +55 -0
- package/skill/immutable-js/references/record.md +196 -0
- package/skill/immutable-js/references/seq.md +248 -0
- package/skill/immutable-js/references/set.md +270 -0
- package/skill/immutable-js/references/shallow-functional.md +99 -0
- package/skill/immutable-js/references/stack.md +210 -0
- package/skill/margaui/SKILL.md +101 -0
- package/skill/margaui/components/accordion.md +127 -0
- package/skill/margaui/components/alert.md +174 -0
- package/skill/margaui/components/avatar.md +220 -0
- package/skill/margaui/components/badge.md +193 -0
- package/skill/margaui/components/breadcrumbs.md +103 -0
- package/skill/margaui/components/button.md +322 -0
- package/skill/margaui/components/calendar.md +67 -0
- package/skill/margaui/components/card.md +373 -0
- package/skill/margaui/components/carousel.md +387 -0
- package/skill/margaui/components/chat.md +171 -0
- package/skill/margaui/components/checkbox.md +101 -0
- package/skill/margaui/components/collapse.md +172 -0
- package/skill/margaui/components/countdown.md +165 -0
- package/skill/margaui/components/diff.md +53 -0
- package/skill/margaui/components/divider.md +107 -0
- package/skill/margaui/components/dock.md +173 -0
- package/skill/margaui/components/drawer.md +184 -0
- package/skill/margaui/components/dropdown.md +388 -0
- package/skill/margaui/components/fab.md +346 -0
- package/skill/margaui/components/fieldset.md +88 -0
- package/skill/margaui/components/file-input.md +84 -0
- package/skill/margaui/components/filter.md +52 -0
- package/skill/margaui/components/footer.md +583 -0
- package/skill/margaui/components/hero.md +135 -0
- package/skill/margaui/components/hover-3d.md +129 -0
- package/skill/margaui/components/hover-gallery.md +49 -0
- package/skill/margaui/components/indicator.md +265 -0
- package/skill/margaui/components/input.md +389 -0
- package/skill/margaui/components/join.md +100 -0
- package/skill/margaui/components/kbd.md +127 -0
- package/skill/margaui/components/label.md +102 -0
- package/skill/margaui/components/link.md +96 -0
- package/skill/margaui/components/list.md +182 -0
- package/skill/margaui/components/loading.md +105 -0
- package/skill/margaui/components/mask.md +168 -0
- package/skill/margaui/components/menu.md +856 -0
- package/skill/margaui/components/mockup-browser.md +39 -0
- package/skill/margaui/components/mockup-code.md +81 -0
- package/skill/margaui/components/mockup-phone.md +39 -0
- package/skill/margaui/components/mockup-window.md +33 -0
- package/skill/margaui/components/modal.md +178 -0
- package/skill/margaui/components/navbar.md +282 -0
- package/skill/margaui/components/pagination.md +122 -0
- package/skill/margaui/components/progress.md +135 -0
- package/skill/margaui/components/radial-progress.md +67 -0
- package/skill/margaui/components/radio.md +133 -0
- package/skill/margaui/components/range.md +134 -0
- package/skill/margaui/components/rating.md +170 -0
- package/skill/margaui/components/select.md +225 -0
- package/skill/margaui/components/skeleton.md +64 -0
- package/skill/margaui/components/stack.md +142 -0
- package/skill/margaui/components/stat.md +254 -0
- package/skill/margaui/components/status.md +73 -0
- package/skill/margaui/components/steps.md +138 -0
- package/skill/margaui/components/swap.md +152 -0
- package/skill/margaui/components/tab.md +248 -0
- package/skill/margaui/components/table.md +1018 -0
- package/skill/margaui/components/text-rotate.md +91 -0
- package/skill/margaui/components/textarea.md +85 -0
- package/skill/margaui/components/theme-controller.md +266 -0
- package/skill/margaui/components/timeline.md +1356 -0
- package/skill/margaui/components/toast.md +165 -0
- package/skill/margaui/components/toggle.md +135 -0
- package/skill/margaui/components/tooltip.md +181 -0
- package/skill/margaui/components/validator.md +163 -0
- package/skill/{advanced.md → tutuca/advanced.md} +5 -0
- package/skill/{cli.md → tutuca/cli.md} +17 -0
- package/skill/{core.md → tutuca/core.md} +5 -0
- /package/skill/{SKILL.md → tutuca/SKILL.md} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tutuca",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Zero-dependency SPA framework with immutable state and virtual DOM",
|
|
6
6
|
"main": "./dist/tutuca.js",
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
"dist": "bun scripts/dist.js",
|
|
21
21
|
"dist-immutable": "bun scripts/dist-immutable.js",
|
|
22
22
|
"dist-all": "bun run dist-immutable && bun run dist",
|
|
23
|
-
"release": "bun run dist-all && bun run build-skill && npm publish --access public",
|
|
24
|
-
"release-dry": "bun run dist-all && bun run build-skill && npm publish --dry-run",
|
|
23
|
+
"release": "bun run dist-all && bun run build-skill && bun run build-margaui-skill && bun run build-immutable-skill && npm publish --access public",
|
|
24
|
+
"release-dry": "bun run dist-all && bun run build-skill && bun run build-margaui-skill && bun run build-immutable-skill && npm publish --dry-run",
|
|
25
25
|
"build-skill": "bun scripts/build-skill.js",
|
|
26
|
+
"build-margaui-skill": "bun scripts/build-margaui-skill.js",
|
|
27
|
+
"build-immutable-skill": "bun scripts/build-immutable-skill.js",
|
|
26
28
|
"test": "bun test test/*.test.js",
|
|
27
29
|
"test-watch": "bun test --watch test/*.test.js",
|
|
28
30
|
"format": "bunx @biomejs/biome format --write src test/*.js docs/src/*.js docs/examples/*.js tools/*.js tools/*/*.js",
|
|
@@ -42,10 +44,7 @@
|
|
|
42
44
|
"dist/tutuca-extra.js",
|
|
43
45
|
"dist/tutuca-extra.min.js",
|
|
44
46
|
"dist/tutuca-cli.js",
|
|
45
|
-
"skill
|
|
46
|
-
"skill/core.md",
|
|
47
|
-
"skill/cli.md",
|
|
48
|
-
"skill/advanced.md"
|
|
47
|
+
"skill"
|
|
49
48
|
],
|
|
50
49
|
"dependencies": {
|
|
51
50
|
"jsdom": "^28.0.0 || ^29.0.0"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: immutable-js
|
|
3
|
+
description: Reference for the Immutable.js API organized by datatype (List, Map, Set, OrderedMap, OrderedSet, Stack, Record, Seq, Collection, Range, Repeat) and by topic (deep updates, equality, type predicates, JS conversion). Use when the user asks how to use a specific Immutable.js datatype or method, when writing or reviewing code in this repository, or when explaining Immutable.js semantics like persistent updates, value equality, or lazy evaluation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Immutable.js
|
|
7
|
+
|
|
8
|
+
Persistent immutable data structures for JavaScript. All operations return a
|
|
9
|
+
new collection rather than mutating the original; structural sharing keeps
|
|
10
|
+
this efficient. Treat collections as **values**, not objects — compare with
|
|
11
|
+
`is(a, b)` or `a.equals(b)`, never `===`.
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { Map } from 'immutable';
|
|
15
|
+
const m1 = Map({ a: 1, b: 2 });
|
|
16
|
+
const m2 = m1.set('b', 50);
|
|
17
|
+
m1.get('b'); // 2 — m1 is unchanged
|
|
18
|
+
m2.get('b'); // 50
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Inheritance cheatsheet
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Collection ─┬─ Collection.Keyed ─┬─ Map ── OrderedMap
|
|
25
|
+
│ └─ Record (object-like, fixed keys)
|
|
26
|
+
│
|
|
27
|
+
├─ Collection.Indexed ─┬─ List
|
|
28
|
+
│ └─ Stack
|
|
29
|
+
│
|
|
30
|
+
└─ Collection.Set ─┬─ Set ── OrderedSet
|
|
31
|
+
└─ (OrderedCollection marker)
|
|
32
|
+
|
|
33
|
+
Seq mirrors the hierarchy lazily:
|
|
34
|
+
Seq ─┬─ Seq.Keyed ─ keyed lazy sequence
|
|
35
|
+
├─ Seq.Indexed ─ indexed lazy sequence
|
|
36
|
+
└─ Seq.Set ─ set-like lazy sequence
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Datatypes
|
|
40
|
+
|
|
41
|
+
Read the reference for a specific datatype when answering questions about
|
|
42
|
+
its constructors, methods, or semantics.
|
|
43
|
+
|
|
44
|
+
- [List](references/list.md) — ordered indexed collection (push/pop/get/set/etc.)
|
|
45
|
+
- [Map](references/map.md) — keyed collection with value-equality keys; covers OrderedMap
|
|
46
|
+
- [Set](references/set.md) — unique values with value equality; covers OrderedSet
|
|
47
|
+
- [Stack](references/stack.md) — LIFO; fast push/pop/peek at the front
|
|
48
|
+
- [Record](references/record.md) — fixed-shape, named, typed record; class-like
|
|
49
|
+
- [Seq](references/seq.md) — lazy sequence (Keyed / Indexed / Set variants)
|
|
50
|
+
- [Collection](references/collection.md) — abstract base; methods shared by all collections
|
|
51
|
+
- [Range, Repeat](references/range-repeat.md) — lazy generator factories
|
|
52
|
+
|
|
53
|
+
## Operations and topics
|
|
54
|
+
|
|
55
|
+
Cross-cutting topics. Load these alongside (or instead of) a datatype reference
|
|
56
|
+
when the question is about an operation rather than a single type.
|
|
57
|
+
|
|
58
|
+
- [Deep updates](references/deep-updates.md) — `getIn`, `setIn`, `updateIn`, `removeIn`, `hasIn`, `merge`, `mergeWith`, `mergeDeep`, `mergeDeepWith`
|
|
59
|
+
- [Shallow functional helpers](references/shallow-functional.md) — top-level `get`, `set`, `has`, `update`, `remove` that work on any collection or plain JS object
|
|
60
|
+
- [JS conversions](references/conversions.md) — `fromJS`, `toJS`, plain-JS interop, reviver patterns
|
|
61
|
+
- [Equality and hashing](references/equality.md) — `is`, `hash`, `ValueObject`, `isValueObject`, value vs reference semantics
|
|
62
|
+
- [Type predicates](references/predicates.md) — `isList`, `isMap`, `isSet`, `isOrderedMap`, `isOrderedSet`, `isStack`, `isRecord`, `isSeq`, `isCollection`, `isKeyed`, `isIndexed`, `isAssociative`, `isOrdered`, `isImmutable`
|
|
63
|
+
|
|
64
|
+
## Cross-cutting semantics worth knowing up front
|
|
65
|
+
|
|
66
|
+
- **Value equality**: keys in `Map`/`Set` and elements in `Set` compare by `is()`, not `===`. Two distinct `Map({a:1})` instances are equal as keys.
|
|
67
|
+
- **Identity preservation**: an operation that produces an equal collection returns the original (`===`-identical), so memoization with `===` is sound.
|
|
68
|
+
- **Mutation batching**: `withMutations(c => { c.set(...).push(...) })` builds a transient copy; cheaper than chained calls when doing many updates.
|
|
69
|
+
- **Lazy `Seq`**: chained `map`/`filter`/etc. on a `Seq` doesn't run until something pulls values (e.g. `toList()`, `forEach`, iteration). See [seq.md](references/seq.md).
|
|
70
|
+
- **Path-based updates**: `setIn`/`updateIn`/`mergeDeep` create missing intermediate `Map`s by default. See [deep-updates.md](references/deep-updates.md).
|
|
71
|
+
- **`fromJS` is shallow-recursive**: arrays become `List`, plain objects become `Map`. Customize with the `reviver`. See [conversions.md](references/conversions.md).
|
|
72
|
+
|
|
73
|
+
## Authoritative sources in this repo
|
|
74
|
+
|
|
75
|
+
When a reference here is ambiguous or you need an exact signature, fall back to:
|
|
76
|
+
|
|
77
|
+
- `type-definitions/immutable.d.ts` — canonical TypeScript signatures for the entire public API
|
|
78
|
+
- `website/docs/<Name>.mdx` — the original long-form docs each reference here distills
|
|
79
|
+
- `README.md` — top-level rationale and worked examples
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
`Collection<K, V>` is the abstract base interface for every immutable iterable in immutable-js. You never construct a `Collection` directly — you construct one of the concrete types (`List`, `Map`, `Set`, `Stack`, `Seq`, `Record`) and use the methods documented here, all of which they inherit. Three sub-interfaces tailor the iteration shape: `Collection.Keyed<K, V>` yields `[K, V]` tuples, `Collection.Indexed<T>` yields values in numeric-index order, and `Collection.Set<T>` yields values (value-unique on concrete `Set`/`OrderedSet`). The `Collection(...)` factory is also a conversion function: returns an existing `Collection` unchanged, wraps an array-like as `Collection.Indexed`, wraps a plain object as `Collection.Keyed<string, V>`.
|
|
2
|
+
|
|
3
|
+
## Class hierarchy summary
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Collection
|
|
7
|
+
├─ Collection.Keyed → Map, OrderedMap, Record (and Seq.Keyed)
|
|
8
|
+
├─ Collection.Indexed → List, Stack (and Seq.Indexed)
|
|
9
|
+
└─ Collection.Set → Set, OrderedSet (and Seq.Set)
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`OrderedCollection<T>` is a marker interface (no own behaviour) mixed into every type with stable iteration order: `List`, `Stack`, `OrderedMap`, `OrderedSet`, every `Collection.Indexed`/`Seq.Indexed`, and any `Seq.Keyed` built from an ordered source. Detect at runtime with `isOrdered()`. There is no `OrderedCollection` value to construct.
|
|
13
|
+
|
|
14
|
+
## Reading
|
|
15
|
+
|
|
16
|
+
### size
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
readonly size: number | undefined;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Element count. Always defined on concrete types; may be `undefined` on a lazy `Seq` whose source has not been evaluated. Use `count()` for a guaranteed number.
|
|
23
|
+
|
|
24
|
+
### get
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
get(key: K): V | undefined;
|
|
28
|
+
get<NSV>(key: K, notSetValue: NSV): V | NSV;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Returns the value for `key`, or `notSetValue` (or `undefined`) if absent. On `Collection.Indexed`, `key` is a numeric index and negative values count from the end (`get(-1)` is last). Because a stored value may itself be `undefined`, prefer the two-arg form to disambiguate "missing" from "set to undefined".
|
|
32
|
+
|
|
33
|
+
### has / includes / contains
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
has(key: K): boolean;
|
|
37
|
+
includes(value: V): boolean;
|
|
38
|
+
contains(value: V): boolean; // alias of includes
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`has` checks key membership; `includes`/`contains` check value membership. Both use `Immutable.is` (deep value equality).
|
|
42
|
+
|
|
43
|
+
### first / last
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
first(): V | undefined;
|
|
47
|
+
first<NSV>(notSetValue: NSV): V | NSV;
|
|
48
|
+
last(): V | undefined;
|
|
49
|
+
last<NSV>(notSetValue: NSV): V | NSV;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
First/last value in iteration order, or the optional default if empty.
|
|
53
|
+
|
|
54
|
+
### getIn / hasIn
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
getIn(searchKeyPath: Iterable<unknown>, notSetValue?: unknown): unknown;
|
|
58
|
+
hasIn(searchKeyPath: Iterable<unknown>): boolean;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Walk a path of keys/indices through nested Immutable collections (and plain JS objects/arrays). See `nested-updates.md`.
|
|
62
|
+
|
|
63
|
+
## Sequence algorithms (return same kind of collection)
|
|
64
|
+
|
|
65
|
+
Most return a Collection of the same variant (`this`-typed where possible). For `Map`/`Set`, sorting/reversing returns the ordered counterpart (`OrderedMap`/`OrderedSet`).
|
|
66
|
+
|
|
67
|
+
### map / flatMap
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
map<M>(mapper: (value: V, key: K, iter: this) => M, context?: unknown): Collection<K, M>;
|
|
71
|
+
flatMap<M>(mapper: (value: V, key: K, iter: this) => Iterable<M>, context?: unknown): Collection<K, M>;
|
|
72
|
+
flatMap<KM, VM>(mapper: (value: V, key: K, iter: this) => Iterable<[KM, VM]>, context?: unknown): Collection<KM, VM>;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Always returns a new instance. `flatMap` is `map(...).flatten(true)`. On `Collection.Set` callbacks, `key === value`.
|
|
76
|
+
|
|
77
|
+
### filter / filterNot
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
filter(predicate: (value: V, key: K, iter: this) => unknown, context?: unknown): this;
|
|
81
|
+
filter<F extends V>(predicate: (value: V, key: K, iter: this) => value is F, context?: unknown): Collection<K, F>;
|
|
82
|
+
filterNot(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`filter` keeps truthy entries; `filterNot` keeps falsy ones. Type guards narrow the result.
|
|
86
|
+
|
|
87
|
+
### reverse / sort / sortBy
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
reverse(): this;
|
|
91
|
+
sort(comparator?: Comparator<V>): this;
|
|
92
|
+
sortBy<C>(mapper: (value: V, key: K, iter: this) => C, comparator?: Comparator<C>): this;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`comparator(a, b)` returns negative/zero/positive (or a `PairSorting` enum value) and must be pure. Sort is stable. On unordered collections (`Map`, `Set`), the result is the ordered counterpart. Always eager.
|
|
96
|
+
|
|
97
|
+
### slice / rest / butLast
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
slice(begin?: number, end?: number): this;
|
|
101
|
+
rest(): this; // all but first
|
|
102
|
+
butLast(): this; // all but last
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Negative slice indices count from the end. Returns the same instance if the slice is the whole collection.
|
|
106
|
+
|
|
107
|
+
### skip / skipLast / skipWhile / skipUntil / take / takeLast / takeWhile / takeUntil
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
skip(amount: number): this;
|
|
111
|
+
skipLast(amount: number): this;
|
|
112
|
+
skipWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
|
|
113
|
+
skipUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
|
|
114
|
+
take(amount: number): this;
|
|
115
|
+
takeLast(amount: number): this;
|
|
116
|
+
takeWhile(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
|
|
117
|
+
takeUntil(predicate: (value: V, key: K, iter: this) => boolean, context?: unknown): this;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`*While` keeps taking/skipping while predicate is true; `*Until` until it becomes true.
|
|
121
|
+
|
|
122
|
+
### concat / flatten
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
concat(...valuesOrCollections: Array<unknown>): Collection<unknown, unknown>;
|
|
126
|
+
flatten(depth?: number): Collection<unknown, unknown>;
|
|
127
|
+
flatten(shallow?: boolean): Collection<unknown, unknown>;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Concrete variants narrow `concat`'s return type — see the per-variant sections below. `flatten()` (no args) flattens deeply; `flatten(true)` flattens one level; `flatten(0)` flattens deeply. Only flattens nested Immutable Collections, not arrays/objects.
|
|
131
|
+
|
|
132
|
+
### groupBy / partition
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
groupBy<G>(grouper: (value: V, key: K, iter: this) => G, context?: unknown): Map<G, this>;
|
|
136
|
+
partition(predicate, context?): [this, this]; // [falsy, truthy]
|
|
137
|
+
partition<F extends V, C>(predicate: (...) => value is F, context?: C): [Collection<K, V>, Collection<K, F>];
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`groupBy` is eager and returns a `Map` of group key → Collection of the same variant. `partition` returns `[notMatching, matching]` in one pass.
|
|
141
|
+
|
|
142
|
+
## Side effects and reductions
|
|
143
|
+
|
|
144
|
+
### forEach
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
forEach(sideEffect: (value: V, key: K, iter: this) => unknown, context?: unknown): number;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Returns the number of iterations executed. Unlike `Array#forEach`, returning `false` from `sideEffect` aborts iteration.
|
|
151
|
+
|
|
152
|
+
### reduce / reduceRight
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
reduce<R>(reducer: (acc: R, value: V, key: K, iter: this) => R, initialReduction: R, context?: unknown): R;
|
|
156
|
+
reduce<R>(reducer): R; // first item is the initial reduction
|
|
157
|
+
reduceRight<R>(reducer, initialReduction: R, context?: unknown): R;
|
|
158
|
+
reduceRight<R>(reducer): R;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
`reduceRight` is `reverse().reduce(...)`.
|
|
162
|
+
|
|
163
|
+
### every / some / find* / keyOf*
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
every(predicate, context?: unknown): boolean;
|
|
167
|
+
some(predicate, context?: unknown): boolean;
|
|
168
|
+
|
|
169
|
+
find(predicate, context?, notSetValue?: V): V | undefined;
|
|
170
|
+
findLast(predicate, context?, notSetValue?: V): V | undefined;
|
|
171
|
+
findEntry(predicate, context?, notSetValue?: V): [K, V] | undefined;
|
|
172
|
+
findLastEntry(predicate, context?, notSetValue?: V): [K, V] | undefined;
|
|
173
|
+
findKey(predicate, context?): K | undefined;
|
|
174
|
+
findLastKey(predicate, context?): K | undefined;
|
|
175
|
+
|
|
176
|
+
keyOf(searchValue: V): K | undefined;
|
|
177
|
+
lastKeyOf(searchValue: V): K | undefined;
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
`*Last` variants iterate in reverse. `keyOf`/`lastKeyOf` look up by `Immutable.is` value equality; on `Collection.Indexed` prefer `indexOf`/`lastIndexOf` for clarity.
|
|
181
|
+
|
|
182
|
+
### max / maxBy / min / minBy
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
max(comparator?: Comparator<V>): V | undefined;
|
|
186
|
+
maxBy<C>(mapper: (value, key, iter) => C, comparator?: Comparator<C>): V | undefined;
|
|
187
|
+
min(comparator?: Comparator<V>): V | undefined;
|
|
188
|
+
minBy<C>(mapper: (value, key, iter) => C, comparator?: Comparator<C>): V | undefined;
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Default comparator is `>` / `<`. On ties, the first encountered wins.
|
|
192
|
+
|
|
193
|
+
### count / countBy / isEmpty / join
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
count(): number;
|
|
197
|
+
count(predicate, context?): number;
|
|
198
|
+
countBy<G>(grouper, context?): Map<G, number>;
|
|
199
|
+
isEmpty(): boolean;
|
|
200
|
+
join(separator?: string): string; // default ","
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`count()` always returns the actual size, even for a lazy `Seq` (forcing evaluation). `isEmpty` may iterate at most once on a lazy `Seq`.
|
|
204
|
+
|
|
205
|
+
### isSubset / isSuperset
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
isSubset(iter: Iterable<V>): boolean; // every value in this is in iter
|
|
209
|
+
isSuperset(iter: Iterable<V>): boolean; // every value in iter is in this
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Conversion
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
toArray(): Array<V> | Array<[K, V]>;
|
|
216
|
+
toObject(): { [key: string]: V };
|
|
217
|
+
toJS(): Array<DeepCopy<V>> | { [key: PropertyKey]: DeepCopy<V> };
|
|
218
|
+
toJSON(): Array<V> | { [key: PropertyKey]: V };
|
|
219
|
+
|
|
220
|
+
toList(): List<V>;
|
|
221
|
+
toMap(): Map<K, V>;
|
|
222
|
+
toOrderedMap(): OrderedMap<K, V>;
|
|
223
|
+
toSet(): Set<V>;
|
|
224
|
+
toOrderedSet(): OrderedSet<V>;
|
|
225
|
+
toStack(): Stack<V>;
|
|
226
|
+
|
|
227
|
+
toSeq(): Seq<K, V>;
|
|
228
|
+
toKeyedSeq(): Seq.Keyed<K, V>;
|
|
229
|
+
toIndexedSeq(): Seq.Indexed<V>;
|
|
230
|
+
toSetSeq(): Seq.Set<V>;
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`toJS` is deep (recursively converts nested Immutable structures); `toJSON`/`toArray`/`toObject` are shallow. `Collection.Keyed#toArray` returns `Array<[K, V]>`; `Collection.Indexed`/`Collection.Set#toArray` return `Array<V>`. `to{List,Set,OrderedSet,Stack}` discard keys; `toMap`/`toOrderedMap` throw if keys are not hashable. See `conversions.md`.
|
|
234
|
+
|
|
235
|
+
## Comparison
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
equals(other: unknown): boolean;
|
|
239
|
+
hashCode(): number;
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`equals` is `Immutable.is(this, other)` — deep value equality. `hashCode` is a stable Uint32; equal collections must produce equal hashes. See `equality.md`.
|
|
243
|
+
|
|
244
|
+
## Iteration
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
keys(): IterableIterator<K>;
|
|
248
|
+
values(): IterableIterator<V>;
|
|
249
|
+
entries(): IterableIterator<[K, V]>;
|
|
250
|
+
[Symbol.iterator](): IterableIterator<unknown>;
|
|
251
|
+
|
|
252
|
+
keySeq(): Seq.Indexed<K>;
|
|
253
|
+
valueSeq(): Seq.Indexed<V>;
|
|
254
|
+
entrySeq(): Seq.Indexed<[K, V]>;
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Default iteration shape per variant: `Keyed` yields `[K, V]` tuples; `Indexed` yields `V` in index order; `Set` yields `V` (value-unique on concrete `Set`). The `keys()`/`values()`/`entries()` methods return ES iterators (no chainable Immutable methods); `keySeq()`/`valueSeq()`/`entrySeq()` return `Seq.Indexed`s that you can chain.
|
|
258
|
+
|
|
259
|
+
### update
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
update<R>(updater: (value: this) => R): R;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Pipe the collection through a function — useful for chaining (`coll.update(fn).map(...)`). RxJS calls this `let`, lodash calls it `thru`.
|
|
266
|
+
|
|
267
|
+
## Variant-specific methods
|
|
268
|
+
|
|
269
|
+
### Collection.Keyed
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
flip(): Collection.Keyed<V, K>;
|
|
273
|
+
mapKeys<M>(mapper: (key: K, value: V, iter: this) => M, context?: unknown): Collection.Keyed<M, V>;
|
|
274
|
+
mapEntries<KM, VM>(
|
|
275
|
+
mapper: (entry: [K, V], index: number, iter: this) => [KM, VM] | undefined,
|
|
276
|
+
context?: unknown,
|
|
277
|
+
): Collection.Keyed<KM, VM>;
|
|
278
|
+
|
|
279
|
+
concat<KC, VC>(...collections: Array<Iterable<[KC, VC]>>): Collection.Keyed<K | KC, V | VC>;
|
|
280
|
+
concat<C>(...collections: Array<{ [key: string]: C }>): Collection.Keyed<K | string, V | C>;
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`flip` swaps keys and values. `mapEntries` may return `undefined` to drop that entry. Inherited `keyOf` returns the key associated with a value (not an index). When iterated, yields `[K, V]`.
|
|
284
|
+
|
|
285
|
+
### Collection.Indexed
|
|
286
|
+
|
|
287
|
+
Indices are 0-based and dense ("unset" and `undefined` are indistinguishable; iteration visits every index `0..size`). Negative indices count from the end.
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
indexOf(searchValue: T): number; // -1 if absent
|
|
291
|
+
lastIndexOf(searchValue: T): number;
|
|
292
|
+
findIndex(predicate, context?): number;
|
|
293
|
+
findLastIndex(predicate, context?): number;
|
|
294
|
+
|
|
295
|
+
interpose(separator: T): this; // T, sep, T, sep, T
|
|
296
|
+
interleave(...collections: Array<Collection<unknown, T>>): this; // round-robin; stops at shortest
|
|
297
|
+
splice(index: number, removeNum: number, ...values: Array<T>): this;
|
|
298
|
+
|
|
299
|
+
zip<U>(other: Collection<unknown, U>): Collection.Indexed<[T, U]>;
|
|
300
|
+
zip(...collections): Collection.Indexed<unknown>;
|
|
301
|
+
zipAll<U>(other: Collection<unknown, U>): Collection.Indexed<[T, U]>; // pads shorter with undefined
|
|
302
|
+
zipWith<U, Z>(zipper: (value: T, otherValue: U) => Z, other: Collection<unknown, U>): Collection.Indexed<Z>;
|
|
303
|
+
|
|
304
|
+
concat<C>(...valuesOrCollections: Array<Iterable<C> | C>): Collection.Indexed<T | C>;
|
|
305
|
+
fromEntrySeq(): Seq.Keyed<unknown, unknown>; // when T is [K, V], reinterpret as keyed
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`splice`, `interleave`, and other reindexing operations are `O(N)` and cannot be used inside `withMutations`. All `Collection.Indexed` methods return re-indexed Collections — to preserve original indices as keys, call `toKeyedSeq()`.
|
|
309
|
+
|
|
310
|
+
### Collection.Set
|
|
311
|
+
|
|
312
|
+
Iterates values; on the concrete `Set`/`OrderedSet`, values are unique (`Immutable.is`). On lazy `Seq.Set`, duplicates may be present. In callbacks, `key === value`.
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
concat<U>(...collections: Array<Iterable<U>>): Collection.Set<T | U>;
|
|
316
|
+
map<M>(mapper: (value: T, key: T, iter: this) => M, context?: unknown): Collection.Set<M>;
|
|
317
|
+
flatMap<M>(mapper: (value: T, key: T, iter: this) => Iterable<M>, context?: unknown): Collection.Set<M>;
|
|
318
|
+
filter<F extends T>(predicate: (value: T, key: T, iter: this) => value is F, context?: unknown): Collection.Set<F>;
|
|
319
|
+
filter(predicate, context?): this;
|
|
320
|
+
partition(predicate, context?): [this, this];
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
`union`, `intersect`, and `subtract` are NOT on `Collection.Set` — they live on the concrete `Set`/`OrderedSet`. See `set.md`.
|
|
324
|
+
|
|
325
|
+
## OrderedCollection
|
|
326
|
+
|
|
327
|
+
`OrderedCollection<T>` is a marker interface — it adds nothing beyond `toArray()` and `[Symbol.iterator]()` that every collection already has. Its purpose is purely type-level: it identifies collections whose iteration order is deterministic and stable across operations.
|
|
328
|
+
|
|
329
|
+
Implementers: `List`, `Stack`, `OrderedMap`, `OrderedSet`, every `Collection.Indexed` (so every `Seq.Indexed`), and any `Seq.Keyed` constructed from an ordered source. `Map` and `Set` are NOT ordered. Detect at runtime:
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
function isOrdered<T>(maybeOrdered: Collection<unknown, T>): maybeOrdered is OrderedCollection<T>;
|
|
333
|
+
function isOrdered(maybeOrdered: unknown): maybeOrdered is OrderedCollection<unknown>;
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
`KeyPath<K>` (used by `getIn`/`setIn`/etc.) is typed as `OrderedCollection<K> | ArrayLike<K>` — so any ordered Collection is a valid key path.
|
|
337
|
+
|
|
338
|
+
## See also
|
|
339
|
+
|
|
340
|
+
- `list.md`, `stack.md` — concrete `Collection.Indexed` types
|
|
341
|
+
- `map.md`, `record.md` — concrete `Collection.Keyed` types
|
|
342
|
+
- `set.md` — concrete `Collection.Set` types (`union`/`intersect`/`subtract` live here)
|
|
343
|
+
- `seq.md` — lazy `Seq.Keyed`/`Seq.Indexed`/`Seq.Set`
|
|
344
|
+
- `equality.md` — `equals`, `hashCode`, `Immutable.is`
|
|
345
|
+
- `conversions.md` — `toJS`/`fromJS`, `toArray`, cross-type `to*`
|
|
346
|
+
- `predicates.md` — `isCollection`, `isOrdered`, `isKeyed`, etc.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Immutable.js conversions go in two directions: PARSE plain JS into Immutable with `fromJS`, and PROJECT Immutable back to plain JS with `toJS` / `toJSON` / `toArray` / `toObject` / specific-type converters (`toList`, `toMap`, `toSet`, ...). Reach for `fromJS` when you receive JSON or other plain data at a boundary. Reach for `toJS` only at boundaries (serialization, debugging, libraries that don't speak Immutable) — passing Immutable values around inside your code is preferred since `toJS` is recursive and allocates a fresh deep copy.
|
|
2
|
+
|
|
3
|
+
## fromJS
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
fromJS(jsValue, reviver?: (key, sequence, path) => unknown): unknown
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Default behavior:
|
|
10
|
+
- Plain `Array` → `List`
|
|
11
|
+
- Plain `Object` (no custom prototype, own enumerable string keys) → `Map`
|
|
12
|
+
- Recurses into both
|
|
13
|
+
- Numbers, strings, booleans, `null`, `Date`, `RegExp`, JS `Map`/`Set`, custom class instances pass through unchanged
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import { fromJS } from 'immutable';
|
|
17
|
+
fromJS({ a: { b: [10, 20, 30] }, c: 40 });
|
|
18
|
+
// Map { a: Map { b: List [ 10, 20, 30 ] }, c: 40 }
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The optional `reviver` is called bottom-up (deepest collection first) with each level wrapped as a `Seq.Keyed` (for objects) or `Seq.Indexed` (for arrays). It must return an Immutable Collection. The default reviver is effectively:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
(key, value) => (isKeyed(value) ? value.toMap() : value.toList());
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Override it to choose different bucket types — e.g. `OrderedMap` + `List`:
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { fromJS, isKeyed } from 'immutable';
|
|
31
|
+
fromJS(payload, (_, value) =>
|
|
32
|
+
isKeyed(value) ? value.toOrderedMap() : value.toList()
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The reviver also receives a `path` array (sequence of keys from the root) — useful for selectively converting only certain branches (e.g. leave `events` as a `List` but turn `index` into an `OrderedMap`).
|
|
37
|
+
|
|
38
|
+
## toJS / toJSON
|
|
39
|
+
|
|
40
|
+
- `toJS()` — recursively converts an Immutable value into plain JS. `Map`/`Record`/Keyed → object (string keys), `List`/`Stack`/Indexed → array, `Set`/`OrderedSet` → array.
|
|
41
|
+
- `toJSON()` — SHALLOW one-level conversion. The same shape (object vs array) but the values are still Immutable.
|
|
42
|
+
- `JSON.stringify(immutableValue)` works out of the box: each node's `toJSON` is invoked recursively by the serializer, so the resulting JSON string IS deeply plain.
|
|
43
|
+
- `Record#toJSON()` returns a plain object with the record's defined keys (no prototype).
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
import { Map, List } from 'immutable';
|
|
47
|
+
const m = Map({ items: List([1, 2, 3]) });
|
|
48
|
+
m.toJS(); // { items: [1, 2, 3] } (deep)
|
|
49
|
+
m.toJSON(); // { items: List [ 1, 2, 3 ] } (shallow)
|
|
50
|
+
JSON.stringify(m); // '{"items":[1,2,3]}' (deep, via toJSON recursion)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Per-type converters
|
|
54
|
+
|
|
55
|
+
Shallow conversions to plain JS containers:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
toArray(): Array<V> | Array<[K, V]> // Keyed → entries; Indexed/Set → values
|
|
59
|
+
toObject(): { [key: string]: V } // Keyed only; coerces keys to strings
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Re-bucket into another Immutable collection (the source's keys may or may not survive — see notes):
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
toList(): List<V> // discards keys (Map → values only)
|
|
66
|
+
toMap(): Map<K, V> // requires hashable keys; throws otherwise
|
|
67
|
+
toOrderedMap(): OrderedMap<K, V> // preserves iteration order
|
|
68
|
+
toSet(): Set<V> // discards keys; requires hashable values
|
|
69
|
+
toOrderedSet(): OrderedSet<V> // preserves iteration order
|
|
70
|
+
toStack(): Stack<V> // discards keys
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Lazy `Seq` variants (no work until iterated):
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
toSeq(): Seq<K, V> // same kind as the source
|
|
77
|
+
toKeyedSeq(): Seq.Keyed<K, V> // for Indexed: indices become keys
|
|
78
|
+
toIndexedSeq(): Seq.Indexed<V> // discards keys
|
|
79
|
+
toSetSeq(): Seq.Set<V> // discards keys
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
These are equivalent to passing the collection to the corresponding constructor (`List(coll)`, `Map(coll)`, ...) but read better in chains and have one important difference: `List(map)` produces a list of `[key, value]` entry tuples, while `map.toList()` produces a list of values only.
|
|
83
|
+
|
|
84
|
+
## Gotchas
|
|
85
|
+
|
|
86
|
+
- `fromJS` does NOT convert `Date`, JS `Map`/`Set`, `RegExp`, typed arrays, or custom class instances — they pass through. Use a `reviver` if you need to convert them.
|
|
87
|
+
- `fromJS` only treats objects with the default `Object.prototype` as plain — anything with a custom prototype is left alone. This is usually what you want, but means subclasses of `Object` won't be deepened.
|
|
88
|
+
- `toJS` is recursive and allocates a fresh deep copy on every call. On large structures it is expensive — iterate Immutable values directly rather than calling `.toJS()` in render paths or hot loops.
|
|
89
|
+
- `Map#toList()` discards keys (values-only). If you want pairs, use `map.entrySeq().toList()` or `map.toIndexedSeq()` over `entrySeq`.
|
|
90
|
+
- `Map#toArray()` (and other Keyed `toArray()`) returns `[key, value]` tuples, not values — use `valueSeq().toArray()` for a flat values array.
|
|
91
|
+
- Round-tripping `fromJS(value).toJS()` produces a structurally similar object but not necessarily identical: property iteration order may change, and any non-plain instances on the input round-trip as the same reference (since `fromJS` left them alone).
|
|
92
|
+
- `JSON.stringify(immutable)` works without explicit conversion — `toJSON` is wired up on every collection. No need to call `.toJS()` first.
|
|
93
|
+
- `toMap()` and `toSet()` throw at runtime if the values/keys are not hashable (e.g. mutable JS objects). `toOrderedMap`/`toOrderedSet` have the same constraint but preserve insertion order.
|
|
94
|
+
|
|
95
|
+
## See also
|
|
96
|
+
|
|
97
|
+
- `references/deep-updates.md` — `getIn`/`setIn`/`updateIn`/`mergeDeep` for working without converting back to JS.
|
|
98
|
+
- `references/list.md`, `references/map.md`, `references/set.md` — per-type construction and method details.
|
|
99
|
+
- `references/predicates.md` — `isImmutable`, `isKeyed`, `isIndexed` (used in `fromJS` revivers).
|