mutts 1.0.9 → 1.0.11
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/README.md +60 -35
- package/dist/browser.cjs +1333 -1760
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +2 -1392
- package/dist/browser.dev.cjs +114 -0
- package/dist/browser.dev.cjs.map +1 -0
- package/dist/browser.dev.d.ts +2 -0
- package/dist/browser.dev.esm.js +5 -0
- package/dist/browser.dev.esm.js.map +1 -0
- package/dist/browser.esm.js +18 -97
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{async-browser-lvzLOCgk.cjs → async-browser-Dgr5CreQ.cjs} +16 -95
- package/dist/chunks/async-browser-Dgr5CreQ.cjs.map +1 -0
- package/dist/chunks/{async-node-C3DeIb0y.cjs → async-node-3PrbVAbB.cjs} +3 -1
- package/dist/chunks/async-node-3PrbVAbB.cjs.map +1 -0
- package/dist/chunks/index-Sf74wXTV.esm.js +2577 -0
- package/dist/chunks/index-Sf74wXTV.esm.js.map +1 -0
- package/dist/chunks/node-Bo7WU5S2.esm.js +96 -0
- package/dist/chunks/node-Bo7WU5S2.esm.js.map +1 -0
- package/dist/chunks/{index-VTO-b2vR.cjs → proxy-Cc79Lrzj.cjs} +2593 -3216
- package/dist/chunks/proxy-Cc79Lrzj.cjs.map +1 -0
- package/dist/chunks/{index-CtA2AWl3.esm.js → proxy-D2C49sXH.esm.js} +2570 -3174
- package/dist/chunks/proxy-D2C49sXH.esm.js.map +1 -0
- package/dist/debug.cjs +987 -28
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.d.ts +37 -38
- package/dist/debug.esm.js +963 -1
- package/dist/debug.esm.js.map +1 -1
- package/dist/devtools/manifest.json +1 -1
- package/dist/devtools/panel.html +1 -1
- package/dist/devtools/panel.js +107 -94
- package/dist/devtools/panel.js.map +1 -1
- package/dist/index.d.ts +1322 -1
- package/dist/mutts.umd.js +6647 -1
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/node.cjs +69 -63
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +114 -0
- package/dist/node.dev.cjs.map +1 -0
- package/dist/node.dev.d.ts +2 -0
- package/dist/node.dev.esm.js +6 -0
- package/dist/node.dev.esm.js.map +1 -0
- package/dist/node.esm.js +4 -97
- package/dist/node.esm.js.map +1 -1
- package/dist/{types-DaHFfhlN.d.ts → types-Bx2PhORg.d.ts} +134 -88
- package/docs/ai/api-reference.md +11 -32
- package/docs/ai/manual.md +297 -239
- package/docs/reactive/advanced.md +318 -9
- package/docs/reactive/attend.md +2 -4
- package/docs/reactive/collections.md +22 -187
- package/docs/reactive/core.md +223 -131
- package/docs/reactive/debugging.md +119 -12
- package/docs/reactive/error-handling.md +10 -10
- package/docs/reactive/resource.md +125 -0
- package/docs/reactive.md +3 -4
- package/docs/utils.md +70 -0
- package/docs/zone.md +1 -1
- package/package.json +76 -38
- package/dist/chunks/async-browser-lvzLOCgk.cjs.map +0 -1
- package/dist/chunks/async-node-C3DeIb0y.cjs.map +0 -1
- package/dist/chunks/index-2vea86wD.esm.js +0 -3011
- package/dist/chunks/index-2vea86wD.esm.js.map +0 -1
- package/dist/chunks/index-CtA2AWl3.esm.js.map +0 -1
- package/dist/chunks/index-VTO-b2vR.cjs.map +0 -1
- package/dist/debug/debug.d.ts +0 -122
- package/dist/debug/debug.d.ts.map +0 -1
- package/dist/debug/index.d.ts +0 -4
- package/dist/debug/index.d.ts.map +0 -1
- package/dist/debug/lineage-panel.d.ts +0 -5
- package/dist/debug/lineage-panel.d.ts.map +0 -1
- package/dist/debug/lineage.d.ts +0 -79
- package/dist/debug/lineage.d.ts.map +0 -1
- package/dist/src/async/browser.d.ts +0 -2
- package/dist/src/async/browser.d.ts.map +0 -1
- package/dist/src/async/index.d.ts +0 -19
- package/dist/src/async/index.d.ts.map +0 -1
- package/dist/src/async/node.d.ts +0 -2
- package/dist/src/async/node.d.ts.map +0 -1
- package/dist/src/decorator.d.ts +0 -106
- package/dist/src/decorator.d.ts.map +0 -1
- package/dist/src/destroyable.d.ts +0 -87
- package/dist/src/destroyable.d.ts.map +0 -1
- package/dist/src/entry-browser.d.ts +0 -3
- package/dist/src/entry-browser.d.ts.map +0 -1
- package/dist/src/entry-node.d.ts +0 -3
- package/dist/src/entry-node.d.ts.map +0 -1
- package/dist/src/eventful.d.ts +0 -20
- package/dist/src/eventful.d.ts.map +0 -1
- package/dist/src/flavored.d.ts +0 -33
- package/dist/src/flavored.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -14
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/indexable.d.ts +0 -243
- package/dist/src/indexable.d.ts.map +0 -1
- package/dist/src/introspection.d.ts +0 -27
- package/dist/src/introspection.d.ts.map +0 -1
- package/dist/src/iterableWeak.d.ts +0 -53
- package/dist/src/iterableWeak.d.ts.map +0 -1
- package/dist/src/mixins.d.ts +0 -25
- package/dist/src/mixins.d.ts.map +0 -1
- package/dist/src/promiseChain.d.ts +0 -20
- package/dist/src/promiseChain.d.ts.map +0 -1
- package/dist/src/reactive/array.d.ts +0 -48
- package/dist/src/reactive/array.d.ts.map +0 -1
- package/dist/src/reactive/buffer.d.ts +0 -120
- package/dist/src/reactive/buffer.d.ts.map +0 -1
- package/dist/src/reactive/change.d.ts +0 -29
- package/dist/src/reactive/change.d.ts.map +0 -1
- package/dist/src/reactive/deep-touch.d.ts +0 -28
- package/dist/src/reactive/deep-touch.d.ts.map +0 -1
- package/dist/src/reactive/deep-watch-state.d.ts +0 -25
- package/dist/src/reactive/deep-watch-state.d.ts.map +0 -1
- package/dist/src/reactive/deep-watch.d.ts +0 -20
- package/dist/src/reactive/deep-watch.d.ts.map +0 -1
- package/dist/src/reactive/describe.d.ts +0 -12
- package/dist/src/reactive/describe.d.ts.map +0 -1
- package/dist/src/reactive/effect-context.d.ts +0 -34
- package/dist/src/reactive/effect-context.d.ts.map +0 -1
- package/dist/src/reactive/effects.d.ts +0 -164
- package/dist/src/reactive/effects.d.ts.map +0 -1
- package/dist/src/reactive/index.d.ts +0 -19
- package/dist/src/reactive/index.d.ts.map +0 -1
- package/dist/src/reactive/map.d.ts +0 -28
- package/dist/src/reactive/map.d.ts.map +0 -1
- package/dist/src/reactive/memoize.d.ts +0 -28
- package/dist/src/reactive/memoize.d.ts.map +0 -1
- package/dist/src/reactive/non-reactive-state.d.ts +0 -9
- package/dist/src/reactive/non-reactive-state.d.ts.map +0 -1
- package/dist/src/reactive/non-reactive.d.ts +0 -11
- package/dist/src/reactive/non-reactive.d.ts.map +0 -1
- package/dist/src/reactive/project.d.ts +0 -40
- package/dist/src/reactive/project.d.ts.map +0 -1
- package/dist/src/reactive/proxy-state.d.ts +0 -8
- package/dist/src/reactive/proxy-state.d.ts.map +0 -1
- package/dist/src/reactive/proxy.d.ts +0 -23
- package/dist/src/reactive/proxy.d.ts.map +0 -1
- package/dist/src/reactive/record.d.ts +0 -115
- package/dist/src/reactive/record.d.ts.map +0 -1
- package/dist/src/reactive/register.d.ts +0 -125
- package/dist/src/reactive/register.d.ts.map +0 -1
- package/dist/src/reactive/registry.d.ts +0 -21
- package/dist/src/reactive/registry.d.ts.map +0 -1
- package/dist/src/reactive/set.d.ts +0 -26
- package/dist/src/reactive/set.d.ts.map +0 -1
- package/dist/src/reactive/tracking.d.ts +0 -7
- package/dist/src/reactive/tracking.d.ts.map +0 -1
- package/dist/src/reactive/types.d.ts +0 -424
- package/dist/src/reactive/types.d.ts.map +0 -1
- package/dist/src/reactive/watch.d.ts +0 -48
- package/dist/src/reactive/watch.d.ts.map +0 -1
- package/dist/src/std-decorators.d.ts +0 -45
- package/dist/src/std-decorators.d.ts.map +0 -1
- package/dist/src/utils.d.ts +0 -49
- package/dist/src/utils.d.ts.map +0 -1
- package/dist/src/zone.d.ts +0 -40
- package/dist/src/zone.d.ts.map +0 -1
- package/docs/reactive/describe.md +0 -85
- package/docs/reactive/project.md +0 -93
- package/docs/reactive/scan.md +0 -293
- package/src/async/browser.ts +0 -323
- package/src/async/index.ts +0 -27
- package/src/async/node.ts +0 -92
- package/src/decorator.ts +0 -272
- package/src/destroyable.ts +0 -199
- package/src/entry-browser.ts +0 -5
- package/src/entry-node.ts +0 -5
- package/src/eventful.ts +0 -110
- package/src/flavored.ts +0 -106
- package/src/index.d.ts +0 -12
- package/src/index.ts +0 -64
- package/src/indexable.ts +0 -526
- package/src/introspection.ts +0 -59
- package/src/iterableWeak.ts +0 -233
- package/src/mixins.ts +0 -123
- package/src/promiseChain.ts +0 -110
- package/src/reactive/array.ts +0 -500
- package/src/reactive/buffer.ts +0 -328
- package/src/reactive/change.ts +0 -131
- package/src/reactive/deep-touch.ts +0 -273
- package/src/reactive/deep-watch-state.ts +0 -82
- package/src/reactive/deep-watch.ts +0 -171
- package/src/reactive/describe.ts +0 -39
- package/src/reactive/effect-context.ts +0 -83
- package/src/reactive/effects.ts +0 -1434
- package/src/reactive/index.ts +0 -72
- package/src/reactive/map.ts +0 -142
- package/src/reactive/memoize.ts +0 -186
- package/src/reactive/non-reactive-state.ts +0 -49
- package/src/reactive/non-reactive.ts +0 -43
- package/src/reactive/project.md +0 -107
- package/src/reactive/project.ts +0 -430
- package/src/reactive/proxy-state.ts +0 -27
- package/src/reactive/proxy.ts +0 -282
- package/src/reactive/record.ts +0 -181
- package/src/reactive/register.ts +0 -538
- package/src/reactive/registry.ts +0 -72
- package/src/reactive/set.ts +0 -117
- package/src/reactive/tracking.ts +0 -41
- package/src/reactive/types.ts +0 -520
- package/src/reactive/watch.ts +0 -180
- package/src/std-decorators.ts +0 -256
- package/src/utils.ts +0 -300
- package/src/zone.ts +0 -142
|
@@ -259,169 +259,22 @@ effect(() => {
|
|
|
259
259
|
})
|
|
260
260
|
```
|
|
261
261
|
|
|
262
|
-
### `Register`
|
|
263
|
-
|
|
264
|
-
`Register` is an ordered, array-like collection that keeps a stable mapping between keys and values. It is useful when you need array semantics (indexable access, ordering, iteration) but also require identity preservation by key—ideal for UI lists keyed by IDs or when you want to memoise entries across reorders.
|
|
265
|
-
|
|
266
|
-
```typescript
|
|
267
|
-
import { Register } from 'mutts/reactive'
|
|
268
|
-
|
|
269
|
-
// Create a register where the key comes from the `id` field
|
|
270
|
-
const list = new Register(({id}: { id: number }) => id, [
|
|
271
|
-
{ id: 1, label: 'Alpha' },
|
|
272
|
-
{ id: 2, label: 'Bravo' },
|
|
273
|
-
])
|
|
274
|
-
|
|
275
|
-
effect(() => {
|
|
276
|
-
console.log('Length:', list.length)
|
|
277
|
-
console.log('First label:', list[0]?.label)
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
// Push uses the key function to keep identities stable
|
|
281
|
-
list.push({ id: 3, label: 'Charlie' })
|
|
282
|
-
|
|
283
|
-
// Replacing with the same key updates watchers without creating a new identity
|
|
284
|
-
list[0] = { id: 1, label: 'Alpha (updated)' }
|
|
285
|
-
|
|
286
|
-
// Access by key
|
|
287
|
-
const second = list.get(2) // { id: 2, label: 'Bravo' }
|
|
288
|
-
|
|
289
|
-
// Duplicate keys share value identity
|
|
290
|
-
list.push({ id: 2, label: 'Bravo (new data)' })
|
|
291
|
-
console.log(list[1] === list[2]) // true
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Highlights:**
|
|
295
|
-
|
|
296
|
-
- Fully indexable (`list[0]`, `list.at(-1)`, `list.length`, iteration, etc.) thanks to the shared `Indexable` infrastructure.
|
|
297
|
-
- Complete array surface forwarding (`map`, `filter`, `reduce`, `concat`, `reverse`, `sort`, `fill`, `copyWithin`, and more) with reactivity preserved.
|
|
298
|
-
- Stable key/value map under the hood allows quick lookups via `get()`, `hasKey()`, and `indexOfKey()`.
|
|
299
|
-
- When the same key appears multiple times, all slots reference the same underlying value instance, making deduplication and memoisation straightforward.
|
|
300
|
-
- Reordering operations emit index-level touches so list reactivity remains predictable in rendered UIs.
|
|
301
|
-
|
|
302
|
-
### Register-specific API (beyond Array)
|
|
303
|
-
|
|
304
|
-
The `Register` exposes additional methods and behaviors that standard arrays do not have:
|
|
305
|
-
|
|
306
|
-
- `get(key)` / `set(key, value)`
|
|
307
|
-
- `get(key: K): T | undefined` returns the latest value for a key.
|
|
308
|
-
- `set(key: K, value: T): void` updates the value for an existing key (no-op if key absent).
|
|
309
|
-
- Example:
|
|
310
|
-
```typescript
|
|
311
|
-
list.set(2, { id: 2, label: 'Bravo (updated)' })
|
|
312
|
-
const v = list.get(2)
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
- `hasKey(key)` / `indexOfKey(key)`
|
|
316
|
-
- `hasKey(key: K): boolean` whether the key is present in any slot.
|
|
317
|
-
- `indexOfKey(key: K): number` first index at which the key appears, or `-1`.
|
|
318
|
-
|
|
319
|
-
- `remove(key)` / `removeAt(index)`
|
|
320
|
-
- `remove(key: K): void` removes all occurrences of `key` from the register.
|
|
321
|
-
- `removeAt(index: number): T | undefined` removes a single slot by index and returns its value.
|
|
322
|
-
|
|
323
|
-
- `keep(predicate)`
|
|
324
|
-
- `keep(predicate: (value: T) => boolean): void` keeps only items for which the predicate returns `true`; items for which it returns `false` are removed. The predicate is evaluated once per distinct key; duplicate keys follow the same decision.
|
|
325
|
-
|
|
326
|
-
- `update(...values)`
|
|
327
|
-
- `update(...values: T[]): void` updates existing entries by their key; ignores values whose key is not yet present.
|
|
328
|
-
|
|
329
|
-
- `upsert(insert, ...values)`
|
|
330
|
-
- `upsert(insert: (value: T) => void, ...values: T[]): void` updates by key when present, otherwise calls `insert(value)` so you can decide how to insert (e.g. `push`, `unshift`, or `splice`).
|
|
331
|
-
- Example:
|
|
332
|
-
```typescript
|
|
333
|
-
list.upsert(v => list.push(v), { id: 4, label: 'Delta' }, { id: 2, label: 'Bravo (again)' })
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
- `entries()`
|
|
337
|
-
- Iterates `[number, value]` pairs in index order: `IterableIterator<[number, T | undefined]>`.
|
|
338
|
-
|
|
339
|
-
- `keys` / `values`
|
|
340
|
-
- `keys: ArrayIterator<number>` provides the index iterator (mirrors `Array#keys()`).
|
|
341
|
-
- `values: IterableIterator<T>` provides an iterator of values (same as default iteration).
|
|
342
|
-
|
|
343
|
-
- `clear()`
|
|
344
|
-
- Removes all entries and disposes internal key-tracking effects.
|
|
345
|
-
|
|
346
|
-
- `toArray()` / `toString()`
|
|
347
|
-
- `toArray(): T[]` materializes the current values into a plain array.
|
|
348
|
-
- `toString(): string` returns a concise description like `[Register length=3]`.
|
|
349
|
-
|
|
350
|
-
### Register CRUD Events
|
|
351
|
-
|
|
352
|
-
`Register` emits lifecycle events for add, delete, update, and rekey operations. This enables side effects like logging, syncing with external systems, or triggering derived updates.
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
const list = register(({id}: { id: number }) => id)
|
|
356
|
-
|
|
357
|
-
// Listen to individual events
|
|
358
|
-
list.on('add', (item, key, index) => {
|
|
359
|
-
console.log(`Added ${key} at index ${index}:`, item)
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
list.on('delete', (item, key, index) => {
|
|
363
|
-
console.log(`Removed ${key} from index ${index}:`, item)
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
list.on('update', (oldItem, newItem, key, index) => {
|
|
367
|
-
console.log(`Updated ${key} at index ${index}`)
|
|
368
|
-
})
|
|
369
|
-
|
|
370
|
-
list.on('rekey', (item, oldKey, newKey, index) => {
|
|
371
|
-
console.log(`Key changed from ${oldKey} to ${newKey}`)
|
|
372
|
-
})
|
|
373
|
-
|
|
374
|
-
// Bulk event registration
|
|
375
|
-
list.on({
|
|
376
|
-
add: (item) => console.log('Added:', item),
|
|
377
|
-
delete: (item) => console.log('Deleted:', item),
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
// Global hook - receive all events
|
|
381
|
-
const unhook = list.hook((event, ...args) => {
|
|
382
|
-
console.log(`Event: ${String(event)}`, args)
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
// Unsubscribe
|
|
386
|
-
const unsubscribe = list.on('add', handler)
|
|
387
|
-
unsubscribe()
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**Event Types:**
|
|
391
|
-
|
|
392
|
-
| Event | Arguments | Description |
|
|
393
|
-
|-------|-----------|-------------|
|
|
394
|
-
| `add` | `(item, key, index)` | New item added to register |
|
|
395
|
-
| `delete` | `(item, key, index)` | Item removed from register |
|
|
396
|
-
| `update` | `(oldItem, newItem, key, index)` | Item value updated (same key) |
|
|
397
|
-
| `rekey` | `(item, oldKey, newKey, index)` | Item's key changed |
|
|
398
|
-
|
|
399
|
-
**Use Cases:**
|
|
400
|
-
- Audit logging
|
|
401
|
-
- Syncing with databases
|
|
402
|
-
- Triggering notifications
|
|
403
|
-
- Cascading updates to dependent systems
|
|
404
|
-
|
|
405
|
-
Notes:
|
|
406
|
-
- Direct length modification via `list.length = n` is not supported; use `splice` instead.
|
|
407
|
-
- Assigning to an index (`list[i] = value`) uses the key function to bind that slot to `value`’s key.
|
|
408
|
-
|
|
409
262
|
## Class Reactivity
|
|
410
263
|
|
|
411
|
-
##
|
|
264
|
+
## Morphing
|
|
412
265
|
|
|
413
|
-
### `
|
|
266
|
+
### `morph()`
|
|
414
267
|
|
|
415
|
-
`
|
|
268
|
+
`morph()` provides a unified API for transforming reactive collections (arrays, records, and maps) into new reactive collections. Each source entry gets its own reactive effect that recomputes only when that specific entry changes, enabling granular updates perfect for rendering pipelines.
|
|
416
269
|
|
|
417
270
|
#### Basic Usage
|
|
418
271
|
|
|
419
272
|
```typescript
|
|
420
|
-
import { cleanup,
|
|
273
|
+
import { cleanup, morph, reactive } from 'mutts'
|
|
421
274
|
|
|
422
275
|
// Arrays
|
|
423
276
|
const users = reactive([{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }])
|
|
424
|
-
const names =
|
|
277
|
+
const names = morph(users, (user) => user.name.toUpperCase())
|
|
425
278
|
|
|
426
279
|
console.log(names) // ['JOHN', 'JANE']
|
|
427
280
|
|
|
@@ -430,8 +283,7 @@ console.log(names[0]) // 'JOHNNY' - only index 0 recomputed
|
|
|
430
283
|
|
|
431
284
|
// Records
|
|
432
285
|
const scores = reactive({ math: 90, science: 85 })
|
|
433
|
-
const grades =
|
|
434
|
-
const score = get()
|
|
286
|
+
const grades = morph(scores, (score) => {
|
|
435
287
|
return score >= 90 ? 'A' : score >= 80 ? 'B' : 'C'
|
|
436
288
|
})
|
|
437
289
|
|
|
@@ -444,7 +296,7 @@ const inventory = reactive(new Map([
|
|
|
444
296
|
['apples', { count: 10 }],
|
|
445
297
|
['oranges', { count: 5 }]
|
|
446
298
|
]))
|
|
447
|
-
const totals =
|
|
299
|
+
const totals = morph(inventory, (item) => item.count)
|
|
448
300
|
|
|
449
301
|
console.log(totals.get('apples')) // 10
|
|
450
302
|
inventory.get('apples')!.count = 15
|
|
@@ -453,41 +305,25 @@ console.log(totals.get('apples')) // 15 - only 'apples' key recomputed
|
|
|
453
305
|
|
|
454
306
|
#### Automatic Type Selection
|
|
455
307
|
|
|
456
|
-
|
|
308
|
+
The `morph()` function automatically selects the appropriate helper based on the source type:
|
|
457
309
|
|
|
458
310
|
```typescript
|
|
459
|
-
//
|
|
460
|
-
const doubled =
|
|
311
|
+
// Arrays
|
|
312
|
+
const doubled = morph([1, 2, 3], (x) => x * 2)
|
|
461
313
|
|
|
462
|
-
//
|
|
463
|
-
const upper =
|
|
314
|
+
// Records
|
|
315
|
+
const upper = morph({ a: 'hello', b: 'world' }, (s) => s.toUpperCase())
|
|
464
316
|
|
|
465
|
-
//
|
|
466
|
-
const counts =
|
|
317
|
+
// Maps
|
|
318
|
+
const counts = morph(new Map([['x', 1], ['y', 2]]), (v) => v * 2)
|
|
467
319
|
```
|
|
468
320
|
|
|
469
|
-
####
|
|
470
|
-
|
|
471
|
-
The callback receives a `ProjectAccess` object with:
|
|
321
|
+
#### Callback Signature
|
|
472
322
|
|
|
473
|
-
|
|
474
|
-
- **`set(value)`**: Function to update the source value (if the source is mutable)
|
|
475
|
-
- **`key`**: The current key or index
|
|
476
|
-
- **`source`**: Reference to the original source collection
|
|
477
|
-
- **`old`**: Previously computed result for this entry (undefined on first run)
|
|
478
|
-
- **`value`**: Computed property that mirrors `get()` (for convenience)
|
|
323
|
+
The callback function receives the current value of the entry being processed:
|
|
479
324
|
|
|
480
325
|
```typescript
|
|
481
|
-
const transformed =
|
|
482
|
-
// Access the source value
|
|
483
|
-
const item = access.get()
|
|
484
|
-
|
|
485
|
-
// Access the key/index
|
|
486
|
-
console.log(`Processing index ${access.key}`)
|
|
487
|
-
|
|
488
|
-
// Leverage previous result
|
|
489
|
-
console.log(`Previous result: ${access.old}`)
|
|
490
|
-
|
|
326
|
+
const transformed = morph(items, (item) => {
|
|
491
327
|
// Transform and return
|
|
492
328
|
return item.value * 2
|
|
493
329
|
})
|
|
@@ -505,9 +341,8 @@ const users = reactive([
|
|
|
505
341
|
])
|
|
506
342
|
|
|
507
343
|
let computeCount = 0
|
|
508
|
-
const summaries =
|
|
344
|
+
const summaries = morph(users, (user) => {
|
|
509
345
|
computeCount++
|
|
510
|
-
const user = get()
|
|
511
346
|
return `${user.name}: ${user.score}`
|
|
512
347
|
})
|
|
513
348
|
|
|
@@ -525,11 +360,11 @@ console.log(computeCount) // 5 (only new index 3 computed)
|
|
|
525
360
|
|
|
526
361
|
#### Key Addition and Removal
|
|
527
362
|
|
|
528
|
-
`
|
|
363
|
+
`morph()` automatically handles keys being added or removed from the source:
|
|
529
364
|
|
|
530
365
|
```typescript
|
|
531
366
|
const source = reactive({ a: 1, b: 2 })
|
|
532
|
-
const doubled =
|
|
367
|
+
const doubled = morph(source, (val) => val * 2)
|
|
533
368
|
|
|
534
369
|
console.log(doubled.a) // 2
|
|
535
370
|
console.log(doubled.b) // 4
|
|
@@ -548,7 +383,7 @@ console.log('a' in doubled) // false (automatically removed)
|
|
|
548
383
|
The returned object includes a `cleanup` symbol that stops all reactive effects:
|
|
549
384
|
|
|
550
385
|
```typescript
|
|
551
|
-
const result =
|
|
386
|
+
const result = morph(items, (item) => item * 2)
|
|
552
387
|
|
|
553
388
|
// Later, when done
|
|
554
389
|
result[cleanup]() // Stops all effects and cleans up
|
|
@@ -566,7 +401,7 @@ result[cleanup]() // Stops all effects and cleans up
|
|
|
566
401
|
### `organized()`
|
|
567
402
|
|
|
568
403
|
```typescript
|
|
569
|
-
import { cleanup, organized, reactive } from 'mutts
|
|
404
|
+
import { cleanup, organized, reactive } from 'mutts'
|
|
570
405
|
|
|
571
406
|
const source = reactive<Record<string, number>>({ apples: 1, oranges: 2 })
|
|
572
407
|
|