mutts 1.0.0 → 1.0.2

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 (85) hide show
  1. package/README.md +24 -2
  2. package/dist/chunks/_tslib-C-cuVLvZ.js +73 -0
  3. package/dist/chunks/_tslib-C-cuVLvZ.js.map +1 -0
  4. package/dist/chunks/_tslib-CMEnd0VE.esm.js +68 -0
  5. package/dist/chunks/_tslib-CMEnd0VE.esm.js.map +1 -0
  6. package/dist/chunks/{decorator-BXsign4Z.js → decorator-D4DU97Zg.js} +70 -4
  7. package/dist/chunks/decorator-D4DU97Zg.js.map +1 -0
  8. package/dist/chunks/{decorator-CPbZNnsX.esm.js → decorator-GnHw1Az7.esm.js} +67 -5
  9. package/dist/chunks/decorator-GnHw1Az7.esm.js.map +1 -0
  10. package/dist/chunks/index-DBScoeCX.esm.js +1960 -0
  11. package/dist/chunks/index-DBScoeCX.esm.js.map +1 -0
  12. package/dist/chunks/index-DOTmXL89.js +1983 -0
  13. package/dist/chunks/index-DOTmXL89.js.map +1 -0
  14. package/dist/decorator.d.ts +58 -1
  15. package/dist/decorator.esm.js +1 -1
  16. package/dist/decorator.js +1 -1
  17. package/dist/destroyable.d.ts +42 -0
  18. package/dist/destroyable.esm.js +19 -1
  19. package/dist/destroyable.esm.js.map +1 -1
  20. package/dist/destroyable.js +19 -1
  21. package/dist/destroyable.js.map +1 -1
  22. package/dist/eventful.d.ts +10 -1
  23. package/dist/eventful.esm.js +5 -27
  24. package/dist/eventful.esm.js.map +1 -1
  25. package/dist/eventful.js +15 -37
  26. package/dist/eventful.js.map +1 -1
  27. package/dist/index.d.ts +52 -3
  28. package/dist/index.esm.js +3 -2
  29. package/dist/index.esm.js.map +1 -1
  30. package/dist/index.js +18 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/indexable.d.ts +26 -0
  33. package/dist/indexable.esm.js +6 -0
  34. package/dist/indexable.esm.js.map +1 -1
  35. package/dist/indexable.js +6 -0
  36. package/dist/indexable.js.map +1 -1
  37. package/dist/mutts.umd.js +1 -1
  38. package/dist/mutts.umd.js.map +1 -1
  39. package/dist/mutts.umd.min.js +1 -1
  40. package/dist/mutts.umd.min.js.map +1 -1
  41. package/dist/promiseChain.d.ts +10 -0
  42. package/dist/promiseChain.esm.js +6 -0
  43. package/dist/promiseChain.esm.js.map +1 -1
  44. package/dist/promiseChain.js +6 -0
  45. package/dist/promiseChain.js.map +1 -1
  46. package/dist/reactive.d.ts +258 -20
  47. package/dist/reactive.esm.js +4 -1454
  48. package/dist/reactive.esm.js.map +1 -1
  49. package/dist/reactive.js +29 -1466
  50. package/dist/reactive.js.map +1 -1
  51. package/dist/std-decorators.d.ts +35 -0
  52. package/dist/std-decorators.esm.js +36 -1
  53. package/dist/std-decorators.esm.js.map +1 -1
  54. package/dist/std-decorators.js +36 -1
  55. package/dist/std-decorators.js.map +1 -1
  56. package/docs/mixin.md +229 -0
  57. package/docs/reactive.md +7931 -458
  58. package/package.json +1 -2
  59. package/dist/chunks/decorator-BXsign4Z.js.map +0 -1
  60. package/dist/chunks/decorator-CPbZNnsX.esm.js.map +0 -1
  61. package/src/decorator.test.ts +0 -495
  62. package/src/decorator.ts +0 -205
  63. package/src/destroyable.test.ts +0 -155
  64. package/src/destroyable.ts +0 -158
  65. package/src/eventful.test.ts +0 -380
  66. package/src/eventful.ts +0 -69
  67. package/src/index.ts +0 -7
  68. package/src/indexable.test.ts +0 -388
  69. package/src/indexable.ts +0 -124
  70. package/src/promiseChain.test.ts +0 -201
  71. package/src/promiseChain.ts +0 -99
  72. package/src/reactive/array.test.ts +0 -923
  73. package/src/reactive/array.ts +0 -352
  74. package/src/reactive/core.test.ts +0 -1663
  75. package/src/reactive/core.ts +0 -866
  76. package/src/reactive/index.ts +0 -28
  77. package/src/reactive/interface.test.ts +0 -1477
  78. package/src/reactive/interface.ts +0 -231
  79. package/src/reactive/map.test.ts +0 -866
  80. package/src/reactive/map.ts +0 -162
  81. package/src/reactive/set.test.ts +0 -289
  82. package/src/reactive/set.ts +0 -142
  83. package/src/std-decorators.test.ts +0 -679
  84. package/src/std-decorators.ts +0 -182
  85. package/src/utils.ts +0 -52
@@ -2,9 +2,19 @@ type Resolved<T> = T extends Promise<infer U> ? Resolved<U> : T extends (...args
2
2
  [k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : Resolved<T[k]>;
3
3
  } : T;
4
4
  type PromiseAnd<T> = Resolved<T> & Promise<Resolved<T>>;
5
+ /**
6
+ * Type that transforms promises into chainable objects
7
+ * Allows calling methods directly on promise results without awaiting them first
8
+ */
5
9
  type PromiseChain<T> = T extends (...args: infer Args) => infer R ? PromiseAnd<(...args: Args) => PromiseChain<Resolved<R>>> : T extends object ? PromiseAnd<{
6
10
  [k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : PromiseChain<Resolved<T[k]>>;
7
11
  }> : Promise<Resolved<T>>;
12
+ /**
13
+ * Transforms a promise or value into a chainable object
14
+ * Allows calling methods directly on promise results without awaiting them first
15
+ * @param given - The promise or value to make chainable
16
+ * @returns A chainable version of the input
17
+ */
8
18
  declare function chainPromise<T>(given: Promise<T> | T): PromiseChain<T>;
9
19
 
10
20
  export { chainPromise };
@@ -47,6 +47,12 @@ function chainObject(given) {
47
47
  function chainable(x) {
48
48
  return x && ['function', 'object'].includes(typeof x);
49
49
  }
50
+ /**
51
+ * Transforms a promise or value into a chainable object
52
+ * Allows calling methods directly on promise results without awaiting them first
53
+ * @param given - The promise or value to make chainable
54
+ * @returns A chainable version of the input
55
+ */
50
56
  function chainPromise(given) {
51
57
  if (!chainable(given))
52
58
  return given;
@@ -1 +1 @@
1
- {"version":3,"file":"promiseChain.esm.js","sources":["../src/promiseChain.ts"],"sourcesContent":["type Resolved<T> = T extends Promise<infer U>\n\t? Resolved<U>\n\t: T extends (...args: infer Args) => infer R\n\t\t? (...args: Args) => Resolved<R>\n\t\t: T extends object\n\t\t\t? {\n\t\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : Resolved<T[k]>\n\t\t\t\t}\n\t\t\t: T\ntype PromiseAnd<T> = Resolved<T> & Promise<Resolved<T>>\nexport type PromiseChain<T> = T extends (...args: infer Args) => infer R\n\t? PromiseAnd<(...args: Args) => PromiseChain<Resolved<R>>>\n\t: T extends object\n\t\t? PromiseAnd<{\n\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : PromiseChain<Resolved<T[k]>>\n\t\t\t}>\n\t\t: Promise<Resolved<T>>\n\nconst forward =\n\t(name: string, target: any) =>\n\t(...args: any[]) => {\n\t\treturn target[name](...args)\n\t}\n\nconst alreadyChained = new WeakMap<any, PromiseChain<any>>()\nconst originals = new WeakMap<Promise<any>, any>()\n\nfunction cache(target: any, rv: PromiseChain<any>) {\n\toriginals.set(rv, target)\n\talreadyChained.set(target, rv)\n}\n\ntype ChainedFunction<T> = ((...args: any[]) => PromiseChain<T>) & {\n\tthen: Promise<T>['then']\n\tcatch: Promise<T>['catch']\n\tfinally: Promise<T>['finally']\n}\n\nconst promiseProxyHandler: ProxyHandler<ChainedFunction<any>> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain function',\n\tget(target, prop) {\n\t\tif (prop === Symbol.toStringTag) return 'PromiseProxy'\n\t\tif (typeof prop === 'string' && ['then', 'catch', 'finally'].includes(prop))\n\t\t\treturn target[prop as keyof typeof target]\n\t\treturn chainPromise(target.then((r) => r[prop as keyof typeof r]))\n\t},\n}\nconst promiseForward = (target: any) => ({\n\t// biome-ignore lint/suspicious/noThenProperty: This one is the whole point\n\tthen: forward('then', target),\n\tcatch: forward('catch', target),\n\tfinally: forward('finally', target),\n})\nconst objectProxyHandler: ProxyHandler<any> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain object',\n\tget(target, prop, receiver) {\n\t\tconst getter = Object.getOwnPropertyDescriptor(target, prop)?.get\n\t\tconst rv = getter ? getter.call(receiver) : target[prop]\n\t\t// Allows fct.call or fct.apply to bypass the chain system\n\t\tif (typeof target === 'function') return rv\n\t\treturn chainPromise(rv)\n\t},\n\tapply(target, thisArg, args) {\n\t\treturn chainPromise(target.apply(thisArg, args))\n\t},\n}\nfunction chainObject<T extends object | Function>(given: T): PromiseChain<T> {\n\tconst rv = new Proxy(given, objectProxyHandler) as PromiseChain<T>\n\tcache(given, rv)\n\treturn rv\n}\n\nfunction chainable(x: any): x is object | Function {\n\treturn x && ['function', 'object'].includes(typeof x)\n}\nexport function chainPromise<T>(given: Promise<T> | T): PromiseChain<T> {\n\tif (!chainable(given)) return given as PromiseChain<T>\n\tif (alreadyChained.has(given)) return alreadyChained.get(given) as PromiseChain<T>\n\tif (!(given instanceof Promise)) return chainObject(given)\n\t// @ts-expect-error It's ok as we check if it's an object above\n\tgiven = given.then((r) => (chainable(r) ? chainObject(r) : r))\n\tconst target = Object.assign(function (this: any, ...args: any[]) {\n\t\treturn chainPromise(\n\t\t\tgiven.then((r) => {\n\t\t\t\treturn this?.then\n\t\t\t\t\t? this.then((t: any) => (r as any).apply(t, args))\n\t\t\t\t\t: (r as any).apply(this, args)\n\t\t\t})\n\t\t)\n\t}, promiseForward(given)) as ChainedFunction<T>\n\tconst chained = new Proxy(\n\t\ttarget,\n\t\tpromiseProxyHandler as ProxyHandler<ChainedFunction<T>>\n\t) as PromiseChain<T>\n\tcache(given, chained as PromiseChain<any>)\n\treturn chained\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"promiseChain.esm.js","sources":["../src/promiseChain.ts"],"sourcesContent":["type Resolved<T> = T extends Promise<infer U>\n\t? Resolved<U>\n\t: T extends (...args: infer Args) => infer R\n\t\t? (...args: Args) => Resolved<R>\n\t\t: T extends object\n\t\t\t? {\n\t\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : Resolved<T[k]>\n\t\t\t\t}\n\t\t\t: T\ntype PromiseAnd<T> = Resolved<T> & Promise<Resolved<T>>\n/**\n * Type that transforms promises into chainable objects\n * Allows calling methods directly on promise results without awaiting them first\n */\nexport type PromiseChain<T> = T extends (...args: infer Args) => infer R\n\t? PromiseAnd<(...args: Args) => PromiseChain<Resolved<R>>>\n\t: T extends object\n\t\t? PromiseAnd<{\n\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : PromiseChain<Resolved<T[k]>>\n\t\t\t}>\n\t\t: Promise<Resolved<T>>\n\nconst forward =\n\t(name: string, target: any) =>\n\t(...args: any[]) => {\n\t\treturn target[name](...args)\n\t}\n\nconst alreadyChained = new WeakMap<any, PromiseChain<any>>()\nconst originals = new WeakMap<Promise<any>, any>()\n\nfunction cache(target: any, rv: PromiseChain<any>) {\n\toriginals.set(rv, target)\n\talreadyChained.set(target, rv)\n}\n\ntype ChainedFunction<T> = ((...args: any[]) => PromiseChain<T>) & {\n\tthen: Promise<T>['then']\n\tcatch: Promise<T>['catch']\n\tfinally: Promise<T>['finally']\n}\n\nconst promiseProxyHandler: ProxyHandler<ChainedFunction<any>> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain function',\n\tget(target, prop) {\n\t\tif (prop === Symbol.toStringTag) return 'PromiseProxy'\n\t\tif (typeof prop === 'string' && ['then', 'catch', 'finally'].includes(prop))\n\t\t\treturn target[prop as keyof typeof target]\n\t\treturn chainPromise(target.then((r) => r[prop as keyof typeof r]))\n\t},\n}\nconst promiseForward = (target: any) => ({\n\t// biome-ignore lint/suspicious/noThenProperty: This one is the whole point\n\tthen: forward('then', target),\n\tcatch: forward('catch', target),\n\tfinally: forward('finally', target),\n})\nconst objectProxyHandler: ProxyHandler<any> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain object',\n\tget(target, prop, receiver) {\n\t\tconst getter = Object.getOwnPropertyDescriptor(target, prop)?.get\n\t\tconst rv = getter ? getter.call(receiver) : target[prop]\n\t\t// Allows fct.call or fct.apply to bypass the chain system\n\t\tif (typeof target === 'function') return rv\n\t\treturn chainPromise(rv)\n\t},\n\tapply(target, thisArg, args) {\n\t\treturn chainPromise(target.apply(thisArg, args))\n\t},\n}\nfunction chainObject<T extends object | Function>(given: T): PromiseChain<T> {\n\tconst rv = new Proxy(given, objectProxyHandler) as PromiseChain<T>\n\tcache(given, rv)\n\treturn rv\n}\n\nfunction chainable(x: any): x is object | Function {\n\treturn x && ['function', 'object'].includes(typeof x)\n}\n/**\n * Transforms a promise or value into a chainable object\n * Allows calling methods directly on promise results without awaiting them first\n * @param given - The promise or value to make chainable\n * @returns A chainable version of the input\n */\nexport function chainPromise<T>(given: Promise<T> | T): PromiseChain<T> {\n\tif (!chainable(given)) return given as PromiseChain<T>\n\tif (alreadyChained.has(given)) return alreadyChained.get(given) as PromiseChain<T>\n\tif (!(given instanceof Promise)) return chainObject(given)\n\t// @ts-expect-error It's ok as we check if it's an object above\n\tgiven = given.then((r) => (chainable(r) ? chainObject(r) : r))\n\tconst target = Object.assign(function (this: any, ...args: any[]) {\n\t\treturn chainPromise(\n\t\t\tgiven.then((r) => {\n\t\t\t\treturn this?.then\n\t\t\t\t\t? this.then((t: any) => (r as any).apply(t, args))\n\t\t\t\t\t: (r as any).apply(this, args)\n\t\t\t})\n\t\t)\n\t}, promiseForward(given)) as ChainedFunction<T>\n\tconst chained = new Proxy(\n\t\ttarget,\n\t\tpromiseProxyHandler as ProxyHandler<ChainedFunction<T>>\n\t) as PromiseChain<T>\n\tcache(given, chained as PromiseChain<any>)\n\treturn chained\n}\n"],"names":[],"mappings":"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"}
@@ -49,6 +49,12 @@ function chainObject(given) {
49
49
  function chainable(x) {
50
50
  return x && ['function', 'object'].includes(typeof x);
51
51
  }
52
+ /**
53
+ * Transforms a promise or value into a chainable object
54
+ * Allows calling methods directly on promise results without awaiting them first
55
+ * @param given - The promise or value to make chainable
56
+ * @returns A chainable version of the input
57
+ */
52
58
  function chainPromise(given) {
53
59
  if (!chainable(given))
54
60
  return given;
@@ -1 +1 @@
1
- {"version":3,"file":"promiseChain.js","sources":["../src/promiseChain.ts"],"sourcesContent":["type Resolved<T> = T extends Promise<infer U>\n\t? Resolved<U>\n\t: T extends (...args: infer Args) => infer R\n\t\t? (...args: Args) => Resolved<R>\n\t\t: T extends object\n\t\t\t? {\n\t\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : Resolved<T[k]>\n\t\t\t\t}\n\t\t\t: T\ntype PromiseAnd<T> = Resolved<T> & Promise<Resolved<T>>\nexport type PromiseChain<T> = T extends (...args: infer Args) => infer R\n\t? PromiseAnd<(...args: Args) => PromiseChain<Resolved<R>>>\n\t: T extends object\n\t\t? PromiseAnd<{\n\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : PromiseChain<Resolved<T[k]>>\n\t\t\t}>\n\t\t: Promise<Resolved<T>>\n\nconst forward =\n\t(name: string, target: any) =>\n\t(...args: any[]) => {\n\t\treturn target[name](...args)\n\t}\n\nconst alreadyChained = new WeakMap<any, PromiseChain<any>>()\nconst originals = new WeakMap<Promise<any>, any>()\n\nfunction cache(target: any, rv: PromiseChain<any>) {\n\toriginals.set(rv, target)\n\talreadyChained.set(target, rv)\n}\n\ntype ChainedFunction<T> = ((...args: any[]) => PromiseChain<T>) & {\n\tthen: Promise<T>['then']\n\tcatch: Promise<T>['catch']\n\tfinally: Promise<T>['finally']\n}\n\nconst promiseProxyHandler: ProxyHandler<ChainedFunction<any>> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain function',\n\tget(target, prop) {\n\t\tif (prop === Symbol.toStringTag) return 'PromiseProxy'\n\t\tif (typeof prop === 'string' && ['then', 'catch', 'finally'].includes(prop))\n\t\t\treturn target[prop as keyof typeof target]\n\t\treturn chainPromise(target.then((r) => r[prop as keyof typeof r]))\n\t},\n}\nconst promiseForward = (target: any) => ({\n\t// biome-ignore lint/suspicious/noThenProperty: This one is the whole point\n\tthen: forward('then', target),\n\tcatch: forward('catch', target),\n\tfinally: forward('finally', target),\n})\nconst objectProxyHandler: ProxyHandler<any> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain object',\n\tget(target, prop, receiver) {\n\t\tconst getter = Object.getOwnPropertyDescriptor(target, prop)?.get\n\t\tconst rv = getter ? getter.call(receiver) : target[prop]\n\t\t// Allows fct.call or fct.apply to bypass the chain system\n\t\tif (typeof target === 'function') return rv\n\t\treturn chainPromise(rv)\n\t},\n\tapply(target, thisArg, args) {\n\t\treturn chainPromise(target.apply(thisArg, args))\n\t},\n}\nfunction chainObject<T extends object | Function>(given: T): PromiseChain<T> {\n\tconst rv = new Proxy(given, objectProxyHandler) as PromiseChain<T>\n\tcache(given, rv)\n\treturn rv\n}\n\nfunction chainable(x: any): x is object | Function {\n\treturn x && ['function', 'object'].includes(typeof x)\n}\nexport function chainPromise<T>(given: Promise<T> | T): PromiseChain<T> {\n\tif (!chainable(given)) return given as PromiseChain<T>\n\tif (alreadyChained.has(given)) return alreadyChained.get(given) as PromiseChain<T>\n\tif (!(given instanceof Promise)) return chainObject(given)\n\t// @ts-expect-error It's ok as we check if it's an object above\n\tgiven = given.then((r) => (chainable(r) ? chainObject(r) : r))\n\tconst target = Object.assign(function (this: any, ...args: any[]) {\n\t\treturn chainPromise(\n\t\t\tgiven.then((r) => {\n\t\t\t\treturn this?.then\n\t\t\t\t\t? this.then((t: any) => (r as any).apply(t, args))\n\t\t\t\t\t: (r as any).apply(this, args)\n\t\t\t})\n\t\t)\n\t}, promiseForward(given)) as ChainedFunction<T>\n\tconst chained = new Proxy(\n\t\ttarget,\n\t\tpromiseProxyHandler as ProxyHandler<ChainedFunction<T>>\n\t) as PromiseChain<T>\n\tcache(given, chained as PromiseChain<any>)\n\treturn chained\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"promiseChain.js","sources":["../src/promiseChain.ts"],"sourcesContent":["type Resolved<T> = T extends Promise<infer U>\n\t? Resolved<U>\n\t: T extends (...args: infer Args) => infer R\n\t\t? (...args: Args) => Resolved<R>\n\t\t: T extends object\n\t\t\t? {\n\t\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : Resolved<T[k]>\n\t\t\t\t}\n\t\t\t: T\ntype PromiseAnd<T> = Resolved<T> & Promise<Resolved<T>>\n/**\n * Type that transforms promises into chainable objects\n * Allows calling methods directly on promise results without awaiting them first\n */\nexport type PromiseChain<T> = T extends (...args: infer Args) => infer R\n\t? PromiseAnd<(...args: Args) => PromiseChain<Resolved<R>>>\n\t: T extends object\n\t\t? PromiseAnd<{\n\t\t\t\t[k in keyof T]: k extends 'then' | 'catch' | 'finally' ? T[k] : PromiseChain<Resolved<T[k]>>\n\t\t\t}>\n\t\t: Promise<Resolved<T>>\n\nconst forward =\n\t(name: string, target: any) =>\n\t(...args: any[]) => {\n\t\treturn target[name](...args)\n\t}\n\nconst alreadyChained = new WeakMap<any, PromiseChain<any>>()\nconst originals = new WeakMap<Promise<any>, any>()\n\nfunction cache(target: any, rv: PromiseChain<any>) {\n\toriginals.set(rv, target)\n\talreadyChained.set(target, rv)\n}\n\ntype ChainedFunction<T> = ((...args: any[]) => PromiseChain<T>) & {\n\tthen: Promise<T>['then']\n\tcatch: Promise<T>['catch']\n\tfinally: Promise<T>['finally']\n}\n\nconst promiseProxyHandler: ProxyHandler<ChainedFunction<any>> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain function',\n\tget(target, prop) {\n\t\tif (prop === Symbol.toStringTag) return 'PromiseProxy'\n\t\tif (typeof prop === 'string' && ['then', 'catch', 'finally'].includes(prop))\n\t\t\treturn target[prop as keyof typeof target]\n\t\treturn chainPromise(target.then((r) => r[prop as keyof typeof r]))\n\t},\n}\nconst promiseForward = (target: any) => ({\n\t// biome-ignore lint/suspicious/noThenProperty: This one is the whole point\n\tthen: forward('then', target),\n\tcatch: forward('catch', target),\n\tfinally: forward('finally', target),\n})\nconst objectProxyHandler: ProxyHandler<any> = {\n\t//@ts-expect-error\n\t[Symbol.toStringTag]: 'MutTs PromiseChain object',\n\tget(target, prop, receiver) {\n\t\tconst getter = Object.getOwnPropertyDescriptor(target, prop)?.get\n\t\tconst rv = getter ? getter.call(receiver) : target[prop]\n\t\t// Allows fct.call or fct.apply to bypass the chain system\n\t\tif (typeof target === 'function') return rv\n\t\treturn chainPromise(rv)\n\t},\n\tapply(target, thisArg, args) {\n\t\treturn chainPromise(target.apply(thisArg, args))\n\t},\n}\nfunction chainObject<T extends object | Function>(given: T): PromiseChain<T> {\n\tconst rv = new Proxy(given, objectProxyHandler) as PromiseChain<T>\n\tcache(given, rv)\n\treturn rv\n}\n\nfunction chainable(x: any): x is object | Function {\n\treturn x && ['function', 'object'].includes(typeof x)\n}\n/**\n * Transforms a promise or value into a chainable object\n * Allows calling methods directly on promise results without awaiting them first\n * @param given - The promise or value to make chainable\n * @returns A chainable version of the input\n */\nexport function chainPromise<T>(given: Promise<T> | T): PromiseChain<T> {\n\tif (!chainable(given)) return given as PromiseChain<T>\n\tif (alreadyChained.has(given)) return alreadyChained.get(given) as PromiseChain<T>\n\tif (!(given instanceof Promise)) return chainObject(given)\n\t// @ts-expect-error It's ok as we check if it's an object above\n\tgiven = given.then((r) => (chainable(r) ? chainObject(r) : r))\n\tconst target = Object.assign(function (this: any, ...args: any[]) {\n\t\treturn chainPromise(\n\t\t\tgiven.then((r) => {\n\t\t\t\treturn this?.then\n\t\t\t\t\t? this.then((t: any) => (r as any).apply(t, args))\n\t\t\t\t\t: (r as any).apply(this, args)\n\t\t\t})\n\t\t)\n\t}, promiseForward(given)) as ChainedFunction<T>\n\tconst chained = new Proxy(\n\t\ttarget,\n\t\tpromiseProxyHandler as ProxyHandler<ChainedFunction<T>>\n\t) as PromiseChain<T>\n\tcache(given, chained as PromiseChain<any>)\n\treturn chained\n}\n"],"names":[],"mappings":";;AAsBA,MAAM,OAAO,GACZ,CAAC,IAAY,EAAE,MAAW,KAC1B,CAAC,GAAG,IAAW,KAAI;IAClB,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;AAC7B,CAAC;AAEF,MAAM,cAAc,GAAG,IAAI,OAAO,EAA0B;AAC5D,MAAM,SAAS,GAAG,IAAI,OAAO,EAAqB;AAElD,SAAS,KAAK,CAAC,MAAW,EAAE,EAAqB,EAAA;AAChD,IAAA,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC;AACzB,IAAA,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;AAC/B;AAQA,MAAM,mBAAmB,GAAuC;;AAE/D,IAAA,CAAC,MAAM,CAAC,WAAW,GAAG,6BAA6B;IACnD,GAAG,CAAC,MAAM,EAAE,IAAI,EAAA;AACf,QAAA,IAAI,IAAI,KAAK,MAAM,CAAC,WAAW;AAAE,YAAA,OAAO,cAAc;AACtD,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1E,YAAA,OAAO,MAAM,CAAC,IAA2B,CAAC;AAC3C,QAAA,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAsB,CAAC,CAAC,CAAC;IACnE,CAAC;CACD;AACD,MAAM,cAAc,GAAG,CAAC,MAAW,MAAM;;AAExC,IAAA,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;AAC7B,IAAA,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;AAC/B,IAAA,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;AACnC,CAAA,CAAC;AACF,MAAM,kBAAkB,GAAsB;;AAE7C,IAAA,CAAC,MAAM,CAAC,WAAW,GAAG,2BAA2B;AACjD,IAAA,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAA;AACzB,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG;AACjE,QAAA,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;;QAExD,IAAI,OAAO,MAAM,KAAK,UAAU;AAAE,YAAA,OAAO,EAAE;AAC3C,QAAA,OAAO,YAAY,CAAC,EAAE,CAAC;IACxB,CAAC;AACD,IAAA,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAA;QAC1B,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;CACD;AACD,SAAS,WAAW,CAA8B,KAAQ,EAAA;IACzD,MAAM,EAAE,GAAG,IAAI,KAAK,CAAC,KAAK,EAAE,kBAAkB,CAAoB;AAClE,IAAA,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;AAChB,IAAA,OAAO,EAAE;AACV;AAEA,SAAS,SAAS,CAAC,CAAM,EAAA;AACxB,IAAA,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACtD;AACA;;;;;AAKG;AACG,SAAU,YAAY,CAAI,KAAqB,EAAA;AACpD,IAAA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAwB;AACtD,IAAA,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,CAAoB;AAClF,IAAA,IAAI,EAAE,KAAK,YAAY,OAAO,CAAC;AAAE,QAAA,OAAO,WAAW,CAAC,KAAK,CAAC;;AAE1D,IAAA,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,UAAqB,GAAG,IAAW,EAAA;QAC/D,OAAO,YAAY,CAClB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAI;YAChB,OAAO,IAAI,EAAE;AACZ,kBAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,KAAM,CAAS,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;kBAC9C,CAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QAChC,CAAC,CAAC,CACF;AACF,IAAA,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAuB;IAC/C,MAAM,OAAO,GAAG,IAAI,KAAK,CACxB,MAAM,EACN,mBAAuD,CACpC;AACpB,IAAA,KAAK,CAAC,KAAK,EAAE,OAA4B,CAAC;AAC1C,IAAA,OAAO,OAAO;AACf;;;;"}
@@ -1,11 +1,79 @@
1
- import { LegacyClassDecorator, ModernClassDecorator, LegacyPropertyDecorator, ModernGetterDecorator, ModernAccessorDecorator, GenericClassDecorator } from './decorator.js';
1
+ import { LegacyPropertyDecorator, ModernMethodDecorator, LegacyClassDecorator, ModernClassDecorator, ModernGetterDecorator, ModernAccessorDecorator, GenericClassDecorator } from './decorator.js';
2
2
 
3
+ /**
4
+ * Function type for dependency tracking in effects and computed values
5
+ * Restores the active effect context for dependency tracking
6
+ */
3
7
  type DependencyFunction = <T>(cb: () => T) => T;
8
+ /**
9
+ * Dependency access passed to user callbacks within effects/computed/watch
10
+ * Provides functions to track dependencies and information about the effect execution
11
+ */
12
+ interface DependencyAccess {
13
+ /**
14
+ * Tracks dependencies in the current effect context
15
+ * Use this for normal dependency tracking within the effect
16
+ * @example
17
+ * ```typescript
18
+ * effect(({ tracked }) => {
19
+ * // In async context, use tracked to restore dependency tracking
20
+ * await someAsyncOperation()
21
+ * const value = tracked(() => state.count) // Tracks state.count in this effect
22
+ * })
23
+ * ```
24
+ */
25
+ tracked: DependencyFunction;
26
+ /**
27
+ * Tracks dependencies in the parent effect context
28
+ * Use this when child effects should track dependencies in the parent,
29
+ * allowing parent cleanup to manage child effects while dependencies trigger the parent
30
+ * @example
31
+ * ```typescript
32
+ * effect(({ ascend }) => {
33
+ * const length = inputs.length
34
+ * if (length > 0) {
35
+ * ascend(() => {
36
+ * // Dependencies here are tracked in the parent effect
37
+ * inputs.forEach(item => console.log(item))
38
+ * })
39
+ * }
40
+ * })
41
+ * ```
42
+ */
43
+ ascend: DependencyFunction;
44
+ /**
45
+ * Indicates whether this is the initial execution of the effect
46
+ * - `true`: First execution when the effect is created
47
+ * - `false`: Subsequent executions triggered by dependency changes
48
+ * @example
49
+ * ```typescript
50
+ * effect(({ init }) => {
51
+ * if (init) {
52
+ * console.log('Effect initialized')
53
+ * // Setup code that should only run once
54
+ * } else {
55
+ * console.log('Effect re-ran due to dependency change')
56
+ * // Code that runs on every update
57
+ * }
58
+ * })
59
+ * ```
60
+ */
61
+ init: boolean;
62
+ }
63
+ /**
64
+ * Type for effect cleanup functions
65
+ */
4
66
  type ScopedCallback = () => void;
67
+ /**
68
+ * Type for property evolution events
69
+ */
5
70
  type PropEvolution = {
6
- type: 'set' | 'del' | 'add';
71
+ type: 'set' | 'del' | 'add' | 'invalidate';
7
72
  prop: any;
8
73
  };
74
+ /**
75
+ * Type for collection operation evolution events
76
+ */
9
77
  type BunchEvolution = {
10
78
  type: 'bunch';
11
79
  method: string;
@@ -15,12 +83,18 @@ type State = {
15
83
  evolution: Evolution;
16
84
  next: State;
17
85
  } | {};
86
+ /**
87
+ * Object containing internal reactive system state for debugging and profiling
88
+ */
18
89
  declare const profileInfo: any;
90
+ /**
91
+ * Error class for reactive system errors
92
+ */
19
93
  declare class ReactiveError extends Error {
20
94
  constructor(message: string);
21
95
  }
22
96
  /**
23
- * Options for the reactive system, can be configured at runtime
97
+ * Global options for the reactive system
24
98
  */
25
99
  declare const options: {
26
100
  /**
@@ -38,13 +112,36 @@ declare const options: {
38
112
  * @param target - The effect that is being triggered
39
113
  * @param caller - The effect that is calling the target
40
114
  */
41
- chain: (target: Function, caller?: Function) => void;
115
+ chain: (targets: Function[], caller?: Function) => void;
116
+ /**
117
+ * Debug purpose: called when an effect chain is started
118
+ * @param target - The effect that is being triggered
119
+ */
120
+ beginChain: (targets: Function[]) => void;
121
+ /**
122
+ * Debug purpose: called when an effect chain is ended
123
+ */
124
+ endChain: () => void;
125
+ /**
126
+ * Debug purpose: called when an object is touched
127
+ * @param obj - The object that is touched
128
+ * @param evolution - The type of change
129
+ * @param props - The properties that changed
130
+ * @param deps - The dependencies that changed
131
+ */
132
+ touched: (obj: any, evolution: Evolution, props?: any[], deps?: Set<ScopedCallback>) => void;
42
133
  /**
43
134
  * Debug purpose: maximum effect chain (like call stack max depth)
44
135
  * Used to prevent infinite loops
45
136
  * @default 100
46
137
  */
47
138
  maxEffectChain: number;
139
+ /**
140
+ * Debug purpose: maximum effect reaction (like call stack max depth)
141
+ * Used to prevent infinite loops
142
+ * @default 'throw'
143
+ */
144
+ maxEffectReaction: "throw" | "debug" | "warn";
48
145
  /**
49
146
  * Maximum depth for deep watching traversal
50
147
  * Used to prevent infinite recursion in circular references
@@ -57,58 +154,199 @@ declare const options: {
57
154
  * @default true
58
155
  */
59
156
  instanceMembers: boolean;
157
+ /**
158
+ * Ignore accessors (getters and setters) and only track direct properties
159
+ * @default true
160
+ */
161
+ ignoreAccessors: boolean;
60
162
  warn: (...args: any[]) => void;
61
163
  };
164
+ type EffectTracking = (obj: any, evolution: Evolution, prop: any) => void;
165
+ /**
166
+ * Registers a debug callback that is called when the current effect is triggered by a dependency change
167
+ *
168
+ * This function is useful for debugging purposes as it pin-points exactly which reactive property
169
+ * change triggered the effect. The callback receives information about:
170
+ * - The object that changed
171
+ * - The type of change (evolution)
172
+ * - The specific property that changed
173
+ *
174
+ * **Note:** The tracker callback is automatically removed after being called once. If you need
175
+ * to track multiple triggers, call `trackEffect` again within the effect.
176
+ *
177
+ * @param onTouch - Callback function that receives (obj, evolution, prop) when the effect is triggered
178
+ * @throws {Error} If called outside of an effect context
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const state = reactive({ count: 0, name: 'John' })
183
+ *
184
+ * effect(() => {
185
+ * // Register a tracker to see what triggers this effect
186
+ * trackEffect((obj, evolution, prop) => {
187
+ * console.log(`Effect triggered by:`, {
188
+ * object: obj,
189
+ * change: evolution.type,
190
+ * property: prop
191
+ * })
192
+ * })
193
+ *
194
+ * // Access reactive properties
195
+ * console.log(state.count, state.name)
196
+ * })
197
+ *
198
+ * state.count = 5
199
+ * // Logs: Effect triggered by: { object: state, change: 'set', property: 'count' }
200
+ * ```
201
+ */
202
+ declare function trackEffect(onTouch: EffectTracking): void;
203
+ /**
204
+ * Gets the current state of a reactive object for evolution tracking
205
+ * @param obj - The reactive object
206
+ * @returns The current state object
207
+ */
62
208
  declare function getState(obj: any): State;
63
- declare class ReactiveBase {
64
- constructor();
65
- }
209
+ declare let activeEffect: ScopedCallback | undefined;
210
+ /**
211
+ * Adds a cleanup function to be called when the current batch of effects completes
212
+ * @param cleanup - The cleanup function to add
213
+ */
214
+ declare function addBatchCleanup(cleanup: ScopedCallback): void;
215
+ /**
216
+ * Decorator that makes methods atomic - batches all effects triggered within the method
217
+ */
218
+ declare const atomic: LegacyPropertyDecorator<any> & ModernMethodDecorator<any> & (<Args extends any[], Return>(original: (...args: Args) => Return) => (...args: Args) => Return);
219
+ /**
220
+ * Base mixin for reactive classes that provides proper constructor reactivity
221
+ * Solves constructor reactivity issues in complex inheritance trees
222
+ */
223
+ declare const ReactiveBase: (new (...args: any[]) => {
224
+ [x: string]: any;
225
+ }) & (<Base>(base: abstract new (...args: any[]) => Base) => new (...args: any[]) => {
226
+ [x: string]: any;
227
+ } & Base);
228
+ /**
229
+ * Always-reactive mixin that makes classes inherently reactive
230
+ * Can be used as both a base class and a mixin function
231
+ */
232
+ declare const Reactive: (new (...args: any[]) => {
233
+ [x: string]: any;
234
+ }) & (<Base>(base: abstract new (...args: any[]) => Base) => new (...args: any[]) => {
235
+ [x: string]: any;
236
+ } & Base);
66
237
  declare function reactiveObject<T>(anyTarget: T): T;
238
+ /**
239
+ * Main decorator for making classes reactive
240
+ * Automatically makes class instances reactive when created
241
+ */
67
242
  declare const reactive: LegacyClassDecorator<new (...args: any[]) => any> & ModernClassDecorator<new (...args: any[]) => any> & typeof reactiveObject;
243
+ /**
244
+ * Gets the original, non-reactive object from a reactive proxy
245
+ * @param proxy - The reactive proxy
246
+ * @returns The original object
247
+ */
68
248
  declare function unwrap<T>(proxy: T): T;
249
+ /**
250
+ * Checks if an object is a reactive proxy
251
+ * @param obj - The object to check
252
+ * @returns True if the object is reactive
253
+ */
69
254
  declare function isReactive(obj: any): boolean;
70
- declare function untracked(fn: () => ScopedCallback | undefined | void): void;
255
+ /**
256
+ * Executes a function without tracking dependencies
257
+ * @param fn - The function to execute
258
+ */
259
+ declare function untracked<T>(fn: () => T): T;
71
260
  /**
72
261
  * @param fn - The effect function to run - provides the cleaner
73
262
  * @returns The cleanup function
74
263
  */
75
- declare function effect<Args extends any[]>(fn: (dep: DependencyFunction, ...args: Args) => ScopedCallback | undefined | void, ...args: Args): ScopedCallback;
76
264
  /**
77
- * Set of functions to test if an object is immutable
265
+ * Creates a reactive effect that automatically re-runs when dependencies change
266
+ * @param fn - The effect function that provides dependencies and may return a cleanup function
267
+ * @param args - Additional arguments that are forwarded to the effect function
268
+ * @returns A cleanup function to stop the effect
269
+ */
270
+ declare function effect<Args extends any[]>(fn: (access: DependencyAccess, ...args: Args) => ScopedCallback | undefined | void, ...args: Args): ScopedCallback;
271
+ /**
272
+ * Set of functions that test if objects are immutable
273
+ * Objects that pass these tests will not be made reactive
78
274
  */
79
275
  declare const immutables: Set<(tested: any) => boolean>;
80
276
  /**
81
- * Check if an object is marked as non-reactive (for testing purposes)
277
+ * Checks if an object is marked as non-reactive
82
278
  * @param obj - The object to check
83
- * @returns true if the object is marked as non-reactive
279
+ * @returns True if the object is non-reactive
84
280
  */
85
281
  declare function isNonReactive(obj: any): boolean;
86
282
 
87
283
  /**
88
- * When used in a computed property computation, it will register the callback to be called when the computed property is invalidated
284
+ * Registers a callback to be called when a computed property is invalidated
89
285
  * @param cb - The callback to register
90
286
  * @param warn - Whether to warn if used outside of a computed property
91
287
  */
92
288
  declare function invalidateComputed(cb: () => void, warn?: boolean): void;
93
- type ComputedFunction<T> = (dep: DependencyFunction) => T;
289
+ type ComputedFunction<T> = (dep: DependencyAccess) => T;
290
+ declare function computedFunction<T>(getter: ComputedFunction<T>): T;
94
291
  /**
95
- * Get the cached value of a computed function - cache is invalidated when the dependencies change
292
+ * Decorator and function for creating computed properties that cache their values
293
+ * Only recomputes when dependencies change
294
+ */
295
+ declare const computed: LegacyPropertyDecorator<any> & ModernGetterDecorator<any> & ModernAccessorDecorator<any> & typeof computedFunction & {
296
+ map: typeof computedMap;
297
+ memo: typeof computedMapMemo;
298
+ self: typeof selfReferencing;
299
+ };
300
+ /**
301
+ * Options for the watch function
96
302
  */
97
- declare const computed: LegacyPropertyDecorator<any> & ModernGetterDecorator<any> & ModernAccessorDecorator<any> & (<T>(getter: ComputedFunction<T>) => T);
98
303
  interface WatchOptions {
304
+ /** Whether to call the callback immediately */
99
305
  immediate?: boolean;
306
+ /** Whether to watch nested properties */
100
307
  deep?: boolean;
101
308
  }
102
- declare function watch<T>(value: (dep: DependencyFunction) => T, changed: (value: T, oldValue?: T) => void, options?: Omit<WatchOptions, 'deep'> & {
309
+ /**
310
+ * Watches a computed value and calls a callback when it changes
311
+ * @param value - Function that returns the value to watch
312
+ * @param changed - Callback to call when the value changes
313
+ * @param options - Watch options
314
+ * @returns Cleanup function to stop watching
315
+ */
316
+ declare function watch<T>(value: (dep: DependencyAccess) => T, changed: (value: T, oldValue?: T) => void, options?: Omit<WatchOptions, 'deep'> & {
103
317
  deep?: false;
104
318
  }): ScopedCallback;
105
- declare function watch<T extends object | any[]>(value: (dep: DependencyFunction) => T, changed: (value: T, oldValue?: T) => void, options?: Omit<WatchOptions, 'deep'> & {
319
+ /**
320
+ * Watches a computed value with deep watching enabled
321
+ * @param value - Function that returns the value to watch
322
+ * @param changed - Callback to call when the value changes
323
+ * @param options - Watch options with deep watching enabled
324
+ * @returns Cleanup function to stop watching
325
+ */
326
+ declare function watch<T extends object | any[]>(value: (dep: DependencyAccess) => T, changed: (value: T, oldValue?: T) => void, options?: Omit<WatchOptions, 'deep'> & {
106
327
  deep: true;
107
328
  }): ScopedCallback;
329
+ /**
330
+ * Watches a reactive object directly
331
+ * @param value - The reactive object to watch
332
+ * @param changed - Callback to call when the object changes
333
+ * @param options - Watch options
334
+ * @returns Cleanup function to stop watching
335
+ */
108
336
  declare function watch<T extends object | any[]>(value: T, changed: (value: T) => void, options?: WatchOptions): ScopedCallback;
109
337
  declare function unreactiveApplication<T extends object>(...args: (keyof T)[]): GenericClassDecorator<T>;
110
338
  declare function unreactiveApplication<T extends object>(obj: T): T;
339
+ /**
340
+ * Decorator that marks classes or properties as non-reactive
341
+ * Prevents objects from being made reactive
342
+ */
111
343
  declare const unreactive: LegacyClassDecorator<new (...args: any[]) => any> & ModernClassDecorator<new (...args: any[]) => any> & typeof unreactiveApplication;
344
+ declare function cleanedBy<T extends object>(obj: T, cleanup: ScopedCallback): T & {
345
+ cleanup: () => void;
346
+ };
347
+ declare function computedMap<T, U>(inputs: T[], compute: (input: T, index: number, oldValue?: U) => U, resize?: (newLength: number, oldLength: number) => void): U[];
348
+ declare function computedMapMemo<I, O>(inputs: I[] | (() => I[]), compute: (input: I) => O): O[];
349
+ declare function selfReferencing<T extends object>(compute: (dep: DependencyAccess) => T): T;
112
350
 
113
- export { ReactiveBase, ReactiveError, computed, effect, getState, immutables, invalidateComputed, isNonReactive, isReactive, profileInfo, reactive, options as reactiveOptions, unreactive, untracked, unwrap, watch };
114
- export type { ScopedCallback };
351
+ export { Reactive, ReactiveBase, ReactiveError, activeEffect, addBatchCleanup, atomic, cleanedBy, computed, effect, getState, immutables, invalidateComputed, isNonReactive, isReactive, profileInfo, reactive, options as reactiveOptions, trackEffect, unreactive, untracked, unwrap, watch };
352
+ export type { Evolution, ScopedCallback };