mutts 1.0.10 → 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 +3 -3
- package/dist/browser.cjs +395 -987
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.dev.cjs +13 -9
- package/dist/browser.dev.cjs.map +1 -1
- package/dist/browser.dev.d.ts +2 -2
- package/dist/browser.dev.esm.js +2 -2
- package/dist/browser.esm.js +15 -13
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{async-browser-BU_IfxYD.cjs → async-browser-Dgr5CreQ.cjs} +13 -11
- package/dist/chunks/async-browser-Dgr5CreQ.cjs.map +1 -0
- package/dist/chunks/{index-CaaQQlPJ.esm.js → index-Sf74wXTV.esm.js} +384 -981
- package/dist/chunks/index-Sf74wXTV.esm.js.map +1 -0
- package/dist/chunks/{node-nKJBk8iJ.esm.js → node-Bo7WU5S2.esm.js} +2 -2
- package/dist/chunks/{node-nKJBk8iJ.esm.js.map → node-Bo7WU5S2.esm.js.map} +1 -1
- package/dist/chunks/{proxy-Dtg-bJ3T.cjs → proxy-Cc79Lrzj.cjs} +414 -339
- package/dist/chunks/proxy-Cc79Lrzj.cjs.map +1 -0
- package/dist/chunks/{proxy-r7lARftl.esm.js → proxy-D2C49sXH.esm.js} +401 -330
- package/dist/chunks/proxy-D2C49sXH.esm.js.map +1 -0
- package/dist/debug.cjs +17 -3
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.d.ts +2 -2
- package/dist/debug.esm.js +17 -3
- package/dist/debug.esm.js.map +1 -1
- package/dist/index.d.ts +84 -209
- package/dist/mutts.umd.js +842 -1362
- 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 +13 -9
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +13 -9
- package/dist/node.dev.cjs.map +1 -1
- package/dist/node.dev.d.ts +2 -2
- package/dist/node.dev.esm.js +3 -3
- package/dist/node.esm.js +3 -3
- package/dist/{types-W5vD6m2n.d.ts → types-Bx2PhORg.d.ts} +38 -47
- package/docs/ai/api-reference.md +0 -14
- package/docs/ai/manual.md +2 -22
- package/docs/reactive/advanced.md +13 -14
- package/docs/reactive/attend.md +1 -2
- package/docs/reactive/collections.md +2 -149
- package/docs/reactive/core.md +218 -96
- package/docs/reactive/debugging.md +2 -2
- package/docs/reactive/resource.md +1 -1
- package/docs/reactive.md +1 -3
- package/docs/zone.md +1 -1
- package/package.json +18 -9
- package/dist/chunks/async-browser-BU_IfxYD.cjs.map +0 -1
- package/dist/chunks/index-CaaQQlPJ.esm.js.map +0 -1
- package/dist/chunks/proxy-Dtg-bJ3T.cjs.map +0 -1
- package/dist/chunks/proxy-r7lARftl.esm.js.map +0 -1
- package/docs/reactive/scan.md +0 -324
|
@@ -259,153 +259,6 @@ 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
|
|
@@ -417,7 +270,7 @@ Notes:
|
|
|
417
270
|
#### Basic Usage
|
|
418
271
|
|
|
419
272
|
```typescript
|
|
420
|
-
import { cleanup, morph, reactive } from 'mutts
|
|
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 }])
|
|
@@ -548,7 +401,7 @@ result[cleanup]() // Stops all effects and cleans up
|
|
|
548
401
|
### `organized()`
|
|
549
402
|
|
|
550
403
|
```typescript
|
|
551
|
-
import { cleanup, organized, reactive } from 'mutts
|
|
404
|
+
import { cleanup, organized, reactive } from 'mutts'
|
|
552
405
|
|
|
553
406
|
const source = reactive<Record<string, number>>({ apples: 1, oranges: 2 })
|
|
554
407
|
|