mutts 1.0.7 → 1.0.8

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 (132) hide show
  1. package/README.md +61 -23
  2. package/dist/async/browser.d.ts +2 -0
  3. package/dist/async/browser.d.ts.map +1 -0
  4. package/dist/async/index.d.ts +18 -0
  5. package/dist/async/index.d.ts.map +1 -0
  6. package/dist/async/node.d.ts +2 -0
  7. package/dist/async/node.d.ts.map +1 -0
  8. package/dist/{chunks/index-BFYK02LG.js → browser.cjs} +169 -60
  9. package/dist/browser.cjs.map +1 -0
  10. package/dist/browser.d.ts +1654 -1
  11. package/dist/browser.esm.js +260 -25
  12. package/dist/browser.esm.js.map +1 -1
  13. package/dist/chunks/async-browser-CA0jPWIi.cjs +304 -0
  14. package/dist/chunks/async-browser-CA0jPWIi.cjs.map +1 -0
  15. package/dist/chunks/async-core-UqHzvJ-S.cjs +25 -0
  16. package/dist/chunks/async-core-UqHzvJ-S.cjs.map +1 -0
  17. package/dist/chunks/async-node-BYHuGTni.cjs +103 -0
  18. package/dist/chunks/async-node-BYHuGTni.cjs.map +1 -0
  19. package/dist/chunks/{index-CNR6QRUl.esm.js → index-DhaOVusv.esm.js} +173 -53
  20. package/dist/chunks/index-DhaOVusv.esm.js.map +1 -0
  21. package/dist/decorator.d.ts +106 -0
  22. package/dist/decorator.d.ts.map +1 -0
  23. package/dist/destroyable.d.ts +87 -0
  24. package/dist/destroyable.d.ts.map +1 -0
  25. package/dist/devtools/devtool/devtools.d.ts +1 -0
  26. package/dist/devtools/devtool/devtools.d.ts.map +1 -0
  27. package/dist/devtools/devtool/panel.d.ts +2 -0
  28. package/dist/devtools/devtool/panel.d.ts.map +1 -0
  29. package/dist/entry-browser.d.ts +3 -0
  30. package/dist/entry-browser.d.ts.map +1 -0
  31. package/dist/entry-node.d.ts +3 -0
  32. package/dist/entry-node.d.ts.map +1 -0
  33. package/dist/eventful.d.ts +18 -0
  34. package/dist/eventful.d.ts.map +1 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/indexable.d.ts +243 -0
  38. package/dist/indexable.d.ts.map +1 -0
  39. package/dist/introspection.d.ts +27 -0
  40. package/dist/introspection.d.ts.map +1 -0
  41. package/dist/iterableWeak.d.ts +53 -0
  42. package/dist/iterableWeak.d.ts.map +1 -0
  43. package/dist/mixins.d.ts +25 -0
  44. package/dist/mixins.d.ts.map +1 -0
  45. package/dist/mutts.umd.js +1 -1
  46. package/dist/mutts.umd.js.map +1 -1
  47. package/dist/mutts.umd.min.js +1 -1
  48. package/dist/mutts.umd.min.js.map +1 -1
  49. package/dist/node.cjs +105 -0
  50. package/dist/node.cjs.map +1 -0
  51. package/dist/node.d.ts +1 -2
  52. package/dist/node.esm.js +91 -32
  53. package/dist/node.esm.js.map +1 -1
  54. package/dist/promiseChain.d.ts +20 -0
  55. package/dist/promiseChain.d.ts.map +1 -0
  56. package/dist/reactive/array.d.ts +49 -0
  57. package/dist/reactive/array.d.ts.map +1 -0
  58. package/dist/reactive/buffer.d.ts +44 -0
  59. package/dist/reactive/buffer.d.ts.map +1 -0
  60. package/dist/reactive/change.d.ts +29 -0
  61. package/dist/reactive/change.d.ts.map +1 -0
  62. package/dist/reactive/debug.d.ts +111 -0
  63. package/dist/reactive/debug.d.ts.map +1 -0
  64. package/dist/reactive/deep-touch.d.ts +28 -0
  65. package/dist/reactive/deep-touch.d.ts.map +1 -0
  66. package/dist/reactive/deep-watch-state.d.ts +25 -0
  67. package/dist/reactive/deep-watch-state.d.ts.map +1 -0
  68. package/dist/reactive/deep-watch.d.ts +19 -0
  69. package/dist/reactive/deep-watch.d.ts.map +1 -0
  70. package/dist/reactive/effect-context.d.ts +7 -0
  71. package/dist/reactive/effect-context.d.ts.map +1 -0
  72. package/dist/reactive/effects.d.ts +151 -0
  73. package/dist/reactive/effects.d.ts.map +1 -0
  74. package/dist/reactive/index.d.ts +20 -0
  75. package/dist/reactive/index.d.ts.map +1 -0
  76. package/dist/reactive/interface.d.ts +64 -0
  77. package/dist/reactive/interface.d.ts.map +1 -0
  78. package/dist/reactive/map.d.ts +30 -0
  79. package/dist/reactive/map.d.ts.map +1 -0
  80. package/dist/reactive/memoize.d.ts +5 -0
  81. package/dist/reactive/memoize.d.ts.map +1 -0
  82. package/dist/reactive/non-reactive-state.d.ts +9 -0
  83. package/dist/reactive/non-reactive-state.d.ts.map +1 -0
  84. package/dist/reactive/non-reactive.d.ts +11 -0
  85. package/dist/reactive/non-reactive.d.ts.map +1 -0
  86. package/dist/reactive/project.d.ts +41 -0
  87. package/dist/reactive/project.d.ts.map +1 -0
  88. package/dist/reactive/proxy-state.d.ts +8 -0
  89. package/dist/reactive/proxy-state.d.ts.map +1 -0
  90. package/dist/reactive/proxy.d.ts +23 -0
  91. package/dist/reactive/proxy.d.ts.map +1 -0
  92. package/dist/reactive/record.d.ts +116 -0
  93. package/dist/reactive/record.d.ts.map +1 -0
  94. package/dist/reactive/register.d.ts +64 -0
  95. package/dist/reactive/register.d.ts.map +1 -0
  96. package/dist/reactive/registry.d.ts +20 -0
  97. package/dist/reactive/registry.d.ts.map +1 -0
  98. package/dist/reactive/set.d.ts +28 -0
  99. package/dist/reactive/set.d.ts.map +1 -0
  100. package/dist/reactive/tracking.d.ts +7 -0
  101. package/dist/reactive/tracking.d.ts.map +1 -0
  102. package/dist/reactive/types.d.ts +376 -0
  103. package/dist/reactive/types.d.ts.map +1 -0
  104. package/dist/std-decorators.d.ts +50 -0
  105. package/dist/std-decorators.d.ts.map +1 -0
  106. package/dist/utils.d.ts +49 -0
  107. package/dist/utils.d.ts.map +1 -0
  108. package/dist/zone.d.ts +40 -0
  109. package/dist/zone.d.ts.map +1 -0
  110. package/docs/std-decorators.md +69 -1
  111. package/docs/zone.md +7 -0
  112. package/package.json +39 -27
  113. package/src/async/browser.ts +266 -34
  114. package/src/async/index.ts +17 -2
  115. package/src/async/node.ts +89 -31
  116. package/src/entry-browser.ts +5 -0
  117. package/src/entry-node.ts +5 -0
  118. package/src/index.d.ts +12 -9
  119. package/src/index.ts +1 -0
  120. package/src/reactive/array.ts +139 -52
  121. package/src/reactive/effect-context.ts +3 -3
  122. package/src/reactive/index.ts +2 -1
  123. package/src/reactive/map.ts +1 -1
  124. package/src/reactive/set.ts +1 -1
  125. package/src/utils.ts +1 -1
  126. package/src/zone.ts +19 -8
  127. package/dist/browser.js +0 -161
  128. package/dist/browser.js.map +0 -1
  129. package/dist/chunks/index-BFYK02LG.js.map +0 -1
  130. package/dist/chunks/index-CNR6QRUl.esm.js.map +0 -1
  131. package/dist/node.js +0 -136
  132. package/dist/node.js.map +0 -1
package/README.md CHANGED
@@ -44,6 +44,66 @@ import { Destroyable, allocated } from 'mutts/destroyable'
44
44
 
45
45
  **Note:** When importing from source files, you'll need to configure your build system (TypeScript, Vite, Webpack, etc.) to handle TypeScript compilation and module resolution. The source files are published alongside the built modules, so you can import directly from the `src` directory.
46
46
 
47
+ ### Environment Setup (Node vs Browser)
48
+
49
+ `mutts` has two distinct entry points to handle environment-specific behaviors (like `async_hooks` in Node vs `wrap` in Browser).
50
+
51
+ * **Automatic Resolution**: Bundlers (Vite, Rollup, Webpack) and Node.js will automatically pick the correct entry point (`mutts/node` or `mutts/browser`) based on the `exports` field in `package.json`.
52
+ * **Manual Selection**: You can force a specific environment if needed:
53
+ ```typescript
54
+ import 'mutts/node' // Side-effect import to polyfill async hooks in tests
55
+ import { ... } from 'mutts/node' // Explicit Node entry
56
+ import { ... } from 'mutts/browser' // Explicit Browser entry
57
+ ```
58
+
59
+ ## [Reactive](./docs/reactive.md)
60
+
61
+ A comprehensive reactivity system. See the **[Introduction](./docs/reactive/core.md)** or browse the **[Table of Contents](./docs/reactive.md)**.
62
+
63
+ **Key Features:**
64
+ - **Core Reactivity**: Proxy-based property access tracking with `reactive()`, `effect()`, `memoize()`, `project()`, and `scan()`
65
+ - **Deep Watching**: Automatic tracking of nested object changes with `deepWatch()`
66
+ - **Reactive Collections**: Specialized reactive versions of Array, Map, Set, WeakMap, and WeakSet
67
+ - **Class Reactivity**: `@reactive` decorator and `ReactiveBase` for class-based reactivity
68
+ - **Reactive Mixin**: Always-reactive classes with mixin support (`Reactive`)
69
+ - **Back-Reference System**: Efficient change propagation through object hierarchies
70
+ - **Type Safety**: Full TypeScript support with proper type inference
71
+ - **Performance Optimized**: Lazy back-reference creation and efficient dependency tracking
72
+ - **Debugging & Development**: Built-in tools like cycle detection and memoization discrepancy check
73
+
74
+ **Use Cases:**
75
+ - State management systems
76
+ - UI framework reactivity
77
+ - Data synchronization
78
+ - Real-time applications
79
+ - Form validation and processing
80
+
81
+ ## [Zones & Async Context](./docs/zone.md)
82
+
83
+ A powerful context propagation system that maintains state across asynchronous boundaries (Promises, timeouts, listeners).
84
+
85
+ **Key Features:**
86
+ - **Universal Context**: Works reliably in both Node.js (via `async_hooks`) and Browser/Edge environments.
87
+ - **Zone**: A simple value container that propagates with execution flow.
88
+ - **ZoneHistory**: A zone that tracks the history of values it has held in the current execution path.
89
+ - **ZoneAggregator**: Combines multiple zones into a single propagatable context.
90
+ - **Async Hooks**: Low-level hooks to capture, restore, and undo context changes across async boundaries.
91
+
92
+ ```typescript
93
+ import { Zone, asyncZone } from 'mutts'
94
+
95
+ const userZone = new Zone<User>()
96
+ // Register for async propagation
97
+ asyncZone.add(userZone)
98
+
99
+ userZone.with(currentUser, async () => {
100
+ // Context is available here
101
+ await someAsyncWork()
102
+ // Context is STILL available here, magically!
103
+ console.log(userZone.active) // currentUser
104
+ })
105
+ ```
106
+
47
107
  ## [Indexable](./docs/indexable.md)
48
108
 
49
109
  A way to write classes that allow numeric indexes managed by a custom function - either given in the class by the symbols [getAt] and [setAt] either by a specification if the Indexable class.
@@ -156,26 +216,4 @@ A comprehensive resource management system that provides automatic cleanup for o
156
216
  - Network resource management
157
217
  - Memory management for large objects
158
218
  - Plugin systems with proper cleanup
159
- - Temporary resource management
160
-
161
- ## [Reactive](./docs/reactive.md)
162
-
163
- A comprehensive reactivity system. See the **[Introduction](./docs/reactive/core.md)** or browse the **[Table of Contents](./docs/reactive.md)**.
164
-
165
- **Key Features:**
166
- - **Core Reactivity**: Proxy-based property access tracking with `reactive()`, `effect()`, `memoize()`, `project()`, and `scan()`
167
- - **Deep Watching**: Automatic tracking of nested object changes with `deepWatch()`
168
- - **Reactive Collections**: Specialized reactive versions of Array, Map, Set, WeakMap, and WeakSet
169
- - **Class Reactivity**: `@reactive` decorator and `ReactiveBase` for class-based reactivity
170
- - **Reactive Mixin**: Always-reactive classes with mixin support (`Reactive`)
171
- - **Back-Reference System**: Efficient change propagation through object hierarchies
172
- - **Type Safety**: Full TypeScript support with proper type inference
173
- - **Performance Optimized**: Lazy back-reference creation and efficient dependency tracking
174
- - **Debugging & Development**: Built-in tools like cycle detection and memoization discrepancy check
175
-
176
- **Use Cases:**
177
- - State management systems
178
- - UI framework reactivity
179
- - Data synchronization
180
- - Real-time applications
181
- - Form validation and processing
219
+ - Temporary resource management
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/async/browser.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ export type Restorer = () => () => void;
2
+ export type Hook = () => Restorer;
3
+ export declare const asyncHooks: {
4
+ addHook(_hook: Hook): () => void;
5
+ /**
6
+ * [Hack] Sanitize a promise (or value) to prevent context leaks.
7
+ * Default: Identity function.
8
+ * Browser: Uses Macrotask wrapping to break microtask chains.
9
+ */
10
+ sanitizePromise(p: any): any;
11
+ };
12
+ /**
13
+ * Register a hook that will be called whenever an asynchronous operation is initiated.
14
+ * The hook should return a restorer function which will be called just before the async callback runs.
15
+ * That restorer should in turn return an undoer function which will be called just after the async callback finishes.
16
+ */
17
+ export declare const asyncHook: (hook: Hook) => () => void;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/async/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,MAAM,IAAI,CAAA;AACvC,MAAM,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAA;AAEjC,eAAO,MAAM,UAAU;mBACP,IAAI,GAAG,MAAM,IAAI;IAG7B;;;;OAIG;uBACgB,GAAG,GAAG,GAAG;CAG/B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,WAlBP,IAkBoC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/async/node.ts"],"names":[],"mappings":""}
@@ -1,10 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const asyncHooks = {
4
- addHook(_hook) {
5
- throw 'One must import the library from the server or the client side';
6
- }
7
- };
3
+ require('./chunks/async-browser-CA0jPWIi.cjs');
4
+ var asyncCore = require('./chunks/async-core-UqHzvJ-S.cjs');
5
+ require('./chunks/async-node-BYHuGTni.cjs');
6
+ require('node:async_hooks');
8
7
 
9
8
  /**
10
9
  * Combines multiple arrays into an array of tuples, stopping at the shortest array length
@@ -266,7 +265,7 @@ function contentRef(container) {
266
265
  })));
267
266
  return contentRefs.get(container);
268
267
  }
269
- function tag(obj, name) {
268
+ function tag(name, obj) {
270
269
  Object.defineProperties(obj, {
271
270
  [Symbol.toStringTag]: {
272
271
  value: name,
@@ -2059,6 +2058,9 @@ function addToMutationHistory(source, target, obj, prop, evolution) {
2059
2058
  }
2060
2059
 
2061
2060
  var _ZoneAggregator_zones;
2061
+ function isu(z) {
2062
+ return z;
2063
+ }
2062
2064
  class AZone {
2063
2065
  enter(value) {
2064
2066
  const prev = this.active;
@@ -2070,12 +2072,16 @@ class AZone {
2070
2072
  }
2071
2073
  with(value, fn) {
2072
2074
  const entered = this.enter(value);
2075
+ let res;
2073
2076
  try {
2074
- return fn();
2077
+ res = fn();
2075
2078
  }
2076
2079
  finally {
2077
2080
  this.leave(entered);
2078
2081
  }
2082
+ // [HACK]: Sanitization
2083
+ // See BROWSER_ASYNC_POLYFILL.md
2084
+ return asyncCore.asyncHooks.sanitizePromise(res);
2079
2085
  }
2080
2086
  root(fn) {
2081
2087
  let prev = this.enter();
@@ -2118,12 +2124,12 @@ class ZoneHistory extends AZone {
2118
2124
  throw new Error('ZoneHistory: re-entering historical zone');
2119
2125
  if (value !== undefined)
2120
2126
  self.history.add(value);
2121
- return { added: value, entered: controlled.enter(value) };
2127
+ return { added: value, entered: isu(controlled).enter(value) };
2122
2128
  },
2123
2129
  leave(entered) {
2124
2130
  if (entered.added !== undefined)
2125
2131
  self.history.delete(entered.added);
2126
- return controlled.leave(entered.entered);
2132
+ return isu(controlled).leave(entered.entered);
2127
2133
  }
2128
2134
  }));
2129
2135
  }
@@ -2157,13 +2163,13 @@ class ZoneAggregator extends AZone {
2157
2163
  const entered = new Map();
2158
2164
  for (const z of __classPrivateFieldGet(this, _ZoneAggregator_zones, "f")) {
2159
2165
  const v = value?.get(z);
2160
- entered.set(z, z.enter(v));
2166
+ entered.set(z, isu(z).enter(v));
2161
2167
  }
2162
2168
  return entered;
2163
2169
  }
2164
2170
  leave(entered) {
2165
2171
  for (const z of __classPrivateFieldGet(this, _ZoneAggregator_zones, "f"))
2166
- z.leave(entered.get(z));
2172
+ isu(z).leave(entered.get(z));
2167
2173
  }
2168
2174
  add(z) {
2169
2175
  __classPrivateFieldGet(this, _ZoneAggregator_zones, "f").add(z);
@@ -2176,8 +2182,8 @@ class ZoneAggregator extends AZone {
2176
2182
  }
2177
2183
  }
2178
2184
  _ZoneAggregator_zones = new WeakMap();
2179
- const asyncZone = tag(new ZoneAggregator(), 'async');
2180
- asyncHooks.addHook(() => {
2185
+ const asyncZone = tag('async', new ZoneAggregator());
2186
+ asyncCore.asyncHooks.addHook(() => {
2181
2187
  const zone = asyncZone.active;
2182
2188
  return () => {
2183
2189
  const prev = asyncZone.active;
@@ -2186,10 +2192,10 @@ asyncHooks.addHook(() => {
2186
2192
  };
2187
2193
  });
2188
2194
 
2189
- const effectHistory = tag(new ZoneHistory(), 'effectHistory');
2190
- tag(effectHistory.present, 'effectHistory.present');
2195
+ const effectHistory = tag('effectHistory', new ZoneHistory());
2196
+ tag('effectHistory.present', effectHistory.present);
2191
2197
  asyncZone.add(effectHistory);
2192
- const effectAggregator = tag(new ZoneAggregator(effectHistory.present), 'effectAggregator');
2198
+ const effectAggregator = tag('effectAggregator', new ZoneAggregator(effectHistory.present));
2193
2199
  function isRunning(effect) {
2194
2200
  const root = getRoot(effect);
2195
2201
  return effectHistory.some((e) => getRoot(e) === root);
@@ -5452,6 +5458,17 @@ function scan(source, callback, initialValue) {
5452
5458
  indexEffects.clear();
5453
5459
  });
5454
5460
  }
5461
+ function resolve(cb) {
5462
+ const result = reactive([]);
5463
+ return cleanedBy(result, effect(() => {
5464
+ const source = cb();
5465
+ if (result.length !== source.length)
5466
+ result.length = source.length;
5467
+ for (let i = 0; i < source.length; i++)
5468
+ if (result[i] !== source[i])
5469
+ result[i] = source[i];
5470
+ }));
5471
+ }
5455
5472
 
5456
5473
  function* index(i, { length = true } = {}) {
5457
5474
  if (length)
@@ -5524,6 +5541,8 @@ class ReactiveArray extends Array {
5524
5541
  at(index) {
5525
5542
  const actualIndex = index < 0 ? this.length + index : index;
5526
5543
  dependant(this, actualIndex);
5544
+ if (index < 0)
5545
+ dependant(this, 'length');
5527
5546
  if (actualIndex < 0 || actualIndex >= this.length)
5528
5547
  return undefined;
5529
5548
  return reactive(this[actualIndex]);
@@ -5578,36 +5597,61 @@ class ReactiveArray extends Array {
5578
5597
  };
5579
5598
  }
5580
5599
  indexOf(searchElement, fromIndex) {
5581
- dependant(this);
5600
+ const length = this.length;
5601
+ let i = fromIndex === undefined ? 0 : fromIndex;
5602
+ if (i < 0)
5603
+ i = Math.max(length + i, 0);
5582
5604
  const unwrappedSearch = unwrap(searchElement);
5583
- // Check both wrapped and unwrapped versions since array may contain either
5584
- const index = this.indexOf(unwrappedSearch, fromIndex);
5585
- if (index !== -1)
5586
- return index;
5587
- // If not found with unwrapped, try with wrapped (in case array contains wrapped version)
5588
- return this.indexOf(searchElement, fromIndex);
5605
+ for (; i < length; i++) {
5606
+ dependant(this, i);
5607
+ const item = this[i];
5608
+ if (item === searchElement || item === unwrappedSearch || unwrap(item) === unwrappedSearch) {
5609
+ return i;
5610
+ }
5611
+ }
5612
+ dependant(this, 'length');
5613
+ return -1;
5589
5614
  }
5590
5615
  lastIndexOf(searchElement, fromIndex) {
5591
- dependant(this);
5616
+ const length = this.length;
5617
+ let i = fromIndex === undefined ? length - 1 : fromIndex;
5618
+ if (i >= length)
5619
+ i = length - 1;
5620
+ if (i < 0)
5621
+ i = Math.max(length + i, -1); // -1 ensures loop condition i >= 0 works correctly
5592
5622
  const unwrappedSearch = unwrap(searchElement);
5593
- // Check both wrapped and unwrapped versions since array may contain either
5594
- const index = this.lastIndexOf(unwrappedSearch, fromIndex);
5595
- if (index !== -1)
5596
- return index;
5597
- // If not found with unwrapped, try with wrapped (in case array contains wrapped version)
5598
- return this.lastIndexOf(searchElement, fromIndex);
5623
+ for (; i >= 0; i--) {
5624
+ dependant(this, i);
5625
+ const item = this[i];
5626
+ if (item === searchElement || item === unwrappedSearch || unwrap(item) === unwrappedSearch) {
5627
+ return i;
5628
+ }
5629
+ }
5630
+ // If we scanned the whole relevant part and didn't find it, we depend on length
5631
+ // (because adding elements might shift indices or add the element)
5632
+ // Actually for lastIndexOf, if we start from end, length dependency is implicit in the start index calculation?
5633
+ // But if we return -1, it means we didn't find it.
5634
+ // If we push an element, should lastIndexOf update?
5635
+ // Yes, if the new element is the one we are looking for.
5636
+ dependant(this, 'length');
5637
+ return -1;
5599
5638
  }
5600
5639
  includes(searchElement, fromIndex) {
5601
- dependant(this);
5602
- const unwrappedSearch = unwrap(searchElement);
5603
- // Check both wrapped and unwrapped versions since array may contain either
5604
- return this.includes(unwrappedSearch, fromIndex) || this.includes(searchElement, fromIndex);
5640
+ return this.indexOf(searchElement, fromIndex) !== -1;
5605
5641
  }
5606
5642
  find(predicateOrElement, thisArg) {
5607
- dependant(this);
5608
5643
  if (typeof predicateOrElement === 'function') {
5609
5644
  const predicate = predicateOrElement;
5610
- return reactive(this.find((value, index, array) => predicate.call(thisArg, reactive(value), index, array), thisArg));
5645
+ const length = this.length;
5646
+ for (let i = 0; i < length; i++) {
5647
+ dependant(this, i);
5648
+ const val = reactive(this[i]);
5649
+ if (predicate.call(thisArg, val, i, this)) {
5650
+ return val;
5651
+ }
5652
+ }
5653
+ dependant(this, 'length');
5654
+ return undefined;
5611
5655
  }
5612
5656
  const fromIndex = typeof thisArg === 'number' ? thisArg : undefined;
5613
5657
  const index = this.indexOf(predicateOrElement, fromIndex);
@@ -5616,10 +5660,18 @@ class ReactiveArray extends Array {
5616
5660
  return reactive(this[index]);
5617
5661
  }
5618
5662
  findIndex(predicateOrElement, thisArg) {
5619
- dependant(this);
5620
5663
  if (typeof predicateOrElement === 'function') {
5621
5664
  const predicate = predicateOrElement;
5622
- return this.findIndex((value, index, array) => predicate.call(thisArg, reactive(value), index, array), thisArg);
5665
+ const length = this.length;
5666
+ for (let i = 0; i < length; i++) {
5667
+ dependant(this, i);
5668
+ const val = reactive(this[i]);
5669
+ if (predicate.call(thisArg, val, i, this)) {
5670
+ return i;
5671
+ }
5672
+ }
5673
+ dependant(this, 'length');
5674
+ return -1;
5623
5675
  }
5624
5676
  const fromIndex = typeof thisArg === 'number' ? thisArg : undefined;
5625
5677
  return this.indexOf(predicateOrElement, fromIndex);
@@ -5678,12 +5730,26 @@ class ReactiveArray extends Array {
5678
5730
  });
5679
5731
  }
5680
5732
  every(callbackfn, thisArg) {
5681
- dependant(this);
5682
- return this.every((value, index, array) => callbackfn.call(thisArg, reactive(value), index, array), thisArg);
5733
+ const length = this.length;
5734
+ for (let i = 0; i < length; i++) {
5735
+ dependant(this, i);
5736
+ if (!callbackfn.call(thisArg, reactive(this[i]), i, this)) {
5737
+ return false;
5738
+ }
5739
+ }
5740
+ dependant(this, 'length');
5741
+ return true;
5683
5742
  }
5684
5743
  some(callbackfn, thisArg) {
5685
- dependant(this);
5686
- return this.some((value, index, array) => callbackfn.call(thisArg, reactive(value), index, array), thisArg);
5744
+ const length = this.length;
5745
+ for (let i = 0; i < length; i++) {
5746
+ dependant(this, i);
5747
+ if (callbackfn.call(thisArg, reactive(this[i]), i, this)) {
5748
+ return true;
5749
+ }
5750
+ }
5751
+ dependant(this, 'length');
5752
+ return false;
5687
5753
  }
5688
5754
  // Side-effectful
5689
5755
  push(...items) {
@@ -5725,19 +5791,29 @@ class ReactiveArray extends Array {
5725
5791
  }
5726
5792
  splice(start, deleteCount, ...items) {
5727
5793
  const oldLength = this.length;
5728
- if (deleteCount === undefined)
5729
- deleteCount = oldLength - start;
5794
+ // Normalize start index
5795
+ let actualStart = start;
5796
+ if (actualStart < 0)
5797
+ actualStart = Math.max(oldLength + actualStart, 0);
5798
+ else
5799
+ actualStart = Math.min(actualStart, oldLength);
5800
+ // Normalize deleteCount
5801
+ let actualDeleteCount = deleteCount;
5802
+ if (actualDeleteCount === undefined) {
5803
+ actualDeleteCount = oldLength - actualStart;
5804
+ }
5805
+ else {
5806
+ actualDeleteCount = Math.max(0, Math.min(actualDeleteCount, oldLength - actualStart));
5807
+ }
5730
5808
  try {
5731
5809
  if (deleteCount === undefined)
5732
5810
  return reactive(this.splice(start));
5733
5811
  return reactive(this.splice(start, deleteCount, ...items));
5734
5812
  }
5735
5813
  finally {
5736
- touched(this, { type: 'bunch', method: 'splice' },
5737
- // TODO: edge cases
5738
- deleteCount === items.length
5739
- ? range(start, start + deleteCount)
5740
- : range(start, oldLength + Math.max(items.length - deleteCount, 0), {
5814
+ touched(this, { type: 'bunch', method: 'splice' }, actualDeleteCount === items.length
5815
+ ? range(actualStart, actualStart + actualDeleteCount - 1)
5816
+ : range(actualStart, oldLength + Math.max(items.length - actualDeleteCount, 0), {
5741
5817
  length: true,
5742
5818
  }));
5743
5819
  }
@@ -5760,6 +5836,17 @@ class ReactiveArray extends Array {
5760
5836
  }
5761
5837
  }
5762
5838
  fill(value, start, end) {
5839
+ const len = this.length;
5840
+ let k = start === undefined ? 0 : start;
5841
+ if (k < 0)
5842
+ k = Math.max(len + k, 0);
5843
+ else
5844
+ k = Math.min(k, len);
5845
+ let final = end === undefined ? len : end;
5846
+ if (final < 0)
5847
+ final = Math.max(len + final, 0);
5848
+ else
5849
+ final = Math.min(final, len);
5763
5850
  try {
5764
5851
  if (start === undefined)
5765
5852
  return this.fill(value);
@@ -5768,7 +5855,9 @@ class ReactiveArray extends Array {
5768
5855
  return this.fill(value, start, end);
5769
5856
  }
5770
5857
  finally {
5771
- touched(this, { type: 'bunch', method: 'fill' }, range(0, this.length - 1));
5858
+ if (final > k) {
5859
+ touched(this, { type: 'bunch', method: 'fill' }, range(k, final - 1));
5860
+ }
5772
5861
  }
5773
5862
  }
5774
5863
  copyWithin(target, start, end) {
@@ -5778,11 +5867,27 @@ class ReactiveArray extends Array {
5778
5867
  return this.copyWithin(target, start, end);
5779
5868
  }
5780
5869
  finally {
5781
- touched(this, { type: 'bunch', method: 'copyWithin' },
5782
- // TODO: calculate the range properly
5783
- range(0, this.length - 1));
5870
+ const len = this.length;
5871
+ let to = target;
5872
+ if (to < 0)
5873
+ to = Math.max(len + to, 0);
5874
+ else if (to >= len)
5875
+ to = len;
5876
+ let from = start;
5877
+ if (from < 0)
5878
+ from = Math.max(len + from, 0);
5879
+ else if (from >= len)
5880
+ from = len;
5881
+ let final = end === undefined ? len : end;
5882
+ if (final < 0)
5883
+ final = Math.max(len + final, 0);
5884
+ else if (final >= len)
5885
+ final = len;
5886
+ const count = Math.min(final - from, len - to);
5887
+ if (count > 0) {
5888
+ touched(this, { type: 'bunch', method: 'copyWithin' }, range(to, to + count - 1));
5889
+ }
5784
5890
  }
5785
- // Touch all affected indices with a single allProps call
5786
5891
  }
5787
5892
  }
5788
5893
 
@@ -5878,7 +5983,7 @@ class ReactiveMap extends Map {
5878
5983
  return this;
5879
5984
  },
5880
5985
  [Symbol.dispose]() { },
5881
- };
5986
+ }; // TODO: real iterator? (If easy)
5882
5987
  }
5883
5988
  // Implement Map methods with reactivity
5884
5989
  delete(key) {
@@ -6023,7 +6128,7 @@ class ReactiveSet extends Set {
6023
6128
  return this;
6024
6129
  },
6025
6130
  [Symbol.dispose]() { },
6026
- };
6131
+ }; //TODO? (something easy)
6027
6132
  }
6028
6133
  }
6029
6134
 
@@ -6240,7 +6345,7 @@ function throttle(delay) {
6240
6345
  });
6241
6346
  }
6242
6347
 
6243
- var version$1 = "1.0.7";
6348
+ var version$1 = "1.0.8";
6244
6349
  var pkg = {
6245
6350
  version: version$1};
6246
6351
 
@@ -6289,6 +6394,8 @@ if (globalScope) {
6289
6394
  globalScope[GLOBAL_MUTTS_KEY] = currentSourceInfo;
6290
6395
  }
6291
6396
 
6397
+ exports.asyncHook = asyncCore.asyncHook;
6398
+ exports.asyncHooks = asyncCore.asyncHooks;
6292
6399
  exports.AZone = AZone;
6293
6400
  exports.ArrayReadForward = ArrayReadForward;
6294
6401
  exports.DecoratorError = DecoratorError;
@@ -6309,7 +6416,6 @@ exports.addBatchCleanup = addBatchCleanup;
6309
6416
  exports.allocated = allocated;
6310
6417
  exports.allocatedValues = allocatedValues;
6311
6418
  exports.arrayEquals = arrayEquals;
6312
- exports.asyncHooks = asyncHooks;
6313
6419
  exports.asyncZone = asyncZone;
6314
6420
  exports.atomic = atomic;
6315
6421
  exports.biDi = biDi;
@@ -6331,9 +6437,11 @@ exports.derived = derived;
6331
6437
  exports.describe = describe;
6332
6438
  exports.destructor = destructor;
6333
6439
  exports.effect = effect;
6440
+ exports.effectAggregator = effectAggregator;
6334
6441
  exports.enableDevTools = enableDevTools;
6335
6442
  exports.forwardArray = forwardArray;
6336
6443
  exports.getActivationLog = getActivationLog;
6444
+ exports.getActiveEffect = getActiveEffect;
6337
6445
  exports.getActiveProjection = getActiveProjection;
6338
6446
  exports.getAt = getAt;
6339
6447
  exports.getState = getState;
@@ -6349,17 +6457,18 @@ exports.memoize = memoize;
6349
6457
  exports.mixin = mixin;
6350
6458
  exports.modernDecorator = modernDecorator;
6351
6459
  exports.named = named;
6352
- exports.options = options;
6353
6460
  exports.organize = organize;
6354
6461
  exports.organized = organized;
6355
6462
  exports.profileInfo = profileInfo;
6356
6463
  exports.project = project;
6357
6464
  exports.reactive = reactive;
6465
+ exports.reactiveOptions = options;
6358
6466
  exports.register = register;
6359
6467
  exports.registerEffectForDebug = registerEffectForDebug;
6360
6468
  exports.registerNativeReactivity = registerNativeReactivity;
6361
6469
  exports.registerObjectForDebug = registerObjectForDebug;
6362
6470
  exports.renamed = renamed;
6471
+ exports.resolve = resolve;
6363
6472
  exports.root = root;
6364
6473
  exports.scan = scan;
6365
6474
  exports.setAt = setAt;
@@ -6375,4 +6484,4 @@ exports.untracked = untracked;
6375
6484
  exports.unwrap = unwrap;
6376
6485
  exports.watch = watch;
6377
6486
  exports.zip = zip;
6378
- //# sourceMappingURL=index-BFYK02LG.js.map
6487
+ //# sourceMappingURL=browser.cjs.map