@rrjs/react-compat 0.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 (66) hide show
  1. package/README.md +130 -0
  2. package/dist/context.d.ts +14 -0
  3. package/dist/context.d.ts.map +1 -0
  4. package/dist/context.js +58 -0
  5. package/dist/context.js.map +1 -0
  6. package/dist/forwardRef.d.ts +13 -0
  7. package/dist/forwardRef.d.ts.map +1 -0
  8. package/dist/forwardRef.js +24 -0
  9. package/dist/forwardRef.js.map +1 -0
  10. package/dist/hooks/noop-hooks.d.ts +9 -0
  11. package/dist/hooks/noop-hooks.d.ts.map +1 -0
  12. package/dist/hooks/noop-hooks.js +60 -0
  13. package/dist/hooks/noop-hooks.js.map +1 -0
  14. package/dist/hooks/useCallback.d.ts +2 -0
  15. package/dist/hooks/useCallback.d.ts.map +1 -0
  16. package/dist/hooks/useCallback.js +34 -0
  17. package/dist/hooks/useCallback.js.map +1 -0
  18. package/dist/hooks/useContext.d.ts +3 -0
  19. package/dist/hooks/useContext.d.ts.map +1 -0
  20. package/dist/hooks/useContext.js +14 -0
  21. package/dist/hooks/useContext.js.map +1 -0
  22. package/dist/hooks/useEffect.d.ts +5 -0
  23. package/dist/hooks/useEffect.d.ts.map +1 -0
  24. package/dist/hooks/useEffect.js +38 -0
  25. package/dist/hooks/useEffect.js.map +1 -0
  26. package/dist/hooks/useId.d.ts +3 -0
  27. package/dist/hooks/useId.d.ts.map +1 -0
  28. package/dist/hooks/useId.js +28 -0
  29. package/dist/hooks/useId.js.map +1 -0
  30. package/dist/hooks/useImperativeHandle.d.ts +3 -0
  31. package/dist/hooks/useImperativeHandle.d.ts.map +1 -0
  32. package/dist/hooks/useImperativeHandle.js +52 -0
  33. package/dist/hooks/useImperativeHandle.js.map +1 -0
  34. package/dist/hooks/useLayoutEffect.d.ts +5 -0
  35. package/dist/hooks/useLayoutEffect.d.ts.map +1 -0
  36. package/dist/hooks/useLayoutEffect.js +43 -0
  37. package/dist/hooks/useLayoutEffect.js.map +1 -0
  38. package/dist/hooks/useMemo.d.ts +2 -0
  39. package/dist/hooks/useMemo.d.ts.map +1 -0
  40. package/dist/hooks/useMemo.js +18 -0
  41. package/dist/hooks/useMemo.js.map +1 -0
  42. package/dist/hooks/useReducer.d.ts +6 -0
  43. package/dist/hooks/useReducer.d.ts.map +1 -0
  44. package/dist/hooks/useReducer.js +21 -0
  45. package/dist/hooks/useReducer.js.map +1 -0
  46. package/dist/hooks/useRef.d.ts +5 -0
  47. package/dist/hooks/useRef.d.ts.map +1 -0
  48. package/dist/hooks/useRef.js +11 -0
  49. package/dist/hooks/useRef.js.map +1 -0
  50. package/dist/hooks/useState.d.ts +4 -0
  51. package/dist/hooks/useState.d.ts.map +1 -0
  52. package/dist/hooks/useState.js +29 -0
  53. package/dist/hooks/useState.js.map +1 -0
  54. package/dist/hooks/useSyncExternalStore.d.ts +4 -0
  55. package/dist/hooks/useSyncExternalStore.d.ts.map +1 -0
  56. package/dist/hooks/useSyncExternalStore.js +41 -0
  57. package/dist/hooks/useSyncExternalStore.js.map +1 -0
  58. package/dist/index.d.ts +20 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +17 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/instance.d.ts +18 -0
  63. package/dist/instance.d.ts.map +1 -0
  64. package/dist/instance.js +87 -0
  65. package/dist/instance.js.map +1 -0
  66. package/package.json +35 -0
package/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # @rrjs/react-compat
2
+
3
+ React hooks implemented on top of signals. Designed so React code translates with minimal changes: state is read through a getter (`count()` instead of `count`). Inside JSX the Babel plugin handles this automatically.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @rrjs/react-compat @rrjs/signals @rrjs/renderer
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```js
14
+ import { useState, useEffect, useMemo } from '@rrjs/react-compat'
15
+ import { h, mount } from '@rrjs/renderer'
16
+
17
+ function Counter() {
18
+ const [count, setCount] = useState(0)
19
+ const doubled = useMemo(() => count() * 2, [count])
20
+
21
+ useEffect(() => {
22
+ document.title = `Count: ${count()}`
23
+ }, [count])
24
+
25
+ return h('div', null,
26
+ h('p', null, () => `${count()} → ${doubled()}`),
27
+ h('button', { onClick: () => setCount(count() + 1) }, 'inc')
28
+ )
29
+ }
30
+
31
+ mount(Counter, document.getElementById('app'))
32
+ ```
33
+
34
+ ## Supported hooks
35
+
36
+ | Hook | Status | Notes |
37
+ |---|---|---|
38
+ | `useState` | ✓ | Returns `[getter, setter]`. Functional updaters supported. |
39
+ | `useReducer` | ✓ | Returns `[stateGetter, dispatch]`. Lazy init supported. |
40
+ | `useMemo` | ✓ | Returns a getter. Wrapped in `computed` — auto-tracks signals read inside. |
41
+ | `useCallback` | ✓ | Standard React behavior with dep array. |
42
+ | `useEffect` | ✓ | Fires post-paint via `MessageChannel`. Cleanup runs before next effect. |
43
+ | `useLayoutEffect` | ✓ | Fires synchronously before paint. |
44
+ | `useRef` | ✓ | Plain mutable box. |
45
+ | `useContext` | ✓ | Stack-based propagation. `createContext` + `Provider`. |
46
+ | `useId` | ✓ | Generates `:rN:`-style ids. Client-only. |
47
+ | `useImperativeHandle` | ✓ | Pairs with `forwardRef`. |
48
+ | `useSyncExternalStore` | ✓ | Subscribes to external stores (Redux, Zustand, etc.). |
49
+ | `useDeferredValue` | — | No-op; returns input as-is. |
50
+ | `useTransition` | — | No-op; runs synchronously. |
51
+
52
+ ## Forwarding refs
53
+
54
+ ```js
55
+ import { forwardRef, useRef } from '@rrjs/react-compat'
56
+
57
+ const FancyInput = forwardRef((props, ref) =>
58
+ h('input', { ref, type: 'text', ...props })
59
+ )
60
+
61
+ function Form() {
62
+ const inputRef = useRef(null)
63
+ return h(FancyInput, { ref: inputRef })
64
+ }
65
+ ```
66
+
67
+ ## Context
68
+
69
+ ```js
70
+ import { createContext, useContext } from '@rrjs/react-compat'
71
+
72
+ const ThemeContext = createContext('light')
73
+
74
+ function App() {
75
+ return h(ThemeContext.Provider, { value: 'dark' },
76
+ h(ThemedButton, null)
77
+ )
78
+ }
79
+
80
+ function ThemedButton() {
81
+ const theme = useContext(ThemeContext)
82
+ return h('button', { className: theme }, 'click')
83
+ }
84
+ ```
85
+
86
+ Nested providers are supported. Each `Provider` push is paired with a pop after children mount.
87
+
88
+ ## External stores (Redux, Zustand, etc.)
89
+
90
+ ```js
91
+ import { useSyncExternalStore } from '@rrjs/react-compat'
92
+
93
+ function Counter({ store }) {
94
+ const state = useSyncExternalStore(store.subscribe, store.getState)
95
+ return h('div', null, () => state().count)
96
+ }
97
+ ```
98
+
99
+ Same contract as React 18+. Any state library that ships React bindings using `useSyncExternalStore` should work.
100
+
101
+ ## Why getters instead of values
102
+
103
+ In React, `const [count, setCount] = useState(0)` makes `count` a plain number. That works because React re-runs the entire component function on every state change — the new value of `count` comes from the new render.
104
+
105
+ In a signal model, the component runs once. After that, `count` would be frozen at the initial value forever. To stay reactive without re-running the component, `count` must be a function that reads the live signal. So `count` is a getter: `count()`.
106
+
107
+ Inside JSX, the Babel plugin wraps `{count}` as `() => count`, and the renderer auto-invokes nested getters. So in JSX you write `{count}` the same as in React. Outside JSX (event handlers, useMemo factories, useEffect bodies), you call the getter: `count()`.
108
+
109
+ ## License
110
+ MIT License
111
+
112
+ Copyright (c) 2026 Saman Abaasi
113
+
114
+ Permission is hereby granted, free of charge, to any person obtaining a copy
115
+ of this software and associated documentation files (the "Software"), to deal
116
+ in the Software without restriction, including without limitation the rights
117
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
118
+ copies of the Software, and to permit persons to whom the Software is
119
+ furnished to do so, subject to the following conditions:
120
+
121
+ The above copyright notice and this permission notice shall be included in all
122
+ copies or substantial portions of the Software.
123
+
124
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
125
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
126
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
127
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
128
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
129
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
130
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ export interface Context<T> {
2
+ _id: symbol;
3
+ _defaultValue: T;
4
+ Provider: (props: {
5
+ value: T;
6
+ children: any;
7
+ }) => any;
8
+ }
9
+ export declare function createContext<T>(defaultValue: T): Context<T>;
10
+ export declare function pushContext(id: symbol, value: unknown): void;
11
+ export declare function popContext(id: symbol): void;
12
+ export declare function readContext<T>(context: Context<T>): T;
13
+ export declare function withProvider<T, R>(context: Context<T>, value: T, fn: () => R): R;
14
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,CAAC,CAAA;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAA;KAAE,KAAK,GAAG,CAAA;CACtD;AAKD,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAgB5D;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAO5D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK3C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAMrD;AAID,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,KAAK,EAAE,CAAC,EACR,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAOH"}
@@ -0,0 +1,58 @@
1
+ // ─── Context — Stack-Based Propagation ──────────────────────────────────────
2
+ // Without a VDOM tree to walk, we use mount-time scoping:
3
+ // - When a Provider mounts its children, it pushes its value onto the stack.
4
+ // - useContext reads the current top of the stack for that context.
5
+ // - When children finish mounting, the Provider pops its value.
6
+ //
7
+ // This works because mounting is synchronous and depth-first — the same property
8
+ // React relies on for hook positional ordering.
9
+ // One stack per context, keyed by the unique _id symbol
10
+ const contextStacks = new Map();
11
+ export function createContext(defaultValue) {
12
+ const id = Symbol('Context');
13
+ const Provider = (props) => {
14
+ pushContext(id, props.value);
15
+ // The renderer will call this and use the returned children.
16
+ // It's responsible for popping after the children finish mounting —
17
+ // we handle that via withProvider() below.
18
+ return props.children;
19
+ };
20
+ return {
21
+ _id: id,
22
+ _defaultValue: defaultValue,
23
+ Provider,
24
+ };
25
+ }
26
+ export function pushContext(id, value) {
27
+ let stack = contextStacks.get(id);
28
+ if (!stack) {
29
+ stack = [];
30
+ contextStacks.set(id, stack);
31
+ }
32
+ stack.push(value);
33
+ }
34
+ export function popContext(id) {
35
+ const stack = contextStacks.get(id);
36
+ if (stack && stack.length > 0) {
37
+ stack.pop();
38
+ }
39
+ }
40
+ export function readContext(context) {
41
+ const stack = contextStacks.get(context._id);
42
+ if (stack && stack.length > 0) {
43
+ return stack[stack.length - 1];
44
+ }
45
+ return context._defaultValue;
46
+ }
47
+ // Used by tests and the renderer to wrap a function call with a Provider's value.
48
+ // Pushes value before fn runs, pops after — even if fn throws.
49
+ export function withProvider(context, value, fn) {
50
+ pushContext(context._id, value);
51
+ try {
52
+ return fn();
53
+ }
54
+ finally {
55
+ popContext(context._id);
56
+ }
57
+ }
58
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,0DAA0D;AAC1D,+EAA+E;AAC/E,sEAAsE;AACtE,kEAAkE;AAClE,EAAE;AACF,iFAAiF;AACjF,gDAAgD;AAQhD,wDAAwD;AACxD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAqB,CAAA;AAElD,MAAM,UAAU,aAAa,CAAI,YAAe;IAC9C,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;IAE5B,MAAM,QAAQ,GAAG,CAAC,KAAkC,EAAE,EAAE;QACtD,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;QAC5B,6DAA6D;QAC7D,oEAAoE;QACpE,2CAA2C;QAC3C,OAAO,KAAK,CAAC,QAAQ,CAAA;IACvB,CAAC,CAAA;IAED,OAAO;QACL,GAAG,EAAE,EAAE;QACP,aAAa,EAAE,YAAY;QAC3B,QAAQ;KACT,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,KAAc;IACpD,IAAI,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,EAAE,CAAA;QACV,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACnC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,GAAG,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAI,OAAmB;IAChD,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC5C,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAM,CAAA;IACrC,CAAC;IACD,OAAO,OAAO,CAAC,aAAa,CAAA;AAC9B,CAAC;AAED,kFAAkF;AAClF,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAC1B,OAAmB,EACnB,KAAQ,EACR,EAAW;IAEX,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC/B,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { RefObject } from './hooks/useRef';
2
+ export type Ref<T> = ((instance: T | null) => void) | RefObject<T> | null;
3
+ export declare const FORWARD_REF: unique symbol;
4
+ export interface ForwardRefComponent<P, T> {
5
+ (props: P & {
6
+ ref?: Ref<T>;
7
+ }): any;
8
+ [FORWARD_REF]: true;
9
+ _render: (props: P, ref: Ref<T>) => any;
10
+ }
11
+ export declare function forwardRef<P, T>(render: (props: P, ref: Ref<T>) => any): ForwardRefComponent<P, T>;
12
+ export declare function isForwardRef(value: unknown): value is ForwardRefComponent<any, any>;
13
+ //# sourceMappingURL=forwardRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forwardRef.d.ts","sourceRoot":"","sources":["../src/forwardRef.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG/C,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;AAIzE,eAAO,MAAM,WAAW,eAAuB,CAAA;AAE/C,MAAM,WAAW,mBAAmB,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC,KAAK,EAAE,CAAC,GAAG;QAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG,GAAG,CAAA;IAClC,CAAC,WAAW,CAAC,EAAE,IAAI,CAAA;IACnB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAA;CACxC;AAOD,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GACrC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAY3B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAKnF"}
@@ -0,0 +1,24 @@
1
+ // The marker that lets the renderer know this is a forwardRef wrapper.
2
+ // We use a Symbol so it's unambiguous and cannot collide with user code.
3
+ export const FORWARD_REF = Symbol('forwardRef');
4
+ // forwardRef wraps a function component that accepts (props, ref) and returns
5
+ // a callable component that the renderer recognizes. When the renderer sees
6
+ // the FORWARD_REF marker, it extracts the ref prop and passes it as the second
7
+ // argument to the user's render function.
8
+ export function forwardRef(render) {
9
+ const component = ((props) => {
10
+ // Direct invocation path — extract ref, call user render.
11
+ // The renderer will normally take the FORWARD_REF path instead and
12
+ // call _render directly. This branch is for completeness.
13
+ const { ref, ...rest } = props;
14
+ return render(rest, ref ?? null);
15
+ });
16
+ component[FORWARD_REF] = true;
17
+ component._render = render;
18
+ return component;
19
+ }
20
+ export function isForwardRef(value) {
21
+ return (typeof value === 'function' &&
22
+ value[FORWARD_REF] === true);
23
+ }
24
+ //# sourceMappingURL=forwardRef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forwardRef.js","sourceRoot":"","sources":["../src/forwardRef.ts"],"names":[],"mappings":"AAKA,uEAAuE;AACvE,yEAAyE;AACzE,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;AAQ/C,8EAA8E;AAC9E,4EAA4E;AAC5E,+EAA+E;AAC/E,0CAA0C;AAE1C,MAAM,UAAU,UAAU,CACxB,MAAsC;IAEtC,MAAM,SAAS,GAAG,CAAC,CAAC,KAA2B,EAAE,EAAE;QACjD,0DAA0D;QAC1D,mEAAmE;QACnE,0DAA0D;QAC1D,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,KAAY,CAAA;QACrC,OAAO,MAAM,CAAC,IAAS,EAAE,GAAG,IAAI,IAAI,CAAC,CAAA;IACvC,CAAC,CAA8B,CAAA;IAE/B,SAAS,CAAC,WAAW,CAAC,GAAG,IAAI,CAAA;IAC7B,SAAS,CAAC,OAAO,GAAG,MAAM,CAAA;IAC1B,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,CACL,OAAO,KAAK,KAAK,UAAU;QAC1B,KAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CACrC,CAAA;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ type StartTransition = (fn: () => void) => void;
2
+ export declare function useTransition(): [() => boolean, StartTransition];
3
+ export declare function useDeferredValue<T>(value: T): T;
4
+ type EffectCleanup = void | (() => void);
5
+ type EffectFn = () => EffectCleanup;
6
+ export declare function useInsertionEffect(fn: EffectFn, deps?: ReadonlyArray<unknown>): void;
7
+ export declare function useDebugValue<T>(_value: T, _formatter?: (v: T) => any): void;
8
+ export {};
9
+ //# sourceMappingURL=noop-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noop-hooks.d.ts","sourceRoot":"","sources":["../../src/hooks/noop-hooks.ts"],"names":[],"mappings":"AAeA,KAAK,eAAe,GAAG,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAA;AAE/C,wBAAgB,aAAa,IAAI,CAAC,MAAM,OAAO,EAAE,eAAe,CAAC,CAMhE;AAWD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAE/C;AA6BD,KAAK,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAA;AACxC,KAAK,QAAQ,GAAG,MAAM,aAAa,CAAA;AAEnC,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAyBpF;AAOD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,IAAI,CAE5E"}
@@ -0,0 +1,60 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ export function useTransition() {
3
+ const isPending = () => false;
4
+ const startTransition = (fn) => {
5
+ fn();
6
+ };
7
+ return [isPending, startTransition];
8
+ }
9
+ // ─── useDeferredValue ────────────────────────────────────────────────────────
10
+ // In React, useDeferredValue returns a "stale" version of a value that updates
11
+ // only when the renderer has spare time. Used for typeahead inputs and similar
12
+ // patterns where intermediate values can be skipped.
13
+ //
14
+ // Without concurrent rendering, deferral has no meaning. We return the input
15
+ // value unchanged. Apps using useDeferredValue still work — they just get the
16
+ // fresh value immediately. No deferral, no batching of intermediate updates.
17
+ export function useDeferredValue(value) {
18
+ return value;
19
+ }
20
+ function depsChanged(next, prev) {
21
+ if (next === undefined || prev === undefined)
22
+ return true;
23
+ if (next.length !== prev.length)
24
+ return true;
25
+ for (let i = 0; i < next.length; i++) {
26
+ if (!Object.is(next[i], prev[i]))
27
+ return true;
28
+ }
29
+ return false;
30
+ }
31
+ export function useInsertionEffect(fn, deps) {
32
+ const instance = getCurrentInstance();
33
+ const i = instance.hookIndex++;
34
+ const existing = instance.hooks[i];
35
+ const makeEntry = (hook) => ({
36
+ cleanup: hook.cleanup,
37
+ run: () => {
38
+ const result = fn();
39
+ hook.cleanup = typeof result === 'function' ? result : null;
40
+ },
41
+ });
42
+ if (existing === undefined) {
43
+ const hook = { deps, cleanup: null };
44
+ instance.hooks[i] = hook;
45
+ instance.layoutEffects.push(makeEntry(hook));
46
+ return;
47
+ }
48
+ if (depsChanged(deps, existing.deps)) {
49
+ existing.deps = deps;
50
+ instance.layoutEffects.push(makeEntry(existing));
51
+ }
52
+ }
53
+ // ─── useDebugValue ───────────────────────────────────────────────────────────
54
+ // useDebugValue annotates custom hooks for React DevTools. It has no runtime
55
+ // behavior — purely a hint to the devtools layer about what to display.
56
+ // We have no DevTools integration. The hook is a true no-op.
57
+ export function useDebugValue(_value, _formatter) {
58
+ // Intentionally empty
59
+ }
60
+ //# sourceMappingURL=noop-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noop-hooks.js","sourceRoot":"","sources":["../../src/hooks/noop-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAA;AAiB7D,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,KAAK,CAAA;IAC7B,MAAM,eAAe,GAAoB,CAAC,EAAE,EAAE,EAAE;QAC9C,EAAE,EAAE,CAAA;IACN,CAAC,CAAA;IACD,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;AACrC,CAAC;AAED,gFAAgF;AAChF,+EAA+E;AAC/E,+EAA+E;AAC/E,qDAAqD;AACrD,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAE7E,MAAM,UAAU,gBAAgB,CAAI,KAAQ;IAC1C,OAAO,KAAK,CAAA;AACd,CAAC;AAiBD,SAAS,WAAW,CAClB,IAAwC,EACxC,IAAwC;IAExC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACzD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAKD,MAAM,UAAU,kBAAkB,CAAC,EAAY,EAAE,IAA6B;IAC5E,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAuC,CAAA;IAExE,MAAM,SAAS,GAAG,CAAC,IAA4B,EAAe,EAAE,CAAC,CAAC;QAChE,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,EAAE,GAAG,EAAE;YACR,MAAM,MAAM,GAAG,EAAE,EAAE,CAAA;YACnB,IAAI,CAAC,OAAO,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;QAC7D,CAAC;KACF,CAAC,CAAA;IAEF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,GAA2B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QAC5D,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QACxB,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5C,OAAM;IACR,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;QACpB,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;IAClD,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,6EAA6E;AAC7E,wEAAwE;AACxE,6DAA6D;AAE7D,MAAM,UAAU,aAAa,CAAI,MAAS,EAAE,UAA0B;IACpE,sBAAsB;AACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function useCallback<T extends (...args: any[]) => any>(fn: T, deps?: ReadonlyArray<unknown>): T;
2
+ //# sourceMappingURL=useCallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCallback.d.ts","sourceRoot":"","sources":["../../src/hooks/useCallback.ts"],"names":[],"mappings":"AA2BA,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAC3D,EAAE,EAAE,CAAC,EACL,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAC5B,CAAC,CAiBH"}
@@ -0,0 +1,34 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ function depsChanged(next, prev) {
3
+ if (next === undefined || prev === undefined)
4
+ return true;
5
+ if (next.length !== prev.length)
6
+ return true;
7
+ for (let i = 0; i < next.length; i++) {
8
+ if (!Object.is(next[i], prev[i]))
9
+ return true;
10
+ }
11
+ return false;
12
+ }
13
+ // useCallback caches a function reference between renders.
14
+ // Same dep-array semantics as useMemo, but the cached value IS the function
15
+ // rather than the result of calling it.
16
+ //
17
+ // In a snapshot-based hook model (which ours is, for React compatibility),
18
+ // useCallback is what prevents stale references when passing handlers down
19
+ // to memoized children — same role it plays in React.
20
+ export function useCallback(fn, deps) {
21
+ const instance = getCurrentInstance();
22
+ const i = instance.hookIndex++;
23
+ const existing = instance.hooks[i];
24
+ if (existing === undefined) {
25
+ instance.hooks[i] = { fn, deps };
26
+ return fn;
27
+ }
28
+ if (depsChanged(deps, existing.deps)) {
29
+ existing.fn = fn;
30
+ existing.deps = deps;
31
+ }
32
+ return existing.fn;
33
+ }
34
+ //# sourceMappingURL=useCallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCallback.js","sourceRoot":"","sources":["../../src/hooks/useCallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAOhD,SAAS,WAAW,CAClB,IAAwC,EACxC,IAAwC;IAExC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACzD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,2DAA2D;AAC3D,4EAA4E;AAC5E,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,sDAAsD;AAEtD,MAAM,UAAU,WAAW,CACzB,EAAK,EACL,IAA6B;IAE7B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAmC,CAAA;IAEpE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAwB,CAAA;QACtD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAA;QAChB,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;IACtB,CAAC;IAED,OAAO,QAAQ,CAAC,EAAE,CAAA;AACpB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Context } from '../context';
2
+ export declare function useContext<T>(context: Context<T>): T;
3
+ //# sourceMappingURL=useContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useContext.d.ts","sourceRoot":"","sources":["../../src/hooks/useContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,OAAO,EAAE,MAAM,YAAY,CAAA;AAYjD,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAEpD"}
@@ -0,0 +1,14 @@
1
+ import { readContext } from '../context';
2
+ // useContext does NOT need a hook slot.
3
+ // It just reads the current value from the global stack for this context.
4
+ // No state to persist between renders — the stack handles it.
5
+ //
6
+ // Note: this means useContext is the only React-shim hook that doesn't
7
+ // allocate a hookIndex slot. We deliberately do NOT call instance.hookIndex++
8
+ // because we want the hook to be callable conditionally without breaking
9
+ // positional ordering for other hooks. React works the same way: useContext
10
+ // doesn't store anything on the Fiber.
11
+ export function useContext(context) {
12
+ return readContext(context);
13
+ }
14
+ //# sourceMappingURL=useContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useContext.js","sourceRoot":"","sources":["../../src/hooks/useContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAW,MAAM,YAAY,CAAA;AAEjD,wCAAwC;AACxC,0EAA0E;AAC1E,8DAA8D;AAC9D,EAAE;AACF,uEAAuE;AACvE,8EAA8E;AAC9E,yEAAyE;AACzE,4EAA4E;AAC5E,uCAAuC;AAEvC,MAAM,UAAU,UAAU,CAAI,OAAmB;IAC/C,OAAO,WAAW,CAAC,OAAO,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,5 @@
1
+ type EffectCleanup = void | (() => void);
2
+ type EffectFn = () => EffectCleanup;
3
+ export declare function useEffect(fn: EffectFn, deps?: ReadonlyArray<unknown>): void;
4
+ export {};
5
+ //# sourceMappingURL=useEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEffect.d.ts","sourceRoot":"","sources":["../../src/hooks/useEffect.ts"],"names":[],"mappings":"AA2BA,KAAK,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAA;AACxC,KAAK,QAAQ,GAAG,MAAM,aAAa,CAAA;AAEnC,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAkB3E"}
@@ -0,0 +1,38 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ function depsChanged(next, prev) {
3
+ if (next === undefined || prev === undefined)
4
+ return true;
5
+ if (next.length !== prev.length)
6
+ return true;
7
+ for (let i = 0; i < next.length; i++) {
8
+ if (!Object.is(next[i], prev[i]))
9
+ return true;
10
+ }
11
+ return false;
12
+ }
13
+ export function useEffect(fn, deps) {
14
+ const instance = getCurrentInstance();
15
+ const i = instance.hookIndex++;
16
+ const existing = instance.hooks[i];
17
+ if (existing === undefined) {
18
+ // First render — always schedule. There are no prev deps to compare to.
19
+ instance.hooks[i] = { deps, cleanup: null };
20
+ instance.passiveEffects.push(makeEntry(instance.hooks[i], fn));
21
+ return;
22
+ }
23
+ // Subsequent render — only re-run if deps changed (or no deps given).
24
+ if (depsChanged(deps, existing.deps)) {
25
+ existing.deps = deps;
26
+ instance.passiveEffects.push(makeEntry(existing, fn));
27
+ }
28
+ }
29
+ function makeEntry(hook, fn) {
30
+ return {
31
+ cleanup: hook.cleanup,
32
+ run: () => {
33
+ const result = fn();
34
+ hook.cleanup = typeof result === 'function' ? result : null;
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=useEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEffect.js","sourceRoot":"","sources":["../../src/hooks/useEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAA;AAO7D,SAAS,WAAW,CAClB,IAAwC,EACxC,IAAwC;IAExC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACzD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAaD,MAAM,UAAU,SAAS,CAAC,EAAY,EAAE,IAA6B;IACnE,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAA8B,CAAA;IAE/D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,wEAAwE;QACxE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAmB,CAAA;QAC5D,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,CAAA;QAC/E,OAAM;IACR,CAAC;IAED,sEAAsE;IACtE,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;QACpB,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IACvD,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAmB,EAAE,EAAY;IAClD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,EAAE,GAAG,EAAE;YACR,MAAM,MAAM,GAAG,EAAE,EAAE,CAAA;YACnB,IAAI,CAAC,OAAO,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;QAC7D,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function useId(): string;
2
+ export declare function _resetIdCounter(): void;
3
+ //# sourceMappingURL=useId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useId.d.ts","sourceRoot":"","sources":["../../src/hooks/useId.ts"],"names":[],"mappings":"AAwBA,wBAAgB,KAAK,IAAI,MAAM,CAS9B;AAGD,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,28 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ // A global counter is the simplest correct implementation client-side.
3
+ // React 18 also uses a counter, though theirs encodes tree position
4
+ // for SSR/hydration matching. For pure client rendering, a counter is fine.
5
+ //
6
+ // React's id format is ":r0:", ":r1:", etc. We match the format so that
7
+ // any third-party library checking the format works the same way.
8
+ let nextId = 0;
9
+ function generateId() {
10
+ return `:r${(nextId++).toString(36)}:`;
11
+ }
12
+ // useId returns a stable unique string for each call site in each component.
13
+ // On the first render of a component, generate a fresh id.
14
+ // On any subsequent render of the same component instance, return the cached id.
15
+ // This is what makes <label htmlFor={id}> match <input id={id} /> across renders.
16
+ export function useId() {
17
+ const instance = getCurrentInstance();
18
+ const i = instance.hookIndex++;
19
+ if (instance.hooks[i] === undefined) {
20
+ instance.hooks[i] = { id: generateId() };
21
+ }
22
+ return instance.hooks[i].id;
23
+ }
24
+ // Exposed for testing — lets tests reset the counter for predictable assertions
25
+ export function _resetIdCounter() {
26
+ nextId = 0;
27
+ }
28
+ //# sourceMappingURL=useId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useId.js","sourceRoot":"","sources":["../../src/hooks/useId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAMhD,uEAAuE;AACvE,oEAAoE;AACpE,4EAA4E;AAC5E,EAAE;AACF,wEAAwE;AACxE,kEAAkE;AAElE,IAAI,MAAM,GAAG,CAAC,CAAA;AAEd,SAAS,UAAU;IACjB,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAA;AACxC,CAAC;AAED,6EAA6E;AAC7E,2DAA2D;AAC3D,iFAAiF;AACjF,kFAAkF;AAElF,MAAM,UAAU,KAAK;IACnB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,UAAU,EAAE,EAAe,CAAA;IACvD,CAAC;IAED,OAAQ,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAe,CAAC,EAAE,CAAA;AAC5C,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,CAAC,CAAA;AACZ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Ref } from '../forwardRef';
2
+ export declare function useImperativeHandle<T>(ref: Ref<T> | undefined, factory: () => T, deps?: ReadonlyArray<unknown>): void;
3
+ //# sourceMappingURL=useImperativeHandle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useImperativeHandle.d.ts","sourceRoot":"","sources":["../../src/hooks/useImperativeHandle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AA2BxC,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,EACvB,OAAO,EAAE,MAAM,CAAC,EAChB,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAC5B,IAAI,CAmCN"}
@@ -0,0 +1,52 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ function depsChanged(next, prev) {
3
+ if (next === undefined || prev === undefined)
4
+ return true;
5
+ if (next.length !== prev.length)
6
+ return true;
7
+ for (let i = 0; i < next.length; i++) {
8
+ if (!Object.is(next[i], prev[i]))
9
+ return true;
10
+ }
11
+ return false;
12
+ }
13
+ // useImperativeHandle customizes what a forwardRef ref exposes.
14
+ // Instead of attaching the raw DOM node, the parent gets a custom handle
15
+ // returned by the factory function.
16
+ //
17
+ // Timing: runs as a LAYOUT effect, before paint. This matches React's behavior —
18
+ // the parent's ref must be populated before any rendered output is visible,
19
+ // because useLayoutEffect in the PARENT might read from this ref immediately.
20
+ export function useImperativeHandle(ref, factory, deps) {
21
+ const instance = getCurrentInstance();
22
+ const i = instance.hookIndex++;
23
+ const existing = instance.hooks[i];
24
+ const attach = {
25
+ cleanup: existing?.cleanup ?? null,
26
+ run: () => {
27
+ if (!ref)
28
+ return;
29
+ const value = factory();
30
+ if (typeof ref === 'function') {
31
+ ref(value);
32
+ instance.hooks[i].cleanup = () => ref(null);
33
+ }
34
+ else if (typeof ref === 'object' && 'current' in ref) {
35
+ ref.current = value;
36
+ instance.hooks[i].cleanup = () => {
37
+ ref.current = null;
38
+ };
39
+ }
40
+ },
41
+ };
42
+ if (existing === undefined) {
43
+ instance.hooks[i] = { deps, cleanup: null };
44
+ instance.layoutEffects.push(attach);
45
+ return;
46
+ }
47
+ if (depsChanged(deps, existing.deps)) {
48
+ existing.deps = deps;
49
+ instance.layoutEffects.push(attach);
50
+ }
51
+ }
52
+ //# sourceMappingURL=useImperativeHandle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useImperativeHandle.js","sourceRoot":"","sources":["../../src/hooks/useImperativeHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAA;AAQ7D,SAAS,WAAW,CAClB,IAAwC,EACxC,IAAwC;IAExC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACzD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,gEAAgE;AAChE,yEAAyE;AACzE,oCAAoC;AACpC,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAC5E,8EAA8E;AAE9E,MAAM,UAAU,mBAAmB,CACjC,GAAuB,EACvB,OAAgB,EAChB,IAA6B;IAE7B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAwC,CAAA;IAEzE,MAAM,MAAM,GAAgB;QAC1B,OAAO,EAAE,QAAQ,EAAE,OAAO,IAAI,IAAI;QAClC,GAAG,EAAE,GAAG,EAAE;YACR,IAAI,CAAC,GAAG;gBAAE,OAAM;YAChB,MAAM,KAAK,GAAG,OAAO,EAAE,CAAA;YAEvB,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;gBAC9B,GAAG,CAAC,KAAK,CAAC,CAET;gBAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAA6B,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC3E,CAAC;iBAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;gBACvD,GAAG,CAAC,OAAO,GAAG,KAAK,CAClB;gBAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAA6B,CAAC,OAAO,GAAG,GAAG,EAAE;oBAC7D,GAAG,CAAC,OAAO,GAAG,IAAW,CAAA;gBAC3B,CAAC,CAAA;YACH,CAAC;QACH,CAAC;KACF,CAAA;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAA6B,CAAA;QACtE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACnC,OAAM;IACR,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;QACpB,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ type EffectCleanup = void | (() => void);
2
+ type EffectFn = () => EffectCleanup;
3
+ export declare function useLayoutEffect(fn: EffectFn, deps?: ReadonlyArray<unknown>): void;
4
+ export {};
5
+ //# sourceMappingURL=useLayoutEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLayoutEffect.d.ts","sourceRoot":"","sources":["../../src/hooks/useLayoutEffect.ts"],"names":[],"mappings":"AAmBA,KAAK,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAA;AACxC,KAAK,QAAQ,GAAG,MAAM,aAAa,CAAA;AAUnC,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAgBjF"}
@@ -0,0 +1,43 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ function depsChanged(next, prev) {
3
+ if (next === undefined || prev === undefined)
4
+ return true;
5
+ if (next.length !== prev.length)
6
+ return true;
7
+ for (let i = 0; i < next.length; i++) {
8
+ if (!Object.is(next[i], prev[i]))
9
+ return true;
10
+ }
11
+ return false;
12
+ }
13
+ // useLayoutEffect runs SYNCHRONOUSLY during the commit phase, BEFORE paint.
14
+ // This is the right hook for:
15
+ // - DOM measurement that affects layout (avoiding flicker)
16
+ // - Synchronous DOM mutations the user should not see partially applied
17
+ // - State updates that must complete before the user sees the screen
18
+ //
19
+ // The cost: it blocks paint. Use useEffect unless you have a specific reason.
20
+ export function useLayoutEffect(fn, deps) {
21
+ const instance = getCurrentInstance();
22
+ const i = instance.hookIndex++;
23
+ const existing = instance.hooks[i];
24
+ if (existing === undefined) {
25
+ instance.hooks[i] = { deps, cleanup: null };
26
+ instance.layoutEffects.push(makeEntry(instance.hooks[i], fn));
27
+ return;
28
+ }
29
+ if (depsChanged(deps, existing.deps)) {
30
+ existing.deps = deps;
31
+ instance.layoutEffects.push(makeEntry(existing, fn));
32
+ }
33
+ }
34
+ function makeEntry(hook, fn) {
35
+ return {
36
+ cleanup: hook.cleanup,
37
+ run: () => {
38
+ const result = fn();
39
+ hook.cleanup = typeof result === 'function' ? result : null;
40
+ },
41
+ };
42
+ }
43
+ //# sourceMappingURL=useLayoutEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLayoutEffect.js","sourceRoot":"","sources":["../../src/hooks/useLayoutEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAA;AAO7D,SAAS,WAAW,CAClB,IAAwC,EACxC,IAAwC;IAExC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACzD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAKD,4EAA4E;AAC5E,8BAA8B;AAC9B,6DAA6D;AAC7D,0EAA0E;AAC1E,uEAAuE;AACvE,EAAE;AACF,8EAA8E;AAE9E,MAAM,UAAU,eAAe,CAAC,EAAY,EAAE,IAA6B;IACzE,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAoC,CAAA;IAErE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAyB,CAAA;QAClE,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAwB,EAAE,EAAE,CAAC,CAAC,CAAA;QACpF,OAAM;IACR,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAA;QACpB,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IACtD,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAyB,EAAE,EAAY;IACxD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,EAAE,GAAG,EAAE;YACR,MAAM,MAAM,GAAG,EAAE,EAAE,CAAA;YACnB,IAAI,CAAC,OAAO,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;QAC7D,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function useMemo<T>(factory: () => T, _deps?: ReadonlyArray<unknown>): () => T;
2
+ //# sourceMappingURL=useMemo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMemo.d.ts","sourceRoot":"","sources":["../../src/hooks/useMemo.ts"],"names":[],"mappings":"AAcA,wBAAgB,OAAO,CAAC,CAAC,EACvB,OAAO,EAAE,MAAM,CAAC,EAChB,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAC7B,MAAM,CAAC,CAUT"}
@@ -0,0 +1,18 @@
1
+ import { computed } from '@rrjs/signals';
2
+ import { getCurrentInstance } from '../instance';
3
+ // useMemo wraps the factory in computed(), which auto-tracks signal reads.
4
+ // Returns the GETTER, not the value — for the same reason useState does.
5
+ // This allows chained useMemo and downstream effects to track changes.
6
+ //
7
+ // Inside JSX, the Babel plugin and the renderer's auto-unwrap make this transparent.
8
+ // Outside JSX, the developer calls the returned function: doubled().
9
+ export function useMemo(factory, _deps) {
10
+ const instance = getCurrentInstance();
11
+ const i = instance.hookIndex++;
12
+ if (instance.hooks[i] === undefined) {
13
+ const getter = computed(factory);
14
+ instance.hooks[i] = { getter };
15
+ }
16
+ return instance.hooks[i].getter;
17
+ }
18
+ //# sourceMappingURL=useMemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMemo.js","sourceRoot":"","sources":["../../src/hooks/useMemo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAMhD,2EAA2E;AAC3E,yEAAyE;AACzE,uEAAuE;AACvE,EAAE;AACF,qFAAqF;AACrF,qEAAqE;AAErE,MAAM,UAAU,OAAO,CACrB,OAAgB,EAChB,KAA8B;IAE9B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;QAChC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAoB,CAAA;IAClD,CAAC;IAED,OAAQ,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAoB,CAAC,MAAM,CAAA;AACrD,CAAC"}
@@ -0,0 +1,6 @@
1
+ type Reducer<S, A> = (state: S, action: A) => S;
2
+ type Dispatch<A> = (action: A) => void;
3
+ export declare function useReducer<S, A>(reducer: Reducer<S, A>, initialState: S): [() => S, Dispatch<A>];
4
+ export declare function useReducer<S, A, I>(reducer: Reducer<S, A>, initialArg: I, init: (arg: I) => S): [() => S, Dispatch<A>];
5
+ export {};
6
+ //# sourceMappingURL=useReducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReducer.d.ts","sourceRoot":"","sources":["../../src/hooks/useReducer.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,CAAA;AAC/C,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;AAuBtC,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,YAAY,EAAE,CAAC,GACd,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AACzB,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAChC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,UAAU,EAAE,CAAC,EACb,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAClB,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { createSignal } from '@rrjs/signals';
2
+ import { getCurrentInstance } from '../instance';
3
+ export function useReducer(reducer, initialArg, init) {
4
+ const instance = getCurrentInstance();
5
+ const i = instance.hookIndex++;
6
+ if (instance.hooks[i] === undefined) {
7
+ // Lazy initialisation if init is provided
8
+ // useReducer(reducer, props.initial, (initial) => ({ count: initial }))
9
+ const initialState = init !== undefined ? init(initialArg) : initialArg;
10
+ const [getter, setter] = createSignal(initialState);
11
+ const dispatch = (action) => {
12
+ const currentState = getter();
13
+ const nextState = reducer(currentState, action);
14
+ setter(nextState);
15
+ };
16
+ instance.hooks[i] = { getter, dispatch };
17
+ }
18
+ const hook = instance.hooks[i];
19
+ return [hook.getter, hook.dispatch];
20
+ }
21
+ //# sourceMappingURL=useReducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReducer.js","sourceRoot":"","sources":["../../src/hooks/useReducer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAmChD,MAAM,UAAU,UAAU,CACxB,OAAsB,EACtB,UAAe,EACf,IAAsB;IAEtB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,0CAA0C;QAC1C,wEAAwE;QACxE,MAAM,YAAY,GAAM,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;QAE1E,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAI,YAAY,CAAC,CAAA;QAEtD,MAAM,QAAQ,GAAgB,CAAC,MAAS,EAAE,EAAE;YAC1C,MAAM,YAAY,GAAG,MAAM,EAAE,CAAA;YAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;YAC/C,MAAM,CAAC,SAAS,CAAC,CAAA;QACnB,CAAC,CAAA;QAED,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAA0B,CAAA;IAClE,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAyB,CAAA;IACtD,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;AACrC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface RefObject<T> {
2
+ current: T;
3
+ }
4
+ export declare function useRef<T>(initial: T): RefObject<T>;
5
+ //# sourceMappingURL=useRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRef.d.ts","sourceRoot":"","sources":["../../src/hooks/useRef.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,OAAO,EAAE,CAAC,CAAA;CACX;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAUlD"}
@@ -0,0 +1,11 @@
1
+ import { getCurrentInstance } from '../instance';
2
+ export function useRef(initial) {
3
+ const instance = getCurrentInstance();
4
+ const i = instance.hookIndex++;
5
+ if (instance.hooks[i] === undefined) {
6
+ // First render — create the ref box
7
+ instance.hooks[i] = { current: initial };
8
+ }
9
+ return instance.hooks[i];
10
+ }
11
+ //# sourceMappingURL=useRef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRef.js","sourceRoot":"","sources":["../../src/hooks/useRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAMhD,MAAM,UAAU,MAAM,CAAI,OAAU;IAClC,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,oCAAoC;QACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAA;IAC1C,CAAC;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAC1B,CAAC"}
@@ -0,0 +1,4 @@
1
+ type SetStateAction<T> = T | ((prev: T) => T);
2
+ export declare function useState<T>(initial: T | (() => T)): [() => T, (action: SetStateAction<T>) => void];
3
+ export {};
4
+ //# sourceMappingURL=useState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useState.d.ts","sourceRoot":"","sources":["../../src/hooks/useState.ts"],"names":[],"mappings":"AAgBA,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;AAQ7C,wBAAgB,QAAQ,CAAC,CAAC,EACxB,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GACrB,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CA+BhD"}
@@ -0,0 +1,29 @@
1
+ import { createSignal } from '@rrjs/signals';
2
+ import { getCurrentInstance } from '../instance';
3
+ export function useState(initial) {
4
+ const instance = getCurrentInstance();
5
+ const i = instance.hookIndex++;
6
+ if (instance.hooks[i] === undefined) {
7
+ const initialValue = typeof initial === 'function'
8
+ ? initial()
9
+ : initial;
10
+ const [getter, setter] = createSignal(initialValue);
11
+ // The dispatch wrapper handles the functional updater form.
12
+ // setCount(c => c + 1) reads the current value through the getter,
13
+ // applies the updater, and writes the result.
14
+ const dispatch = (action) => {
15
+ if (typeof action === 'function') {
16
+ setter(action(getter()));
17
+ }
18
+ else {
19
+ setter(action);
20
+ }
21
+ };
22
+ instance.hooks[i] = { getter, setter, dispatch };
23
+ }
24
+ const hook = instance.hooks[i];
25
+ // Return the getter, not the value.
26
+ // The first element of the tuple is a function: count is () => number.
27
+ return [hook.getter, hook.dispatch];
28
+ }
29
+ //# sourceMappingURL=useState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useState.js","sourceRoot":"","sources":["../../src/hooks/useState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAuBhD,MAAM,UAAU,QAAQ,CACtB,OAAsB;IAEtB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,YAAY,GAChB,OAAO,OAAO,KAAK,UAAU;YAC3B,CAAC,CAAE,OAAmB,EAAE;YACxB,CAAC,CAAC,OAAO,CAAA;QAEb,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAI,YAAY,CAAC,CAAA;QAEtD,4DAA4D;QAC5D,mEAAmE;QACnE,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,CAAC,MAAyB,EAAQ,EAAE;YACnD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,MAAM,CAAE,MAAyB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;YAC9C,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,MAAM,CAAC,CAAA;YAChB,CAAC;QACH,CAAC,CAAA;QAED,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAqB,CAAA;IACrE,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAoB,CAAA;IAEjD,oCAAoC;IACpC,uEAAuE;IACvE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;AACrC,CAAC"}
@@ -0,0 +1,4 @@
1
+ type Subscribe = (onStoreChange: () => void) => () => void;
2
+ export declare function useSyncExternalStore<T>(subscribe: Subscribe, getSnapshot: () => T, _getServerSnapshot?: () => T): () => T;
3
+ export {};
4
+ //# sourceMappingURL=useSyncExternalStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSyncExternalStore.d.ts","sourceRoot":"","sources":["../../src/hooks/useSyncExternalStore.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG,CAAC,aAAa,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;AA2B1D,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,CAAC,EACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC,GAC3B,MAAM,CAAC,CAwBT"}
@@ -0,0 +1,41 @@
1
+ import { createSignal } from '@rrjs/signals';
2
+ import { getCurrentInstance } from '../instance';
3
+ // useSyncExternalStore is the React 18+ primitive that lets external state
4
+ // libraries (Redux, Zustand, Jotai, etc.) plug into a React-compatible
5
+ // rendering system.
6
+ //
7
+ // The contract:
8
+ // - subscribe(callback): the store calls `callback` whenever its value changes,
9
+ // and returns a function that unsubscribes the callback.
10
+ // - getSnapshot(): returns the current value synchronously.
11
+ //
12
+ // Our implementation bridges this to the signal world:
13
+ // 1. Read the initial snapshot.
14
+ // 2. Create a signal seeded with that snapshot.
15
+ // 3. Subscribe to the store. When it notifies, read a fresh snapshot
16
+ // and write it into the signal.
17
+ // 4. Return the signal's getter — components that read it auto-track.
18
+ //
19
+ // The third argument (getServerSnapshot) is accepted for API compatibility.
20
+ // We use it only for the initial value if we're in an SSR context — which
21
+ // we don't currently support, so we just ignore it client-side.
22
+ export function useSyncExternalStore(subscribe, getSnapshot, _getServerSnapshot) {
23
+ const instance = getCurrentInstance();
24
+ const i = instance.hookIndex++;
25
+ if (instance.hooks[i] === undefined) {
26
+ // Initial mount: snapshot, signal, subscription
27
+ const [getter, setter] = createSignal(getSnapshot());
28
+ const onStoreChange = () => {
29
+ const next = getSnapshot();
30
+ // The signal's same-value bailout handles unchanged snapshots correctly:
31
+ // Object.is(prev, next) means no notification fires, no DOM thrash.
32
+ setter(next);
33
+ };
34
+ const unsubscribe = subscribe(onStoreChange);
35
+ // Register cleanup to unsubscribe when the component unmounts.
36
+ instance.cleanup.push(unsubscribe);
37
+ instance.hooks[i] = { getter, unsubscribe };
38
+ }
39
+ return instance.hooks[i].getter;
40
+ }
41
+ //# sourceMappingURL=useSyncExternalStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSyncExternalStore.js","sourceRoot":"","sources":["../../src/hooks/useSyncExternalStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAU,MAAM,eAAe,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAShD,2EAA2E;AAC3E,uEAAuE;AACvE,oBAAoB;AACpB,EAAE;AACF,gBAAgB;AAChB,kFAAkF;AAClF,6DAA6D;AAC7D,8DAA8D;AAC9D,EAAE;AACF,uDAAuD;AACvD,kCAAkC;AAClC,kDAAkD;AAClD,uEAAuE;AACvE,qCAAqC;AACrC,wEAAwE;AACxE,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,gEAAgE;AAEhE,MAAM,UAAU,oBAAoB,CAClC,SAAoB,EACpB,WAAoB,EACpB,kBAA4B;IAE5B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAA;IAE9B,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,gDAAgD;QAChD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAI,WAAW,EAAE,CAAC,CAAA;QAEvD,MAAM,aAAa,GAAG,GAAG,EAAE;YACzB,MAAM,IAAI,GAAG,WAAW,EAAE,CAAA;YAC1B,yEAAyE;YACzE,oEAAoE;YACpE,MAAM,CAAC,IAAI,CAAC,CAAA;QACd,CAAC,CAAA;QAED,MAAM,WAAW,GAAG,SAAS,CAAC,aAAa,CAAC,CAAA;QAE5C,+DAA+D;QAC/D,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAElC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAiC,CAAA;IAC5E,CAAC;IAED,OAAQ,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAiC,CAAC,MAAM,CAAA;AAClE,CAAC"}
@@ -0,0 +1,20 @@
1
+ export { useRef } from './hooks/useRef';
2
+ export type { RefObject } from './hooks/useRef';
3
+ export { useState } from './hooks/useState';
4
+ export { useReducer } from './hooks/useReducer';
5
+ export { useMemo } from './hooks/useMemo';
6
+ export { useCallback } from './hooks/useCallback';
7
+ export { useEffect } from './hooks/useEffect';
8
+ export { useLayoutEffect } from './hooks/useLayoutEffect';
9
+ export { useContext } from './hooks/useContext';
10
+ export { useId } from './hooks/useId';
11
+ export { useImperativeHandle } from './hooks/useImperativeHandle';
12
+ export { useSyncExternalStore } from './hooks/useSyncExternalStore';
13
+ export { useTransition, useDeferredValue, useInsertionEffect, useDebugValue, } from './hooks/noop-hooks';
14
+ export { forwardRef, isForwardRef, FORWARD_REF } from './forwardRef';
15
+ export type { Ref, ForwardRefComponent } from './forwardRef';
16
+ export { createContext, withProvider, pushContext, popContext, } from './context';
17
+ export type { Context } from './context';
18
+ export { createInstance, withInstance, getCurrentInstance, setCurrentInstance, flushLayoutEffects, flushPassiveEffects, } from './instance';
19
+ export type { ComponentInstance, EffectEntry } from './instance';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAGnE,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,GACd,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACpE,YAAY,EAAE,GAAG,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAE5D,OAAO,EACL,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,GACX,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EACL,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ export { useRef } from './hooks/useRef';
2
+ export { useState } from './hooks/useState';
3
+ export { useReducer } from './hooks/useReducer';
4
+ export { useMemo } from './hooks/useMemo';
5
+ export { useCallback } from './hooks/useCallback';
6
+ export { useEffect } from './hooks/useEffect';
7
+ export { useLayoutEffect } from './hooks/useLayoutEffect';
8
+ export { useContext } from './hooks/useContext';
9
+ export { useId } from './hooks/useId';
10
+ export { useImperativeHandle } from './hooks/useImperativeHandle';
11
+ export { useSyncExternalStore } from './hooks/useSyncExternalStore';
12
+ // Documented no-ops — Tier 3 in the compatibility contract
13
+ export { useTransition, useDeferredValue, useInsertionEffect, useDebugValue, } from './hooks/noop-hooks';
14
+ export { forwardRef, isForwardRef, FORWARD_REF } from './forwardRef';
15
+ export { createContext, withProvider, pushContext, popContext, } from './context';
16
+ export { createInstance, withInstance, getCurrentInstance, setCurrentInstance, flushLayoutEffects, flushPassiveEffects, } from './instance';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAGvC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAEnE,2DAA2D;AAC3D,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,GACd,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAGpE,OAAO,EACL,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,GACX,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAA"}
@@ -0,0 +1,18 @@
1
+ export interface ComponentInstance {
2
+ hooks: any[];
3
+ hookIndex: number;
4
+ layoutEffects: EffectEntry[];
5
+ passiveEffects: EffectEntry[];
6
+ cleanup: Array<() => void>;
7
+ }
8
+ export interface EffectEntry {
9
+ run: () => void;
10
+ cleanup: (() => void) | null;
11
+ }
12
+ export declare function getCurrentInstance(): ComponentInstance;
13
+ export declare function setCurrentInstance(instance: ComponentInstance | null): void;
14
+ export declare function createInstance(): ComponentInstance;
15
+ export declare function withInstance<T>(instance: ComponentInstance, fn: () => T): T;
16
+ export declare function flushLayoutEffects(instance: ComponentInstance): void;
17
+ export declare function flushPassiveEffects(instance: ComponentInstance): void;
18
+ //# sourceMappingURL=instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAEhC,KAAK,EAAE,GAAG,EAAE,CAAA;IAEZ,SAAS,EAAE,MAAM,CAAA;IAEjB,aAAa,EAAE,WAAW,EAAE,CAAA;IAC5B,cAAc,EAAE,WAAW,EAAE,CAAA;IAE7B,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,IAAI,CAAA;IACf,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAA;CAC7B;AASD,wBAAgB,kBAAkB,IAAI,iBAAiB,CAQtD;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAE3E;AAID,wBAAgB,cAAc,IAAI,iBAAiB,CAQlD;AAQD,wBAAgB,YAAY,CAAC,CAAC,EAC5B,QAAQ,EAAE,iBAAiB,EAC3B,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CASH;AAsBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAapE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAerE"}
@@ -0,0 +1,87 @@
1
+ // ─── Types ──────────────────────────────────────────────────────────────────
2
+ // ─── The current rendering instance ─────────────────────────────────────────
3
+ // While a component function is running, this holds the instance whose hooks
4
+ // should be allocated to the next hook call. After the function returns,
5
+ // it goes back to null.
6
+ let currentInstance = null;
7
+ export function getCurrentInstance() {
8
+ if (!currentInstance) {
9
+ throw new Error('Hook called outside of a component. ' +
10
+ 'Hooks can only be called inside the body of a component function.');
11
+ }
12
+ return currentInstance;
13
+ }
14
+ export function setCurrentInstance(instance) {
15
+ currentInstance = instance;
16
+ }
17
+ // ─── Create a new component instance ────────────────────────────────────────
18
+ export function createInstance() {
19
+ return {
20
+ hooks: [],
21
+ hookIndex: 0,
22
+ layoutEffects: [],
23
+ passiveEffects: [],
24
+ cleanup: [],
25
+ };
26
+ }
27
+ // ─── Render lifecycle ───────────────────────────────────────────────────────
28
+ // Wraps a component function call with the proper instance setup.
29
+ // hookIndex resets to 0 — this is critical.
30
+ // If anything triggers a re-run (rare in our signal model but possible),
31
+ // hooks must be allocated from the same array slots, in the same order.
32
+ export function withInstance(instance, fn) {
33
+ const prev = currentInstance;
34
+ setCurrentInstance(instance);
35
+ instance.hookIndex = 0;
36
+ try {
37
+ return fn();
38
+ }
39
+ finally {
40
+ setCurrentInstance(prev);
41
+ }
42
+ }
43
+ // ─── Effect flushing ────────────────────────────────────────────────────────
44
+ // Called by the renderer after a component has finished its render phase
45
+ // and DOM mutations are committed. This is the "commit phase" equivalent.
46
+ //
47
+ // Layout effects run synchronously, before paint.
48
+ // Passive effects are scheduled via MessageChannel — they run in a new macro
49
+ // task after the browser has had the chance to paint.
50
+ // MessageChannel is the same mechanism React's Scheduler uses for the same reason:
51
+ // queueMicrotask runs BEFORE paint (microtask checkpoint), which is wrong for useEffect.
52
+ // MessageChannel posts a message that delivers in the NEXT macro task, after paint.
53
+ const channel = new MessageChannel();
54
+ const pendingPassiveFlushes = [];
55
+ channel.port1.onmessage = () => {
56
+ const flushes = pendingPassiveFlushes.splice(0);
57
+ for (const flush of flushes)
58
+ flush();
59
+ };
60
+ export function flushLayoutEffects(instance) {
61
+ // Run synchronously. Cleanup of previous effect, then run new effect.
62
+ // Order matters: all cleanups for stale effects fire before any new effect runs.
63
+ // We separate into two passes to match React's behavior.
64
+ const entries = instance.layoutEffects;
65
+ instance.layoutEffects = [];
66
+ for (const entry of entries) {
67
+ entry.cleanup?.();
68
+ }
69
+ for (const entry of entries) {
70
+ entry.run();
71
+ }
72
+ }
73
+ export function flushPassiveEffects(instance) {
74
+ // Schedule, don't run. Effects run in the next macro task — after paint.
75
+ pendingPassiveFlushes.push(() => {
76
+ const entries = instance.passiveEffects;
77
+ instance.passiveEffects = [];
78
+ for (const entry of entries) {
79
+ entry.cleanup?.();
80
+ }
81
+ for (const entry of entries) {
82
+ entry.run();
83
+ }
84
+ });
85
+ channel.port2.postMessage(null);
86
+ }
87
+ //# sourceMappingURL=instance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.js","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAmB/E,+EAA+E;AAC/E,6EAA6E;AAC7E,yEAAyE;AACzE,wBAAwB;AAExB,IAAI,eAAe,GAA6B,IAAI,CAAA;AAEpD,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,sCAAsC;YACtC,mEAAmE,CACpE,CAAA;IACH,CAAC;IACD,OAAO,eAAe,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAkC;IACnE,eAAe,GAAG,QAAQ,CAAA;AAC5B,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,aAAa,EAAE,EAAE;QACjB,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,EAAE;KACZ,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,kEAAkE;AAClE,4CAA4C;AAC5C,yEAAyE;AACzE,wEAAwE;AAExE,MAAM,UAAU,YAAY,CAC1B,QAA2B,EAC3B,EAAW;IAEX,MAAM,IAAI,GAAG,eAAe,CAAA;IAC5B,kBAAkB,CAAC,QAAQ,CAAC,CAAA;IAC5B,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAA;IACtB,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAA;IACb,CAAC;YAAS,CAAC;QACT,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;AACH,CAAC;AAGD,+EAA+E;AAC/E,yEAAyE;AACzE,0EAA0E;AAC1E,EAAE;AACF,kDAAkD;AAClD,6EAA6E;AAC7E,sDAAsD;AAEtD,mFAAmF;AACnF,yFAAyF;AACzF,oFAAoF;AACpF,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAA;AACpC,MAAM,qBAAqB,GAAsB,EAAE,CAAA;AAEnD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE;IAC7B,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAC/C,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,KAAK,EAAE,CAAA;AACtC,CAAC,CAAA;AAED,MAAM,UAAU,kBAAkB,CAAC,QAA2B;IAC5D,sEAAsE;IACtE,iFAAiF;IACjF,yDAAyD;IACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAA;IACtC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAA;IAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,CAAC,OAAO,EAAE,EAAE,CAAA;IACnB,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,CAAC,GAAG,EAAE,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAA2B;IAC7D,yEAAyE;IACzE,qBAAqB,CAAC,IAAI,CAAC,GAAG,EAAE;QAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAA;QACvC,QAAQ,CAAC,cAAc,GAAG,EAAE,CAAA;QAE5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,KAAK,CAAC,OAAO,EAAE,EAAE,CAAA;QACnB,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,KAAK,CAAC,GAAG,EAAE,CAAA;QACb,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@rrjs/react-compat",
3
+ "version": "0.1.0",
4
+ "description": "React hooks API on top of signals: useState, useEffect, useReducer, useContext, and more",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "prepublishOnly": "npm run build && npm test"
18
+ },
19
+ "dependencies": {
20
+ "@rrjs/signals": "^0.1.0"
21
+ },
22
+ "devDependencies": {
23
+ "vitest": "^1.0.0",
24
+ "jsdom": "^24.0.0",
25
+ "typescript": "^5.0.0"
26
+ },
27
+ "license": "MIT",
28
+ "author": "Saman Abaasi <samabaasii@gmail.com>",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/SamAbaasi/reactive-react.git",
32
+ "directory": "packages/react-compat"
33
+ },
34
+ "keywords": ["react", "hooks", "compatibility", "signals", "useState", "useEffect"]
35
+ }