signalium 1.0.1 → 1.1.0

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 (136) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +18 -0
  3. package/dist/cjs/config.d.ts +2 -2
  4. package/dist/cjs/config.d.ts.map +1 -1
  5. package/dist/cjs/config.js.map +1 -1
  6. package/dist/cjs/hooks.d.ts.map +1 -1
  7. package/dist/cjs/hooks.js +14 -2
  8. package/dist/cjs/hooks.js.map +1 -1
  9. package/dist/cjs/index.d.ts +1 -1
  10. package/dist/cjs/index.d.ts.map +1 -1
  11. package/dist/cjs/index.js +2 -1
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/internals/async.d.ts +1 -1
  14. package/dist/cjs/internals/async.d.ts.map +1 -1
  15. package/dist/cjs/internals/async.js +20 -15
  16. package/dist/cjs/internals/async.js.map +1 -1
  17. package/dist/cjs/internals/connect.d.ts.map +1 -1
  18. package/dist/cjs/internals/connect.js +6 -0
  19. package/dist/cjs/internals/connect.js.map +1 -1
  20. package/dist/cjs/internals/contexts.d.ts +9 -2
  21. package/dist/cjs/internals/contexts.d.ts.map +1 -1
  22. package/dist/cjs/internals/contexts.js +37 -3
  23. package/dist/cjs/internals/contexts.js.map +1 -1
  24. package/dist/cjs/internals/derived.d.ts +15 -5
  25. package/dist/cjs/internals/derived.d.ts.map +1 -1
  26. package/dist/cjs/internals/derived.js +11 -11
  27. package/dist/cjs/internals/derived.js.map +1 -1
  28. package/dist/cjs/internals/get.js +2 -2
  29. package/dist/cjs/internals/get.js.map +1 -1
  30. package/dist/cjs/internals/scheduling.d.ts +2 -0
  31. package/dist/cjs/internals/scheduling.d.ts.map +1 -1
  32. package/dist/cjs/internals/scheduling.js +16 -1
  33. package/dist/cjs/internals/scheduling.js.map +1 -1
  34. package/dist/cjs/internals/state.d.ts +2 -2
  35. package/dist/cjs/internals/state.d.ts.map +1 -1
  36. package/dist/cjs/internals/utils/equals.d.ts +2 -0
  37. package/dist/cjs/internals/utils/equals.d.ts.map +1 -1
  38. package/dist/cjs/internals/utils/equals.js +5 -3
  39. package/dist/cjs/internals/utils/equals.js.map +1 -1
  40. package/dist/cjs/react/context.d.ts.map +1 -1
  41. package/dist/cjs/react/context.js +5 -0
  42. package/dist/cjs/react/context.js.map +1 -1
  43. package/dist/cjs/react/provider.d.ts.map +1 -1
  44. package/dist/cjs/react/provider.js +0 -4
  45. package/dist/cjs/react/provider.js.map +1 -1
  46. package/dist/cjs/react/rendering.d.ts +2 -0
  47. package/dist/cjs/react/rendering.d.ts.map +1 -0
  48. package/dist/cjs/react/rendering.js +25 -0
  49. package/dist/cjs/react/rendering.js.map +1 -0
  50. package/dist/cjs/react/signal-value.d.ts +1 -1
  51. package/dist/cjs/react/signal-value.d.ts.map +1 -1
  52. package/dist/cjs/react/signal-value.js +4 -54
  53. package/dist/cjs/react/signal-value.js.map +1 -1
  54. package/dist/cjs/react/state.d.ts +2 -2
  55. package/dist/cjs/react/state.d.ts.map +1 -1
  56. package/dist/cjs/react/state.js.map +1 -1
  57. package/dist/cjs/types.d.ts +13 -1
  58. package/dist/cjs/types.d.ts.map +1 -1
  59. package/dist/esm/config.d.ts +2 -2
  60. package/dist/esm/config.d.ts.map +1 -1
  61. package/dist/esm/config.js.map +1 -1
  62. package/dist/esm/hooks.d.ts.map +1 -1
  63. package/dist/esm/hooks.js +14 -2
  64. package/dist/esm/hooks.js.map +1 -1
  65. package/dist/esm/index.d.ts +1 -1
  66. package/dist/esm/index.d.ts.map +1 -1
  67. package/dist/esm/index.js +1 -1
  68. package/dist/esm/index.js.map +1 -1
  69. package/dist/esm/internals/async.d.ts +1 -1
  70. package/dist/esm/internals/async.d.ts.map +1 -1
  71. package/dist/esm/internals/async.js +21 -16
  72. package/dist/esm/internals/async.js.map +1 -1
  73. package/dist/esm/internals/connect.d.ts.map +1 -1
  74. package/dist/esm/internals/connect.js +6 -0
  75. package/dist/esm/internals/connect.js.map +1 -1
  76. package/dist/esm/internals/contexts.d.ts +9 -2
  77. package/dist/esm/internals/contexts.d.ts.map +1 -1
  78. package/dist/esm/internals/contexts.js +35 -3
  79. package/dist/esm/internals/contexts.js.map +1 -1
  80. package/dist/esm/internals/derived.d.ts +15 -5
  81. package/dist/esm/internals/derived.d.ts.map +1 -1
  82. package/dist/esm/internals/derived.js +11 -11
  83. package/dist/esm/internals/derived.js.map +1 -1
  84. package/dist/esm/internals/get.js +2 -2
  85. package/dist/esm/internals/get.js.map +1 -1
  86. package/dist/esm/internals/scheduling.d.ts +2 -0
  87. package/dist/esm/internals/scheduling.d.ts.map +1 -1
  88. package/dist/esm/internals/scheduling.js +14 -0
  89. package/dist/esm/internals/scheduling.js.map +1 -1
  90. package/dist/esm/internals/state.d.ts +2 -2
  91. package/dist/esm/internals/state.d.ts.map +1 -1
  92. package/dist/esm/internals/utils/equals.d.ts +2 -0
  93. package/dist/esm/internals/utils/equals.d.ts.map +1 -1
  94. package/dist/esm/internals/utils/equals.js +2 -2
  95. package/dist/esm/internals/utils/equals.js.map +1 -1
  96. package/dist/esm/react/context.d.ts.map +1 -1
  97. package/dist/esm/react/context.js +5 -0
  98. package/dist/esm/react/context.js.map +1 -1
  99. package/dist/esm/react/provider.d.ts.map +1 -1
  100. package/dist/esm/react/provider.js +0 -4
  101. package/dist/esm/react/provider.js.map +1 -1
  102. package/dist/esm/react/rendering.d.ts +2 -0
  103. package/dist/esm/react/rendering.d.ts.map +1 -0
  104. package/dist/esm/react/rendering.js +19 -0
  105. package/dist/esm/react/rendering.js.map +1 -0
  106. package/dist/esm/react/signal-value.d.ts +1 -1
  107. package/dist/esm/react/signal-value.d.ts.map +1 -1
  108. package/dist/esm/react/signal-value.js +2 -19
  109. package/dist/esm/react/signal-value.js.map +1 -1
  110. package/dist/esm/react/state.d.ts +2 -2
  111. package/dist/esm/react/state.d.ts.map +1 -1
  112. package/dist/esm/react/state.js.map +1 -1
  113. package/dist/esm/types.d.ts +13 -1
  114. package/dist/esm/types.d.ts.map +1 -1
  115. package/package.json +1 -1
  116. package/src/__tests__/context.test.ts +55 -1
  117. package/src/__tests__/gc.test.ts +256 -0
  118. package/src/__tests__/utils/instrumented-hooks.ts +8 -11
  119. package/src/config.ts +5 -3
  120. package/src/hooks.ts +17 -3
  121. package/src/index.ts +8 -1
  122. package/src/internals/async.ts +13 -8
  123. package/src/internals/connect.ts +8 -0
  124. package/src/internals/contexts.ts +45 -5
  125. package/src/internals/derived.ts +25 -16
  126. package/src/internals/get.ts +2 -2
  127. package/src/internals/scheduling.ts +20 -0
  128. package/src/internals/state.ts +3 -3
  129. package/src/internals/utils/equals.ts +2 -2
  130. package/src/react/__tests__/contexts.test.tsx +20 -1
  131. package/src/react/context.ts +6 -0
  132. package/src/react/provider.tsx +0 -6
  133. package/src/react/rendering.ts +25 -0
  134. package/src/react/signal-value.ts +3 -26
  135. package/src/react/state.ts +3 -3
  136. package/src/types.ts +15 -1
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/internals/state.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAS1G,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAAiE;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IAEZ,OAAO,CAAC,UAAU,CAAoC;gBAE1C,KAAK,EAAE,CAAC,EAAE,MAAM,GAAE,YAAY,CAAC,CAAC,CAAqB,EAAE,IAAI,GAAE,MAAgB;IAOzF,GAAG,IAAI,CAAC;IAmBR,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC;IAI1B,IAAI,IAAI,CAAC;IAIT,GAAG,CAAC,KAAK,EAAE,CAAC;IAuBZ,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI;CAWlD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,QAUpD;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,YAAY,EAAE,CAAC,EACf,IAAI,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,GACnD,WAAW,CAAC,CAAC,CAAC,CAIhB"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/internals/state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AASvG,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAAiE;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IAEZ,OAAO,CAAC,UAAU,CAAoC;gBAE1C,KAAK,EAAE,CAAC,EAAE,MAAM,GAAE,YAAY,CAAC,CAAC,CAAqB,EAAE,IAAI,GAAE,MAAgB;IAOzF,GAAG,IAAI,CAAC;IAmBR,MAAM,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC;IAI1B,IAAI,IAAI,CAAC;IAIT,GAAG,CAAC,KAAK,EAAE,CAAC;IAuBZ,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI;CAWlD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,QAUpD;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,YAAY,EAAE,CAAC,EACf,IAAI,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,CAAC,GACnD,WAAW,CAAC,CAAC,CAAC,CAIhB"}
@@ -1,3 +1,5 @@
1
1
  import { SignalEquals } from '../../types.js';
2
+ export declare const DEFAULT_EQUALS: SignalEquals<unknown>;
3
+ export declare const FALSE_EQUALS: SignalEquals<unknown>;
2
4
  export declare const equalsFrom: <T>(equals: SignalEquals<T> | false | undefined) => SignalEquals<T>;
3
5
  //# sourceMappingURL=equals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"equals.d.ts","sourceRoot":"","sources":["../../../../src/internals/utils/equals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,eAAO,MAAM,UAAU,GAAI,CAAC,UAAU,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,SAAS,KAAG,YAAY,CAAC,CAAC,CAMzF,CAAC"}
1
+ {"version":3,"file":"equals.d.ts","sourceRoot":"","sources":["../../../../src/internals/utils/equals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,eAAO,MAAM,cAAc,EAAE,YAAY,CAAC,OAAO,CAAqB,CAAC;AACvE,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,OAAO,CAAe,CAAC;AAE/D,eAAO,MAAM,UAAU,GAAI,CAAC,UAAU,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,SAAS,KAAG,YAAY,CAAC,CAAC,CAMzF,CAAC"}
@@ -1,5 +1,5 @@
1
- const DEFAULT_EQUALS = (a, b) => a === b;
2
- const FALSE_EQUALS = () => false;
1
+ export const DEFAULT_EQUALS = (a, b) => a === b;
2
+ export const FALSE_EQUALS = () => false;
3
3
  export const equalsFrom = (equals) => {
4
4
  if (equals === false) {
5
5
  return FALSE_EQUALS;
@@ -1 +1 @@
1
- {"version":3,"file":"equals.js","sourceRoot":"","sources":["../../../../src/internals/utils/equals.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;AAChE,MAAM,YAAY,GAA0B,GAAG,EAAE,CAAC,KAAK,CAAC;AAExD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAI,MAA2C,EAAmB,EAAE;IAC5F,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,IAAI,cAAc,CAAC;AAClC,CAAC,CAAC"}
1
+ {"version":3,"file":"equals.js","sourceRoot":"","sources":["../../../../src/internals/utils/equals.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAA0B,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,YAAY,GAA0B,GAAG,EAAE,CAAC,KAAK,CAAC;AAE/D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAI,MAA2C,EAAmB,EAAE;IAC5F,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,IAAI,cAAc,CAAC;AAClC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/react/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,eAAO,MAAM,YAAY,kDAAoD,CAAC;AAE9E,wBAAgB,QAAQ,4BAEvB"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/react/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,eAAO,MAAM,YAAY,kDAAoD,CAAC;AAE9E,wBAAgB,QAAQ,4BAOvB"}
@@ -1,6 +1,11 @@
1
1
  import { createContext, useContext } from 'react';
2
+ import { isRendering } from './rendering.js';
2
3
  export const ScopeContext = createContext(undefined);
3
4
  export function useScope() {
5
+ if (!isRendering()) {
6
+ return undefined;
7
+ }
8
+ // eslint-disable-next-line react-hooks/rules-of-hooks
4
9
  return useContext(ScopeContext);
5
10
  }
6
11
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/react/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGlD,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAA0B,SAAS,CAAC,CAAC;AAE9E,MAAM,UAAU,QAAQ;IACtB,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/react/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAA0B,SAAS,CAAC,CAAC;AAE9E,MAAM,UAAU,QAAQ;IACtB,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,sDAAsD;IACtD,OAAO,UAAU,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAAe,MAAM,0BAA0B,CAAC;AAEjF,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,EACnD,QAAQ,EACR,QAAQ,EACR,OAAc,EACd,IAAY,GACb,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,2CAWA"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,WAAW,EAAe,MAAM,0BAA0B,CAAC;AAEjF,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,EACnD,QAAQ,EACR,QAAQ,EACR,OAAc,EACd,IAAY,GACb,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,2CAKA"}
@@ -3,10 +3,6 @@ import { useContext } from 'react';
3
3
  import { ScopeContext } from './context.js';
4
4
  import { SignalScope } from '../internals/contexts.js';
5
5
  export function ContextProvider({ children, contexts, inherit = true, root = false, }) {
6
- // if (root) {
7
- // useEffect(() => )
8
- // return <ScopeContext.Provider value={scope}>{children}</ScopeContext.Provider>;
9
- // }
10
6
  const parentScope = useContext(ScopeContext);
11
7
  const scope = new SignalScope(contexts, inherit ? parentScope : undefined);
12
8
  return _jsx(ScopeContext.Provider, { value: scope, children: children });
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA4B,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEjF,MAAM,UAAU,eAAe,CAAsB,EACnD,QAAQ,EACR,QAAQ,EACR,OAAO,GAAG,IAAI,EACd,IAAI,GAAG,KAAK,GAMb;IACC,cAAc;IACd,sBAAsB;IAEtB,oFAAoF;IACpF,IAAI;IAEJ,MAAM,WAAW,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,QAA6C,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEhH,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAC;AACjF,CAAC"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/react/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA4B,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEjF,MAAM,UAAU,eAAe,CAAsB,EACnD,QAAQ,EACR,QAAQ,EACR,OAAO,GAAG,IAAI,EACd,IAAI,GAAG,KAAK,GAMb;IACC,MAAM,WAAW,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,QAA6C,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEhH,OAAO,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAyB,CAAC;AACjF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function isRendering(): boolean;
2
+ //# sourceMappingURL=rendering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.d.ts","sourceRoot":"","sources":["../../../src/react/rendering.ts"],"names":[],"mappings":"AAcA,wBAAgB,WAAW,YAU1B"}
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ // This is a private React internal that we need to access to check if we are rendering.
3
+ // There is no other consistent way to check if we are rendering in both development
4
+ // and production, and it doesn't appear that the React team wants to add one. This
5
+ // should be checked on every major React version upgrade.
6
+ const REACT_INTERNALS = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ||
7
+ React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE ||
8
+ React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
9
+ const IS_REACT_18 = !!REACT_INTERNALS.ReactCurrentDispatcher;
10
+ const ReactCurrentDispatcher = REACT_INTERNALS.ReactCurrentDispatcher || REACT_INTERNALS;
11
+ export function isRendering() {
12
+ const dispatcher = IS_REACT_18 ? ReactCurrentDispatcher.current : ReactCurrentDispatcher.H;
13
+ return (!!dispatcher &&
14
+ // dispatcher can be in a state where it's defined, but all hooks are invalid to call.
15
+ // Only way we can tell is that if they are invalid, they will all be equal to each other
16
+ // (e.g. because it's the function that throws an error)
17
+ dispatcher.useState !== dispatcher.useEffect);
18
+ }
19
+ //# sourceMappingURL=rendering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.js","sourceRoot":"","sources":["../../../src/react/rendering.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,wFAAwF;AACxF,oFAAoF;AACpF,mFAAmF;AACnF,0DAA0D;AAC1D,MAAM,eAAe,GAClB,KAAa,CAAC,kDAAkD;IAChE,KAAa,CAAC,+DAA+D;IAC7E,KAAa,CAAC,+DAA+D,CAAC;AAEjF,MAAM,WAAW,GAAG,CAAC,CAAC,eAAe,CAAC,sBAAsB,CAAC;AAC7D,MAAM,sBAAsB,GAAG,eAAe,CAAC,sBAAsB,IAAI,eAAe,CAAC;AAEzF,MAAM,UAAU,WAAW;IACzB,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAE3F,OAAO,CACL,CAAC,CAAC,UAAU;QACZ,sFAAsF;QACtF,yFAAyF;QACzF,wDAAwD;QACxD,UAAU,CAAC,QAAQ,KAAK,UAAU,CAAC,SAAS,CAC7C,CAAC;AACJ,CAAC"}
@@ -2,5 +2,5 @@ import type { DerivedSignal } from '../internals/derived.js';
2
2
  import type { StateSignal } from '../internals/state.js';
3
3
  import type { ReactiveValue } from '../types.js';
4
4
  export declare function useStateSignal<T>(signal: StateSignal<T>): T;
5
- export declare function useDerivedSignal<T>(signal: DerivedSignal<T, unknown[]>): ReactiveValue<T>;
5
+ export declare function useDerivedSignal<T, Args extends unknown[]>(signal: DerivedSignal<T, Args>): ReactiveValue<T>;
6
6
  //# sourceMappingURL=signal-value.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signal-value.d.ts","sourceRoot":"","sources":["../../../src/react/signal-value.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA4BjD,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAU3D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CA4BzF"}
1
+ {"version":3,"file":"signal-value.d.ts","sourceRoot":"","sources":["../../../src/react/signal-value.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAU3D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CA4B5G"}
@@ -1,25 +1,8 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
- import React, { useCallback, useSyncExternalStore } from 'react';
2
+ import { useCallback, useSyncExternalStore } from 'react';
3
3
  import { isReactivePromise } from '../internals/utils/type-utils.js';
4
4
  import { isReactiveSubscription } from '../internals/async.js';
5
- // This is a private React internal that we need to access to check if we are rendering.
6
- // There is no other consistent way to check if we are rendering in both development
7
- // and production, and it doesn't appear that the React team wants to add one. This
8
- // should be checked on every major React version upgrade.
9
- const REACT_INTERNALS = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ||
10
- React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE ||
11
- React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
12
- const ReactCurrentDispatcher = REACT_INTERNALS.ReactCurrentDispatcher || REACT_INTERNALS;
13
- const ReactCurrentOwner = REACT_INTERNALS.ReactCurrentOwner || REACT_INTERNALS;
14
- const getReactCurrentDispatcher = () => {
15
- return ReactCurrentDispatcher.current || REACT_INTERNALS.H;
16
- };
17
- const getReactCurrentOwner = () => {
18
- return ReactCurrentOwner.current || REACT_INTERNALS.A;
19
- };
20
- function isRendering() {
21
- return !!getReactCurrentDispatcher() && !!getReactCurrentOwner();
22
- }
5
+ import { isRendering } from './rendering.js';
23
6
  export function useStateSignal(signal) {
24
7
  if (!isRendering()) {
25
8
  return signal.peek();
@@ -1 +1 @@
1
- {"version":3,"file":"signal-value.js","sourceRoot":"","sources":["../../../src/react/signal-value.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAIjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,wFAAwF;AACxF,oFAAoF;AACpF,mFAAmF;AACnF,0DAA0D;AAC1D,MAAM,eAAe,GAClB,KAAa,CAAC,kDAAkD;IAChE,KAAa,CAAC,+DAA+D;IAC7E,KAAa,CAAC,+DAA+D,CAAC;AAEjF,MAAM,sBAAsB,GAAG,eAAe,CAAC,sBAAsB,IAAI,eAAe,CAAC;AACzF,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,IAAI,eAAe,CAAC;AAE/E,MAAM,yBAAyB,GAAG,GAAG,EAAE;IACrC,OAAO,sBAAsB,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,GAAG,EAAE;IAChC,OAAO,iBAAiB,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,SAAS,WAAW;IAClB,OAAO,CAAC,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,cAAc,CAAI,MAAsB;IACtD,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,oBAAoB,CACzB,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EACzE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EACnB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAI,MAAmC;IACrE,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,oBAAoB,CAChC,MAAM,CAAC,eAAe,EAAE,EACxB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAClB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CACnB,CAAC;IAEF,8EAA8E;IAC9E,4EAA4E;IAC5E,0EAA0E;IAC1E,yBAAyB;IACzB,EAAE;IACF,4EAA4E;IAC5E,2EAA2E;IAC3E,qCAAqC;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5E,IAAI,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAkC,CAAC,CAAC;QACtE,CAAC;QAED,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,KAAyB,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"signal-value.js","sourceRoot":"","sources":["../../../src/react/signal-value.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAI1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,UAAU,cAAc,CAAI,MAAsB;IACtD,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,oBAAoB,CACzB,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EACzE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EACnB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAA4B,MAA8B;IACxF,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,oBAAoB,CAChC,MAAM,CAAC,eAAe,EAAE,EACxB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAClB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CACnB,CAAC;IAEF,8EAA8E;IAC9E,4EAA4E;IAC5E,0EAA0E;IAC1E,yBAAyB;IACzB,EAAE;IACF,4EAA4E;IAC5E,2EAA2E;IAC3E,qCAAqC;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5E,IAAI,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAkC,CAAC,CAAC;QACtE,CAAC;QAED,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,KAAyB,CAAC;AACnC,CAAC"}
@@ -1,3 +1,3 @@
1
- import { SignalOptions, WriteableSignal } from '../types.js';
2
- export declare function useStateSignal<T>(value: T, opts?: SignalOptions<T, unknown[]>): WriteableSignal<T>;
1
+ import { SignalOptions, StateSignal } from '../types.js';
2
+ export declare function useStateSignal<T>(value: T, opts?: SignalOptions<T, unknown[]>): StateSignal<T>;
3
3
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/react/state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAQlG"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/react/state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAQ9F"}
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/react/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,MAAM,UAAU,cAAc,CAAI,KAAQ,EAAE,IAAkC;IAC5E,MAAM,GAAG,GAAG,MAAM,CAAiC,SAAS,CAAC,CAAC;IAE9D,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/react/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGpC,MAAM,UAAU,cAAc,CAAI,KAAQ,EAAE,IAAkC;IAC5E,MAAM,GAAG,GAAG,MAAM,CAA6B,SAAS,CAAC,CAAC;IAE1D,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC"}
@@ -3,9 +3,15 @@ export interface Signal<T = unknown> {
3
3
  get(): T;
4
4
  addListener(listener: SignalListener): () => void;
5
5
  }
6
- export interface WriteableSignal<T> extends Signal<T> {
6
+ export interface StateSignal<T> extends Signal<T> {
7
7
  set(value: T): void;
8
+ peek(): T;
9
+ update(updater: (value: T) => T): void;
8
10
  }
11
+ /**
12
+ * @deprecated Use `StateSignal` instead.
13
+ */
14
+ export type WriteableSignal<T> = StateSignal<T>;
9
15
  export type SignalEquals<T> = (prev: T, next: T) => boolean;
10
16
  export type SignalListener = () => void;
11
17
  export type SignalSubscription = {
@@ -24,6 +30,12 @@ export interface SignalOptions<T, Args extends unknown[]> {
24
30
  desc?: string;
25
31
  scope?: SignalScope;
26
32
  paramKey?: (...args: Args) => string;
33
+ /**
34
+ * Called when signal's watchCount reaches 0.
35
+ * Return `true` to allow GC, `false` to prevent it.
36
+ * If not provided, defaults to always allowing GC.
37
+ */
38
+ shouldGC?: (signal: object, value: T, args: Args) => boolean;
27
39
  }
28
40
  export interface SignalOptionsWithInit<T, Args extends unknown[]> extends SignalOptions<T, Args> {
29
41
  initValue: T extends Promise<infer U> ? U : T extends Generator<any, infer U, any> ? U : T;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalium",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "repository": "https://github.com/pzuraq/signalium",
6
6
  "description": "Chain-reactivity at critical mass",
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, test } from 'vitest';
2
- import { createContext, useContext, withContexts, state } from '../index.js';
2
+ import { createContext, useContext, withContexts, state, setRootContexts } from '../index.js';
3
3
  import { permute } from './utils/permute.js';
4
4
  import { nextTick } from './utils/async.js';
5
5
  import { reactive } from './utils/instrumented-hooks.js';
@@ -11,6 +11,60 @@ describe('contexts', () => {
11
11
  }).toThrow('useContext must be used within a signal hook');
12
12
  });
13
13
 
14
+ test('setRootContexts sets contexts at the root level', () => {
15
+ const value = state('Hello');
16
+ const context = createContext(value);
17
+ const override = state('Hey');
18
+
19
+ // Create a reactive function that uses the context
20
+ const derived = reactive(() => `${useContext(context).get()}, World`);
21
+
22
+ // Initially should use default value
23
+ expect(derived()).toBe('Hello, World');
24
+
25
+ // Set root contexts
26
+ setRootContexts([[context, override]]);
27
+
28
+ // Should now use the override value
29
+ expect(derived()).toBe('Hey, World');
30
+
31
+ // Changes to override should be reflected
32
+ override.set('Hi');
33
+ expect(derived()).toBe('Hi, World');
34
+ });
35
+
36
+ test('setRootContexts with multiple contexts', () => {
37
+ const value1 = state('Hello');
38
+ const value2 = state('World');
39
+ const context1 = createContext(value1);
40
+ const context2 = createContext(value2);
41
+ const override1 = state('Hey');
42
+ const override2 = state('There');
43
+
44
+ const derived = reactive(() => `${useContext(context1).get()}, ${useContext(context2).get()}`);
45
+
46
+ // Initially should use default values
47
+ expect(derived()).toBe('Hello, World');
48
+
49
+ // Set multiple root contexts
50
+ setRootContexts([
51
+ [context1, override1],
52
+ [context2, override2],
53
+ ]);
54
+
55
+ expect(derived()).toBe('Hey, There');
56
+
57
+ // Changes to overrides should be reflected
58
+ override1.set('Hi');
59
+ override2.set('Everyone');
60
+ expect(derived()).toBe('Hi, Everyone');
61
+
62
+ // Changes to original values should not affect the result
63
+ value1.set('Bye');
64
+ value2.set('Earth');
65
+ expect(derived()).toBe('Hi, Everyone');
66
+ });
67
+
14
68
  test('async computed maintains context ownership across await boundaries', async () => {
15
69
  const ctx = createContext('default');
16
70
 
@@ -0,0 +1,256 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { reactive, createContext, withContexts, watcher, state } from '../index.js';
3
+ import { SignalScope, ROOT_SCOPE, forceGc, clearRootScope } from '../internals/contexts.js';
4
+ import { nextTick, sleep } from './utils/async.js';
5
+
6
+ // Helper to access private properties for testing
7
+ const getSignalsMap = (scope: SignalScope) => {
8
+ return (scope as any).signals as Map<number, any>;
9
+ };
10
+
11
+ const getGCCandidates = (scope: SignalScope) => {
12
+ return (scope as any).gcCandidates as Set<any>;
13
+ };
14
+
15
+ describe('Garbage Collection', () => {
16
+ beforeEach(() => {
17
+ clearRootScope();
18
+ });
19
+
20
+ it('should automatically garbage collect unwatched signals', async () => {
21
+ const testSignal = reactive(() => 42);
22
+
23
+ const w = watcher(() => testSignal());
24
+
25
+ // Watch the signal
26
+ const unwatch = w.addListener(() => {
27
+ testSignal();
28
+ });
29
+
30
+ await nextTick();
31
+
32
+ // Signal should be in the scope
33
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
34
+
35
+ // Unwatch the signal
36
+ unwatch();
37
+
38
+ await sleep(50);
39
+
40
+ // Signal should be garbage collected
41
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(0);
42
+ });
43
+
44
+ it('should not garbage collect signals with shouldGC returning false', async () => {
45
+ // Create a signal that should not be garbage collected
46
+ const persistentSignal = reactive(() => 'persist', {
47
+ shouldGC: () => false,
48
+ });
49
+
50
+ const w = watcher(() => persistentSignal());
51
+
52
+ // Watch the signal
53
+ const unwatch = w.addListener(() => {
54
+ persistentSignal();
55
+ });
56
+
57
+ await nextTick();
58
+
59
+ // Signal should be in the scope
60
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
61
+
62
+ // Unwatch the signal
63
+ unwatch();
64
+
65
+ await sleep(50);
66
+
67
+ // Signal should still be in the scope
68
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
69
+ });
70
+
71
+ it('should support conditional GC based on signal state', async () => {
72
+ // Create a signal with conditional GC
73
+ const shouldAllowGC = state(false);
74
+
75
+ const conditionalSignal = reactive(() => shouldAllowGC.get(), {
76
+ shouldGC: (signal, value) => {
77
+ // console.log('shouldGC', signal, value);
78
+ return value;
79
+ },
80
+ });
81
+
82
+ const w = watcher(() => conditionalSignal());
83
+
84
+ // Watch the signal
85
+ const unwatch = w.addListener(() => {
86
+ conditionalSignal();
87
+ });
88
+
89
+ await nextTick();
90
+
91
+ // Signal should be in the scope
92
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
93
+
94
+ // Unwatch the signal
95
+ unwatch();
96
+
97
+ await sleep(50);
98
+
99
+ // Signal should still be in the scope because shouldGC returns false
100
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
101
+
102
+ // Now allow GC
103
+ shouldAllowGC.set(true);
104
+
105
+ // Watch the signal
106
+ const unwatch2 = w.addListener(() => {
107
+ conditionalSignal();
108
+ });
109
+
110
+ await nextTick();
111
+
112
+ // Signal should be in GC candidates
113
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
114
+
115
+ unwatch2();
116
+
117
+ await sleep(50);
118
+
119
+ // Signal should be garbage collected
120
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(0);
121
+ });
122
+
123
+ it('should support manual garbage collection', async () => {
124
+ let signalObj: object;
125
+
126
+ // Create multiple signals
127
+ const signal1 = reactive(() => 'signal1');
128
+ const signal2 = reactive(() => 'signal2', {
129
+ shouldGC: signal => {
130
+ signalObj = signal;
131
+ return false;
132
+ },
133
+ });
134
+
135
+ const w1 = watcher(() => signal1());
136
+ const w2 = watcher(() => signal2());
137
+
138
+ // Watch both signals
139
+ const unwatch1 = w1.addListener(() => {
140
+ signal1();
141
+ });
142
+ const unwatch2 = w2.addListener(() => {
143
+ signal2();
144
+ });
145
+
146
+ await nextTick();
147
+
148
+ // Both signals should be in the scope
149
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(2);
150
+
151
+ // Unwatch both signals
152
+ unwatch1();
153
+ unwatch2();
154
+
155
+ await sleep(50);
156
+
157
+ // Only signal1 should be garbage collected
158
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
159
+
160
+ // The remaining signal should be signal2
161
+ const remainingSignal = Array.from(getSignalsMap(ROOT_SCOPE).values())[0];
162
+ expect(remainingSignal.get()).toBe('signal2');
163
+
164
+ forceGc(signalObj!);
165
+
166
+ await sleep(50);
167
+
168
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(0);
169
+ });
170
+
171
+ it('should not garbage collect signals that are still being watched', async () => {
172
+ // Create a signal
173
+ const watchedSignal = reactive(() => 'watched');
174
+
175
+ const w = watcher(() => watchedSignal());
176
+
177
+ // Watch the signal but don't unwatch
178
+ w.addListener(() => {
179
+ watchedSignal();
180
+ });
181
+
182
+ await nextTick();
183
+
184
+ // Signal should be in the scope
185
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
186
+
187
+ await sleep(50);
188
+
189
+ // Signal should still be in the scope because it's being watched
190
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
191
+ });
192
+
193
+ it('should handle context-scoped signals correctly', async () => {
194
+ // Create a context
195
+ const TestContext = createContext('test');
196
+
197
+ // Create signals in context
198
+ let contextSignal: any;
199
+
200
+ withContexts([[TestContext, 'value']], () => {
201
+ contextSignal = reactive(() => 'context-scoped');
202
+
203
+ const w = watcher(() => contextSignal());
204
+
205
+ // Watch and unwatch
206
+ const unwatch = w.addListener(() => {
207
+ contextSignal();
208
+ });
209
+
210
+ unwatch();
211
+ });
212
+
213
+ await nextTick();
214
+
215
+ // Get the context scope (this is a bit hacky for testing)
216
+ const contextScope = (ROOT_SCOPE as any).children.values().next().value;
217
+
218
+ await sleep(50);
219
+
220
+ // Signal should be garbage collected from the context scope
221
+ expect(getSignalsMap(contextScope).size).toBe(0);
222
+ });
223
+
224
+ it('should remove signal from GC candidates if watched again', async () => {
225
+ // Create a signal
226
+ const signal = reactive(() => 'rewatch');
227
+
228
+ const w = watcher(() => signal());
229
+
230
+ // Watch and unwatch
231
+ const unwatch = w.addListener(() => {
232
+ signal();
233
+ });
234
+
235
+ await nextTick();
236
+
237
+ // Signal should be in the scope
238
+ expect(getSignalsMap(ROOT_SCOPE).size).toBe(1);
239
+
240
+ unwatch();
241
+ await nextTick();
242
+
243
+ // Signal should be in GC candidates
244
+ expect(getGCCandidates(ROOT_SCOPE).size).toBe(1);
245
+
246
+ // Watch again
247
+ w.addListener(() => {
248
+ signal();
249
+ });
250
+
251
+ await nextTick();
252
+
253
+ // Signal should be removed from GC candidates
254
+ expect(getGCCandidates(ROOT_SCOPE).size).toBe(0);
255
+ });
256
+ });
@@ -9,7 +9,7 @@ import {
9
9
  } from '../../index.js';
10
10
  import { ReactiveTask, ReactiveValue, SignalOptionsWithInit, SignalSubscription } from '../../types.js';
11
11
  import { Context, ContextImpl, getCurrentScope, ROOT_SCOPE, SignalScope } from '../../internals/contexts.js';
12
- import { createDerivedSignal, DerivedSignal } from '../../internals/derived.js';
12
+ import { DerivedSignal } from '../../internals/derived.js';
13
13
  import { ReactivePromise } from '../../internals/async.js';
14
14
  import { hashValue } from '../../internals/utils/hash.js';
15
15
 
@@ -71,10 +71,10 @@ const WATCHERS = new WeakMap<Function, DerivedSignal<unknown, unknown[]>>();
71
71
 
72
72
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
73
73
  function getWatcherForHook(hook: Function) {
74
- let watcher = WATCHERS.get(hook);
74
+ let w = WATCHERS.get(hook);
75
75
 
76
- if (!watcher) {
77
- watcher = createDerivedSignal(
76
+ if (!w) {
77
+ w = watcher(
78
78
  () => {
79
79
  let result = hook();
80
80
 
@@ -84,18 +84,15 @@ function getWatcherForHook(hook: Function) {
84
84
 
85
85
  return result;
86
86
  },
87
- undefined,
88
- undefined,
89
- undefined,
90
87
  { desc: 'test' + TEST_ID++ },
91
- );
88
+ ) as DerivedSignal<unknown, unknown[]>;
92
89
 
93
- unsubs.push(watcher.addListener(() => {}));
90
+ unsubs.push(w.addListener(() => {}));
94
91
 
95
- WATCHERS.set(hook, watcher);
92
+ WATCHERS.set(hook, w);
96
93
  }
97
94
 
98
- return watcher;
95
+ return w;
99
96
  }
100
97
 
101
98
  function toHaveSignalValue(
package/src/config.ts CHANGED
@@ -14,7 +14,7 @@ interface SignalHooksConfig {
14
14
  runBatch: BatchFn;
15
15
  getFrameworkScope: () => SignalScope | undefined;
16
16
  useStateSignal: <T>(signal: StateSignal<T>) => T;
17
- useDerivedSignal: <T>(signal: DerivedSignal<T, unknown[]>) => ReactiveValue<T>;
17
+ useDerivedSignal: <T, Args extends unknown[]>(signal: DerivedSignal<T, Args>) => ReactiveValue<T>;
18
18
  }
19
19
 
20
20
  export let scheduleFlush: FlushFn = flushWatchers => {
@@ -28,9 +28,11 @@ export let runBatch: BatchFn = fn => fn();
28
28
  export let getFrameworkScope: () => SignalScope | undefined = () => undefined;
29
29
 
30
30
  let useFrameworkStateSignal: <T>(signal: StateSignal<T>) => T = signal => signal.get();
31
- let useFrameworkDerivedSignal: <T>(signal: DerivedSignal<T, unknown[]>) => ReactiveValue<T> = signal => signal.get();
31
+ let useFrameworkDerivedSignal: <T, Args extends unknown[]>(
32
+ signal: DerivedSignal<T, Args>,
33
+ ) => ReactiveValue<T> = signal => signal.get();
32
34
 
33
- export function useDerivedSignal<T>(signal: DerivedSignal<T, any[]>): ReactiveValue<T> {
35
+ export function useDerivedSignal<T, Args extends unknown[]>(signal: DerivedSignal<T, Args>): ReactiveValue<T> {
34
36
  if (CURRENT_CONSUMER !== undefined) {
35
37
  return signal.get();
36
38
  } else {