mutts 1.0.2 → 1.0.3

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.
Files changed (104) hide show
  1. package/README.md +14 -6
  2. package/dist/chunks/{_tslib-C-cuVLvZ.js → _tslib-BgjropY9.js} +9 -1
  3. package/dist/chunks/_tslib-BgjropY9.js.map +1 -0
  4. package/dist/chunks/{_tslib-CMEnd0VE.esm.js → _tslib-Mzh1rNsX.esm.js} +9 -2
  5. package/dist/chunks/_tslib-Mzh1rNsX.esm.js.map +1 -0
  6. package/dist/chunks/{decorator-D4DU97Zg.js → decorator-DLvrD0UF.js} +42 -19
  7. package/dist/chunks/decorator-DLvrD0UF.js.map +1 -0
  8. package/dist/chunks/{decorator-GnHw1Az7.esm.js → decorator-DqiszP7i.esm.js} +42 -19
  9. package/dist/chunks/decorator-DqiszP7i.esm.js.map +1 -0
  10. package/dist/chunks/index-DzUDtFc7.esm.js +4841 -0
  11. package/dist/chunks/index-DzUDtFc7.esm.js.map +1 -0
  12. package/dist/chunks/index-HNVqPzjz.js +4891 -0
  13. package/dist/chunks/index-HNVqPzjz.js.map +1 -0
  14. package/dist/decorator.esm.js +1 -1
  15. package/dist/decorator.js +1 -1
  16. package/dist/destroyable.d.ts +1 -1
  17. package/dist/destroyable.esm.js +1 -1
  18. package/dist/destroyable.esm.js.map +1 -1
  19. package/dist/destroyable.js +1 -1
  20. package/dist/destroyable.js.map +1 -1
  21. package/dist/devtools/devtools.html +9 -0
  22. package/dist/devtools/devtools.js +5 -0
  23. package/dist/devtools/devtools.js.map +1 -0
  24. package/dist/devtools/manifest.json +8 -0
  25. package/dist/devtools/panel.css +72 -0
  26. package/dist/devtools/panel.html +31 -0
  27. package/dist/devtools/panel.js +13048 -0
  28. package/dist/devtools/panel.js.map +1 -0
  29. package/dist/eventful.esm.js +1 -1
  30. package/dist/eventful.js +1 -1
  31. package/dist/index.d.ts +18 -63
  32. package/dist/index.esm.js +4 -4
  33. package/dist/index.js +36 -11
  34. package/dist/index.js.map +1 -1
  35. package/dist/indexable.d.ts +187 -1
  36. package/dist/indexable.esm.js +197 -3
  37. package/dist/indexable.esm.js.map +1 -1
  38. package/dist/indexable.js +198 -2
  39. package/dist/indexable.js.map +1 -1
  40. package/dist/mutts.umd.js +1 -1
  41. package/dist/mutts.umd.js.map +1 -1
  42. package/dist/mutts.umd.min.js +1 -1
  43. package/dist/mutts.umd.min.js.map +1 -1
  44. package/dist/promiseChain.esm.js.map +1 -1
  45. package/dist/promiseChain.js.map +1 -1
  46. package/dist/reactive.d.ts +601 -97
  47. package/dist/reactive.esm.js +3 -3
  48. package/dist/reactive.js +31 -10
  49. package/dist/reactive.js.map +1 -1
  50. package/dist/std-decorators.esm.js +1 -1
  51. package/dist/std-decorators.js +1 -1
  52. package/docs/ai/api-reference.md +133 -0
  53. package/docs/ai/manual.md +105 -0
  54. package/docs/iterableWeak.md +646 -0
  55. package/docs/reactive/advanced.md +1280 -0
  56. package/docs/reactive/collections.md +767 -0
  57. package/docs/reactive/core.md +973 -0
  58. package/docs/reactive.md +21 -9545
  59. package/package.json +18 -5
  60. package/src/decorator.ts +266 -0
  61. package/src/destroyable.ts +199 -0
  62. package/src/eventful.ts +77 -0
  63. package/src/index.d.ts +9 -0
  64. package/src/index.ts +9 -0
  65. package/src/indexable.ts +484 -0
  66. package/src/introspection.ts +59 -0
  67. package/src/iterableWeak.ts +233 -0
  68. package/src/mixins.ts +123 -0
  69. package/src/promiseChain.ts +110 -0
  70. package/src/reactive/array.ts +414 -0
  71. package/src/reactive/change.ts +134 -0
  72. package/src/reactive/debug.ts +517 -0
  73. package/src/reactive/deep-touch.ts +268 -0
  74. package/src/reactive/deep-watch-state.ts +82 -0
  75. package/src/reactive/deep-watch.ts +168 -0
  76. package/src/reactive/effect-context.ts +94 -0
  77. package/src/reactive/effects.ts +1333 -0
  78. package/src/reactive/index.ts +75 -0
  79. package/src/reactive/interface.ts +223 -0
  80. package/src/reactive/map.ts +171 -0
  81. package/src/reactive/mapped.ts +130 -0
  82. package/src/reactive/memoize.ts +107 -0
  83. package/src/reactive/non-reactive-state.ts +49 -0
  84. package/src/reactive/non-reactive.ts +43 -0
  85. package/src/reactive/project.project.md +93 -0
  86. package/src/reactive/project.ts +335 -0
  87. package/src/reactive/proxy-state.ts +27 -0
  88. package/src/reactive/proxy.ts +285 -0
  89. package/src/reactive/record.ts +196 -0
  90. package/src/reactive/register.ts +421 -0
  91. package/src/reactive/set.ts +144 -0
  92. package/src/reactive/tracking.ts +101 -0
  93. package/src/reactive/types.ts +358 -0
  94. package/src/reactive/zone.ts +208 -0
  95. package/src/std-decorators.ts +217 -0
  96. package/src/utils.ts +117 -0
  97. package/dist/chunks/_tslib-C-cuVLvZ.js.map +0 -1
  98. package/dist/chunks/_tslib-CMEnd0VE.esm.js.map +0 -1
  99. package/dist/chunks/decorator-D4DU97Zg.js.map +0 -1
  100. package/dist/chunks/decorator-GnHw1Az7.esm.js.map +0 -1
  101. package/dist/chunks/index-DBScoeCX.esm.js +0 -1960
  102. package/dist/chunks/index-DBScoeCX.esm.js.map +0 -1
  103. package/dist/chunks/index-DOTmXL89.js +0 -1983
  104. package/dist/chunks/index-DOTmXL89.js.map +0 -1
@@ -1,5 +1,5 @@
1
- export { R as Reactive, h as ReactiveBase, j as ReactiveError, a as activeEffect, b as addBatchCleanup, c as atomic, l as cleanedBy, n as computed, e as effect, g as getState, i as immutables, q as invalidateComputed, d as isNonReactive, f as isReactive, p as profileInfo, r as reactive, o as reactiveOptions, t as trackEffect, s as unreactive, u as untracked, k as unwrap, w as watch } from './chunks/index-DBScoeCX.esm.js';
2
- import './chunks/decorator-GnHw1Az7.esm.js';
3
- import './chunks/_tslib-CMEnd0VE.esm.js';
1
+ export { L as ReactiveBase, U as ReactiveError, R as ReadOnlyError, Q as Register, j as addBatchCleanup, k as atomic, l as biDi, c as buildReactivityGraph, x as cleanedBy, y as cleanup, h as deepWatch, n as defer, z as derived, o as effect, e as enableDevTools, q as getActiveEffect, g as getState, F as immutables, i as isDevtoolsEnabled, G as isNonReactive, K as isReactive, V as isZoneEnabled, C as mapped, E as memoize, O as organize, P as organized, p as profileInfo, J as project, M as reactive, T as reactiveOptions, D as reduced, S as register, r as registerEffectForDebug, H as registerNativeReactivity, d as registerObjectForDebug, u as root, s as setEffectName, f as setObjectName, W as setZoneEnabled, t as touched, b as touched1, v as trackEffect, A as unreactive, w as untracked, N as unwrap, B as watch } from './chunks/index-DzUDtFc7.esm.js';
2
+ import './chunks/decorator-DqiszP7i.esm.js';
4
3
  import './indexable.esm.js';
4
+ import './chunks/_tslib-Mzh1rNsX.esm.js';
5
5
  //# sourceMappingURL=reactive.esm.js.map
package/dist/reactive.js CHANGED
@@ -1,32 +1,53 @@
1
1
  'use strict';
2
2
 
3
- var reactive = require('./chunks/index-DOTmXL89.js');
4
- require('./chunks/decorator-D4DU97Zg.js');
5
- require('./chunks/_tslib-C-cuVLvZ.js');
3
+ var reactive = require('./chunks/index-HNVqPzjz.js');
4
+ require('./chunks/decorator-DLvrD0UF.js');
6
5
  require('./indexable.js');
6
+ require('./chunks/_tslib-BgjropY9.js');
7
7
 
8
8
 
9
9
 
10
- exports.Reactive = reactive.Reactive;
11
10
  exports.ReactiveBase = reactive.ReactiveBase;
12
11
  exports.ReactiveError = reactive.ReactiveError;
13
- Object.defineProperty(exports, "activeEffect", {
14
- enumerable: true,
15
- get: function () { return reactive.activeEffect; }
16
- });
12
+ exports.ReadOnlyError = reactive.ReadOnlyError;
13
+ exports.Register = reactive.Register;
17
14
  exports.addBatchCleanup = reactive.addBatchCleanup;
18
15
  exports.atomic = reactive.atomic;
16
+ exports.biDi = reactive.biDi;
17
+ exports.buildReactivityGraph = reactive.buildReactivityGraph;
19
18
  exports.cleanedBy = reactive.cleanedBy;
20
- exports.computed = reactive.computed;
19
+ exports.cleanup = reactive.cleanup;
20
+ exports.deepWatch = reactive.deepWatch;
21
+ exports.defer = reactive.defer;
22
+ exports.derived = reactive.derived;
21
23
  exports.effect = reactive.effect;
24
+ exports.enableDevTools = reactive.enableDevTools;
25
+ exports.getActiveEffect = reactive.getActiveEffect;
22
26
  exports.getState = reactive.getState;
23
27
  exports.immutables = reactive.immutables;
24
- exports.invalidateComputed = reactive.invalidateComputed;
28
+ exports.isDevtoolsEnabled = reactive.isDevtoolsEnabled;
25
29
  exports.isNonReactive = reactive.isNonReactive;
26
30
  exports.isReactive = reactive.isReactive;
31
+ exports.isZoneEnabled = reactive.isZoneEnabled;
32
+ exports.mapped = reactive.mapped;
33
+ exports.memoize = reactive.memoize;
34
+ exports.organize = reactive.organize;
35
+ exports.organized = reactive.organized;
27
36
  exports.profileInfo = reactive.profileInfo;
37
+ exports.project = reactive.project;
28
38
  exports.reactive = reactive.reactive;
29
39
  exports.reactiveOptions = reactive.options;
40
+ exports.reduced = reactive.reduced;
41
+ exports.register = reactive.register;
42
+ exports.registerEffectForDebug = reactive.registerEffectForDebug;
43
+ exports.registerNativeReactivity = reactive.registerNativeReactivity;
44
+ exports.registerObjectForDebug = reactive.registerObjectForDebug;
45
+ exports.root = reactive.root;
46
+ exports.setEffectName = reactive.setEffectName;
47
+ exports.setObjectName = reactive.setObjectName;
48
+ exports.setZoneEnabled = reactive.setZoneEnabled;
49
+ exports.touched = reactive.touched;
50
+ exports.touched1 = reactive.touched1;
30
51
  exports.trackEffect = reactive.trackEffect;
31
52
  exports.unreactive = reactive.unreactive;
32
53
  exports.untracked = reactive.untracked;
@@ -1 +1 @@
1
- {"version":3,"file":"reactive.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"reactive.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { d as decorator } from './chunks/decorator-GnHw1Az7.esm.js';
1
+ import { d as decorator } from './chunks/decorator-DqiszP7i.esm.js';
2
2
 
3
3
  // In order to avoid async re-entrance, we could use zone.js or something like that.
4
4
  const syncCalculating = [];
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var decorator = require('./chunks/decorator-D4DU97Zg.js');
3
+ var decorator = require('./chunks/decorator-DLvrD0UF.js');
4
4
 
5
5
  // In order to avoid async re-entrance, we could use zone.js or something like that.
6
6
  const syncCalculating = [];
@@ -0,0 +1,133 @@
1
+ # Mutts API Context
2
+
3
+ This file contains the aggregated type definitions for the Mutts library.
4
+ AI Agents should read this code block to understand correct function signatures and types.
5
+
6
+ ```typescript
7
+ /**
8
+ * MUTTS API CONTEXT FILE
9
+ */
10
+
11
+ // --------------------------------------------------------------------------------
12
+ // CORE REACTIVITY
13
+ // --------------------------------------------------------------------------------
14
+
15
+ export declare const Effect: unique symbol;
16
+ export declare const cleanup: unique symbol;
17
+ export declare const getAt: unique symbol;
18
+ export declare const setAt: unique symbol;
19
+ /**
20
+ * Symbol to check if an object is reactive
21
+ */
22
+ export declare const Reactive: unique symbol;
23
+ /**
24
+ * Symbol to map back from a reactive proxy to its original target
25
+ */
26
+ export declare const Raw: unique symbol;
27
+ export type ScopedCallback = (() => void | (() => void)) & {
28
+ [cleanup]?: () => void;
29
+ };
30
+ export type DependencyFunction = <T>(fn: () => T) => T;
31
+ export type DependencyAccess = {
32
+ tracked: DependencyFunction;
33
+ ascend: DependencyFunction;
34
+ reaction: boolean;
35
+ };
36
+
37
+ export declare function reactive<T extends object>(target: T): T;
38
+ export declare function effect(fn: (access: DependencyAccess, ...args: any[]) => (ScopedCallback | undefined | void), ...args: any[]): ScopedCallback;
39
+ export declare function unwrap<T>(obj: T): T;
40
+ export declare function isReactive(obj: any): boolean;
41
+ export declare function isNonReactive(obj: any): boolean;
42
+ export declare function untracked<T>(fn: () => T): T;
43
+
44
+ // --------------------------------------------------------------------------------
45
+ // REACTIVE HELPERS
46
+ // --------------------------------------------------------------------------------
47
+
48
+ export declare function atomic<T extends (...args: any[]) => any>(fn: T): T;
49
+ export declare function memoize<Result, Args extends any[]>(fn: (...args: Args) => Result, maxArgs?: number): (...args: Args) => Result;
50
+ export declare function deepWatch(source: any, callback: (path: string[], value: any) => void): () => void;
51
+ export declare function biDi<T>(target: (val: T) => void, source: { get: () => T, set: (v: T) => void }): (val: T) => void;
52
+
53
+ // --------------------------------------------------------------------------------
54
+ // COLLECTIONS
55
+ // --------------------------------------------------------------------------------
56
+
57
+ export interface Register<T, K extends PropertyKey = PropertyKey> extends Iterable<T> {
58
+ length: number;
59
+ [index: number]: T;
60
+ get(key: K): T | undefined;
61
+ set(key: K, value: T): void;
62
+ hasKey(key: K): boolean;
63
+ indexOfKey(key: K): number;
64
+ remove(key: K): void;
65
+ removeAt(index: number): T | undefined;
66
+ push(...items: T[]): number;
67
+ // ... complete array methods are supported
68
+ }
69
+
70
+ export declare function register<T, K extends PropertyKey = PropertyKey>(keyFn: (item: T) => K, initial?: Iterable<T>): Register<T, K>;
71
+ export declare function mapped<T, U>(inputs: readonly T[], compute: (input: T, index: number, output: U[]) => U): readonly U[];
72
+ export declare function reduced<T, U, R extends object = any>(inputs: readonly T[], compute: (input: T, factor: R) => readonly U[]): readonly U[];
73
+ export declare function project<S, R>(source: S, apply: (access: any, target: any) => any): R;
74
+ export declare function organized<S, T>(source: S, apply: (access: any, target: T) => any, baseTarget?: T): T;
75
+
76
+ // --------------------------------------------------------------------------------
77
+ // DESTROYABLE
78
+ // --------------------------------------------------------------------------------
79
+
80
+ export declare const destructor: unique symbol;
81
+ export declare const allocated: unique symbol;
82
+ export declare function Destroyable<T>(base?: T): any;
83
+ export declare class DestructionError extends Error {}
84
+
85
+ // --------------------------------------------------------------------------------
86
+ // EVENTS
87
+ // --------------------------------------------------------------------------------
88
+
89
+ export interface EventfulMixin {
90
+ on(event: string, callback: Function): void;
91
+ off(event: string, callback: Function): void;
92
+ emit(event: string, ...args: any[]): void;
93
+ }
94
+ export declare function Eventful<T extends new (...args: any[]) => any>(Base: T): T & (new (...args: any[]) => EventfulMixin);
95
+
96
+ // --------------------------------------------------------------------------------
97
+ // DECORATORS
98
+ // --------------------------------------------------------------------------------
99
+
100
+ export declare function cached(target: any, key: string, descriptor: PropertyDescriptor): void;
101
+ export declare function debounce(delay: number): Function;
102
+ export declare function throttle(delay: number): Function;
103
+ export declare function deprecated(message?: string): Function;
104
+
105
+ // --------------------------------------------------------------------------------
106
+ // INTROSPECTION (AI Debugging)
107
+ // --------------------------------------------------------------------------------
108
+
109
+ export interface ReactivityGraph {
110
+ nodes: { id: string, label: string, type: 'effect'|'object' }[];
111
+ edges: { source: string, target: string, type: string }[];
112
+ }
113
+
114
+ export interface MutationRecord {
115
+ type: 'set' | 'add' | 'delete';
116
+ prop: PropertyKey;
117
+ oldValue: any;
118
+ newValue: any;
119
+ objectName?: string;
120
+ }
121
+
122
+ export declare function getDependencyGraph(): ReactivityGraph;
123
+ export declare function getMutationHistory(): MutationRecord[];
124
+ export declare const options: {
125
+ cycleHandling: 'throw' | 'warn' | 'break' | 'strict';
126
+ introspection: { enableHistory: boolean; historySize: number };
127
+ };
128
+
129
+ export enum ReactiveErrorCode {
130
+ CYCLE_DETECTED = 'CYCLE_DETECTED',
131
+ MAX_DEPTH_EXCEEDED = 'MAX_DEPTH_EXCEEDED',
132
+ }
133
+ ```
@@ -0,0 +1,105 @@
1
+ # Mutts AI Agent Manual
2
+
3
+ > [!IMPORTANT]
4
+ > **Identity**: You are an AI Agent. This document is written for **YOU**.
5
+ > **Purpose**: This file defines the protocols, schemas, and capabilities available to you when working with the `mutts` reactivity system.
6
+ >
7
+ > For exact TypeScript signatures of the entire library, consult the **[API Reference for Agents](./api-reference.md)**.
8
+
9
+ ## 1. Introspection Capability
10
+ When you encounter reactivity bugs (infinite loops, unexpected updates), **DO NOT GUESS**. Use the introspection API to "see" the system state.
11
+
12
+ ### Enabling Introspection
13
+ Introspection is often disabled by default for performance. Enable it before debugging.
14
+ ```typescript
15
+ import { enableIntrospection, options } from 'mutts/introspection'
16
+
17
+ // Enable history tracking (memory expensive, use only for debugging)
18
+ enableIntrospection({ historySize: 50 })
19
+ ```
20
+
21
+ ### Dependency Graph
22
+ Understanding "Who depends on What".
23
+ ```typescript
24
+ import { getDependencyGraph } from 'mutts/introspection'
25
+
26
+ const graph = getDependencyGraph()
27
+ // Returns: { nodes: { id: string, type: 'effect'|'object', label: string }[], edges: { from: string, to: string, type: 'dependency' }[] }
28
+ ```
29
+ **Agent Protocol**: If valid code is behaving unexpectedly, inspect the graph to ensure dependencies are actually linked as you expect.
30
+
31
+ ### Mutation History
32
+ Understanding "What just happened".
33
+ ```typescript
34
+ import { getMutationHistory } from 'mutts/introspection'
35
+
36
+ const history = getMutationHistory()
37
+ /*
38
+ Returns Array<{
39
+ id: number,
40
+ type: 'set' | 'add' | 'delete',
41
+ prop: string | symbol,
42
+ oldValue: any,
43
+ newValue: any,
44
+ objectName: string, // "Human readable name"
45
+ source: string, // "Effect X" or "External"
46
+ timestamp: number
47
+ }>
48
+ */
49
+ ```
50
+ **Agent Protocol**: When diagnosing "why is this value wrong?", check the *last mutation* of that property in history.
51
+
52
+ ## 2. Structured Error Handling
53
+ `mutts` throws `ReactiveError` instances. These are designed to be machine-parseable.
54
+
55
+ ### ReactiveErrorCode
56
+ Always check `error.debugInfo.code`.
57
+ ```typescript
58
+ enum ReactiveErrorCode {
59
+ CycleDetected = 'CYCLE_DETECTED',
60
+ MaxDepthExceeded = 'MAX_DEPTH_EXCEEDED',
61
+ MaxReactionExceeded = 'MAX_REACTION_EXCEEDED',
62
+ WriteInComputed = 'WRITE_IN_COMPUTED',
63
+ TrackingError = 'TRACKING_ERROR'
64
+ }
65
+ ```
66
+
67
+ ### Debugging Protocols
68
+
69
+ #### Protocol: Handling `CycleDetected` / `MaxDepthExceeded`
70
+ **Symptom**: `ReactiveError` with code `CycleDetected` or `MaxDepthExceeded`.
71
+ **Action**:
72
+ 1. Read `error.debugInfo.cycle` (Array of effect names).
73
+ 2. **CRITICAL**: Read `error.debugInfo.causalChain`.
74
+ * It tells you the *logical path*: `Effect A` -> (modifies `x`) -> `Effect B` -> (modifies `y`) -> `Effect A`.
75
+ 3. **CRITICAL**: Read `error.debugInfo.creationStack`.
76
+ * This gives you the **File path and Line number** where the problematic effect was defined.
77
+
78
+ **Example Error Object**:
79
+ ```json
80
+ {
81
+ "message": "[reactive] Max effect chain reached...",
82
+ "debugInfo": {
83
+ "code": "MAX_DEPTH_EXCEEDED",
84
+ "causalChain": [
85
+ "Effect(Anonymous) -> (set 'count') -> Effect(Display)",
86
+ "Effect(Display) -> (set 'dummy') -> Effect(Anonymous)"
87
+ ],
88
+ "creationStack": " at tests/my-test.ts:45:10\n at ...",
89
+ "cycle": ["Effect(Anonymous)", "Effect(Display)"]
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## 3. Strict Mode
95
+ If you are writing new code that might be complex, verify it with "Strict Mode".
96
+ This forces a graph check *before* execution, preventing infinite loops from hanging the runtime.
97
+ ```typescript
98
+ import { options } from 'mutts/introspection'
99
+ options.cycleHandling = 'strict'
100
+ ```
101
+
102
+ ## 4. Architecture Constraints for Agents
103
+ 1. **Do not** access properties starting with `_mutts_` directly unless instructed. These are internal implementation details.
104
+ 2. **Do not** rely on `batchQueue` global state in your reasoning; it is ephemeral.
105
+ 3. **Do** name your effects when possible (`effect(() => {}, { name: 'MyEffect' })`) to make your own future debugging easier.