@pyreon/react-compat 0.13.1 → 0.15.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.
- package/README.md +20 -0
- package/lib/analysis/index.js.html +1 -1
- package/lib/analysis/jsx-runtime.js.html +1 -1
- package/lib/index.js +370 -40
- package/lib/jsx-runtime.js +57 -5
- package/lib/types/index.d.ts +205 -4
- package/package.json +8 -4
- package/src/env.d.ts +6 -0
- package/src/index.ts +549 -52
- package/src/jsx-runtime.ts +93 -2
- package/src/react-compat-rerender.browser.test.tsx +59 -0
- package/src/react-compat.browser.test.tsx +34 -0
- package/src/tests/compat-integration.test.tsx +1 -0
- package/src/tests/native-marker-bypass.test.tsx +88 -0
- package/src/tests/new-apis.test.ts +1519 -0
- package/src/tests/react-compat.test.ts +2 -0
- package/lib/dom.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/jsx-runtime.js.map +0 -1
- package/lib/types/dom.d.ts.map +0 -1
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/jsx-runtime.d.ts.map +0 -1
package/lib/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ErrorBoundary, Fragment, Props, Suspense, VNode, VNode as
|
|
1
|
+
import { CSSProperties, Context, ErrorBoundary, Fragment, Props, Suspense, VNode, VNode as VNode$1, VNodeChild, VNodeChild as VNodeChild$1, createRef, h, h as createElement, lazy } from "@pyreon/core";
|
|
2
2
|
import { batch } from "@pyreon/reactivity";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
@@ -9,8 +9,9 @@ import { batch } from "@pyreon/reactivity";
|
|
|
9
9
|
declare function useState<T>(initial: T | (() => T)): [T, (v: T | ((prev: T) => T)) => void];
|
|
10
10
|
/**
|
|
11
11
|
* React-compatible `useReducer` — returns `[state, dispatch]`.
|
|
12
|
+
* Supports the 3-argument form: `useReducer(reducer, initialArg, init)`.
|
|
12
13
|
*/
|
|
13
|
-
declare function useReducer<S, A>(reducer: (state: S, action: A) => S,
|
|
14
|
+
declare function useReducer<S, A>(reducer: (state: S, action: A) => S, initialArg: S | (() => S), init?: (arg: S) => S): [S, (action: A) => void];
|
|
14
15
|
/**
|
|
15
16
|
* React-compatible `useEffect` — runs after render when deps change.
|
|
16
17
|
* Returns cleanup on unmount and before re-running.
|
|
@@ -20,6 +21,11 @@ declare function useEffect(fn: () => (() => void) | void, deps?: unknown[]): voi
|
|
|
20
21
|
* React-compatible `useLayoutEffect` — runs synchronously after DOM mutations.
|
|
21
22
|
*/
|
|
22
23
|
declare function useLayoutEffect(fn: () => (() => void) | void, deps?: unknown[]): void;
|
|
24
|
+
/**
|
|
25
|
+
* React-compatible `useInsertionEffect` — runs synchronously before layout effects.
|
|
26
|
+
* Intended for CSS-in-JS libraries to inject styles before DOM reads.
|
|
27
|
+
*/
|
|
28
|
+
declare function useInsertionEffect(fn: () => (() => void) | void, deps?: unknown[]): void;
|
|
23
29
|
/**
|
|
24
30
|
* React-compatible `useMemo` — returns the cached value, recomputed when deps change.
|
|
25
31
|
*/
|
|
@@ -34,6 +40,48 @@ declare function useCallback<T extends (...args: never[]) => unknown>(fn: T, dep
|
|
|
34
40
|
declare function useRef<T>(initial?: T): {
|
|
35
41
|
current: T | null;
|
|
36
42
|
};
|
|
43
|
+
declare const COMPAT_CTX: unique symbol;
|
|
44
|
+
/**
|
|
45
|
+
* Compat-specific context with subscriber notification and tree-scoped nesting.
|
|
46
|
+
*
|
|
47
|
+
* Uses Pyreon's native context stack for tree-scoped Provider nesting (inner
|
|
48
|
+
* Providers override outer ones for their subtree), with a subscriber set
|
|
49
|
+
* layered on top for React-style consumer re-rendering.
|
|
50
|
+
*/
|
|
51
|
+
interface CompatContext<T> {
|
|
52
|
+
/** Brand marker so `useContext` can distinguish compat contexts */
|
|
53
|
+
readonly [COMPAT_CTX_BRAND]: true;
|
|
54
|
+
/** Default value when no Provider is mounted */
|
|
55
|
+
_defaultValue: T;
|
|
56
|
+
/** Pyreon native context for tree-scoped value+subscriber storage */
|
|
57
|
+
_pyreonCtx: Context<{
|
|
58
|
+
value: T;
|
|
59
|
+
subscribers: Set<() => void>;
|
|
60
|
+
}>;
|
|
61
|
+
/** Subscribers at the default (no-Provider) level */
|
|
62
|
+
_subscribers: Set<() => void>;
|
|
63
|
+
/** React-compatible Provider component (native Pyreon, NOT compat-wrapped).
|
|
64
|
+
* Returns a reactive accessor `() => VNodeChild` for Pyreon's renderer. */
|
|
65
|
+
Provider: (props: Record<string, unknown>) => unknown;
|
|
66
|
+
}
|
|
67
|
+
declare const COMPAT_CTX_BRAND: typeof COMPAT_CTX;
|
|
68
|
+
/**
|
|
69
|
+
* React-compatible `createContext` — creates a context with a Provider that
|
|
70
|
+
* supports nested Providers (inner overrides outer for its subtree) and
|
|
71
|
+
* notifies all `useContext` consumers when its value changes.
|
|
72
|
+
*/
|
|
73
|
+
declare function createContext<T>(defaultValue: T): CompatContext<T>;
|
|
74
|
+
/**
|
|
75
|
+
* React-compatible `useContext` — reads the current context value and
|
|
76
|
+
* subscribes the calling component to future value changes.
|
|
77
|
+
*
|
|
78
|
+
* Reads from Pyreon's tree-scoped context stack (correct nesting) and
|
|
79
|
+
* subscribes to the nearest Provider's subscriber set for re-rendering.
|
|
80
|
+
*
|
|
81
|
+
* Works with both compat contexts (from this module's `createContext`) and
|
|
82
|
+
* Pyreon native contexts (from `@pyreon/core`).
|
|
83
|
+
*/
|
|
84
|
+
declare function useContext<T>(context: CompatContext<T> | Context<T>): T;
|
|
37
85
|
/**
|
|
38
86
|
* React-compatible `useId` — returns a stable unique string per hook call.
|
|
39
87
|
*/
|
|
@@ -41,6 +89,9 @@ declare function useId(): string;
|
|
|
41
89
|
/**
|
|
42
90
|
* React-compatible `memo` — wraps a component to skip re-render when props
|
|
43
91
|
* are shallowly equal.
|
|
92
|
+
*
|
|
93
|
+
* Each component INSTANCE gets its own props/result cache via a hook slot,
|
|
94
|
+
* so two `<MemoComp />` usages don't share memoization state.
|
|
44
95
|
*/
|
|
45
96
|
declare function memo<P extends Record<string, unknown>>(component: (props: P) => VNodeChild$1, areEqual?: (prevProps: P, nextProps: P) => boolean): (props: P) => VNodeChild$1;
|
|
46
97
|
/**
|
|
@@ -76,7 +127,7 @@ declare function forwardRef<P extends Record<string, unknown>>(render: (props: P
|
|
|
76
127
|
/**
|
|
77
128
|
* React-compatible `cloneElement` — creates a new VNode with merged props.
|
|
78
129
|
*/
|
|
79
|
-
declare function cloneElement(element: VNode, props?: Record<string, unknown>, ...children: VNodeChild$1[]): VNode;
|
|
130
|
+
declare function cloneElement(element: VNode$1, props?: Record<string, unknown>, ...children: VNodeChild$1[]): VNode$1;
|
|
80
131
|
/**
|
|
81
132
|
* React-compatible `Children` utilities for working with VNode children.
|
|
82
133
|
*/
|
|
@@ -102,6 +153,156 @@ declare const Children: {
|
|
|
102
153
|
*/
|
|
103
154
|
only(children: VNodeChild$1 | VNodeChild$1[]): VNodeChild$1;
|
|
104
155
|
};
|
|
156
|
+
/**
|
|
157
|
+
* React-compatible `useSyncExternalStore` — subscribes to an external store.
|
|
158
|
+
* Re-subscribes automatically when the `subscribe` function identity changes.
|
|
159
|
+
*/
|
|
160
|
+
declare function useSyncExternalStore<T>(subscribe: (onStoreChange: () => void) => () => void, getSnapshot: () => T, getServerSnapshot?: () => T): T;
|
|
161
|
+
/**
|
|
162
|
+
* React-compatible `use` — reads a Context or suspends on a Promise.
|
|
163
|
+
* Can be called conditionally (unlike other hooks).
|
|
164
|
+
*
|
|
165
|
+
* IMPORTANT: Promises must have a stable identity across renders.
|
|
166
|
+
* Create promises outside the component or memoize them. Calling
|
|
167
|
+
* `use(fetch('/api'))` creates a new promise each render and will
|
|
168
|
+
* cause infinite suspension.
|
|
169
|
+
*/
|
|
170
|
+
declare function use<T>(resource: Context<T> | CompatContext<T> | Promise<T>): T;
|
|
171
|
+
/**
|
|
172
|
+
* React-compatible `useActionState` — manages async action state with pending indicator.
|
|
173
|
+
*/
|
|
174
|
+
declare function useActionState<S, P>(action: (state: S, payload: P) => S | Promise<S>, initialState: S): [S, (payload: P) => void, boolean];
|
|
175
|
+
/**
|
|
176
|
+
* React-compatible `startTransition` — runs the callback synchronously.
|
|
177
|
+
* No concurrent mode in Pyreon, so transitions are immediate.
|
|
178
|
+
*/
|
|
179
|
+
declare function startTransition(fn: () => void): void;
|
|
180
|
+
/**
|
|
181
|
+
* React-compatible `isValidElement` — checks if a value is a VNode.
|
|
182
|
+
*/
|
|
183
|
+
declare function isValidElement(value: unknown): value is VNode$1;
|
|
184
|
+
/**
|
|
185
|
+
* React-compatible `useDebugValue` — no-op in Pyreon (no React DevTools integration).
|
|
186
|
+
*/
|
|
187
|
+
declare function useDebugValue<T>(_value: T, _format?: (v: T) => unknown): void;
|
|
188
|
+
/**
|
|
189
|
+
* React-compatible `flushSync` — runs the callback synchronously.
|
|
190
|
+
*
|
|
191
|
+
* BEHAVIORAL DIFFERENCE: In Pyreon's compat model, state updates are
|
|
192
|
+
* batched via microtask. flushSync runs the callback and returns its
|
|
193
|
+
* result, but the DOM updates triggered by state changes inside the
|
|
194
|
+
* callback still fire asynchronously. For DOM measurement after state
|
|
195
|
+
* updates, use `await act(() => setState(...))` in tests, or
|
|
196
|
+
* `requestAnimationFrame` in production code.
|
|
197
|
+
*/
|
|
198
|
+
declare function flushSync<T>(fn: () => T): T;
|
|
199
|
+
/**
|
|
200
|
+
* React-compatible `act` — flushes pending microtasks for testing.
|
|
201
|
+
*/
|
|
202
|
+
declare function act(fn: () => void | Promise<void>): Promise<void>;
|
|
203
|
+
declare const version = "19.0.0-pyreon";
|
|
204
|
+
/**
|
|
205
|
+
* React-compatible `StrictMode` — pass-through in Pyreon (no double-invoke behavior).
|
|
206
|
+
*/
|
|
207
|
+
declare function StrictMode(props: {
|
|
208
|
+
children?: VNodeChild$1;
|
|
209
|
+
}): VNodeChild$1;
|
|
210
|
+
/**
|
|
211
|
+
* React-compatible `Profiler` — pass-through in Pyreon (no profiling integration).
|
|
212
|
+
*/
|
|
213
|
+
declare function Profiler(props: {
|
|
214
|
+
id: string;
|
|
215
|
+
onRender?: (...args: unknown[]) => void;
|
|
216
|
+
children?: VNodeChild$1;
|
|
217
|
+
}): VNodeChild$1;
|
|
218
|
+
/**
|
|
219
|
+
* React-compatible `Component` class stub.
|
|
220
|
+
* Class components are not fully supported — use function components with hooks.
|
|
221
|
+
*/
|
|
222
|
+
declare class Component<P = Record<string, unknown>, S = Record<string, unknown>> {
|
|
223
|
+
props: Readonly<P>;
|
|
224
|
+
state: Readonly<S>;
|
|
225
|
+
constructor(props: P);
|
|
226
|
+
setState(_partial: Partial<S> | ((prev: S) => Partial<S>)): void;
|
|
227
|
+
forceUpdate(): void;
|
|
228
|
+
render(): VNodeChild$1;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* React-compatible `PureComponent` class stub.
|
|
232
|
+
*/
|
|
233
|
+
declare class PureComponent<P = Record<string, unknown>, S = Record<string, unknown>> extends Component<P, S> {}
|
|
234
|
+
type FC<P = Record<string, unknown>> = (props: P) => VNodeChild$1;
|
|
235
|
+
type FunctionComponent<P = Record<string, unknown>> = FC<P>;
|
|
236
|
+
type ReactElement = VNode$1;
|
|
237
|
+
type ReactNode = VNodeChild$1;
|
|
238
|
+
type JSXElementConstructor<P> = (props: P) => VNodeChild$1;
|
|
239
|
+
type Dispatch<A> = (action: A) => void;
|
|
240
|
+
type SetStateAction<S> = S | ((prev: S) => S);
|
|
241
|
+
type RefObject<T> = {
|
|
242
|
+
readonly current: T | null;
|
|
243
|
+
};
|
|
244
|
+
type MutableRefObject<T> = {
|
|
245
|
+
current: T;
|
|
246
|
+
};
|
|
247
|
+
type RefCallback<T> = (instance: T | null) => void;
|
|
248
|
+
type ForwardedRef<T> = RefObject<T> | RefCallback<T> | null;
|
|
249
|
+
type PropsWithChildren<P = Record<string, unknown>> = P & {
|
|
250
|
+
children?: ReactNode;
|
|
251
|
+
};
|
|
252
|
+
type PropsWithRef<P> = P & {
|
|
253
|
+
ref?: RefObject<unknown> | RefCallback<unknown> | null;
|
|
254
|
+
};
|
|
255
|
+
type SyntheticEvent<T = Element> = Event & {
|
|
256
|
+
currentTarget: T;
|
|
257
|
+
};
|
|
258
|
+
type ChangeEvent<T = Element> = Event & {
|
|
259
|
+
currentTarget: T;
|
|
260
|
+
target: T;
|
|
261
|
+
};
|
|
262
|
+
type FormEvent<T = Element> = Event & {
|
|
263
|
+
currentTarget: T;
|
|
264
|
+
};
|
|
265
|
+
type MouseEvent<T = Element> = globalThis.MouseEvent & {
|
|
266
|
+
currentTarget: T;
|
|
267
|
+
};
|
|
268
|
+
type KeyboardEvent<T = Element> = globalThis.KeyboardEvent & {
|
|
269
|
+
currentTarget: T;
|
|
270
|
+
};
|
|
271
|
+
type FocusEvent<T = Element> = globalThis.FocusEvent & {
|
|
272
|
+
currentTarget: T;
|
|
273
|
+
};
|
|
274
|
+
type DragEvent<T = Element> = globalThis.DragEvent & {
|
|
275
|
+
currentTarget: T;
|
|
276
|
+
};
|
|
277
|
+
type PointerEvent<T = Element> = globalThis.PointerEvent & {
|
|
278
|
+
currentTarget: T;
|
|
279
|
+
};
|
|
280
|
+
type TouchEvent<T = Element> = globalThis.TouchEvent & {
|
|
281
|
+
currentTarget: T;
|
|
282
|
+
};
|
|
283
|
+
type ClipboardEvent<T = Element> = globalThis.ClipboardEvent & {
|
|
284
|
+
currentTarget: T;
|
|
285
|
+
};
|
|
286
|
+
type AnimationEvent<T = Element> = globalThis.AnimationEvent & {
|
|
287
|
+
currentTarget: T;
|
|
288
|
+
};
|
|
289
|
+
type TransitionEvent<T = Element> = globalThis.TransitionEvent & {
|
|
290
|
+
currentTarget: T;
|
|
291
|
+
};
|
|
292
|
+
type WheelEvent<T = Element> = globalThis.WheelEvent & {
|
|
293
|
+
currentTarget: T;
|
|
294
|
+
};
|
|
295
|
+
type HTMLAttributes<T = HTMLElement> = Record<string, unknown> & {
|
|
296
|
+
ref?: RefObject<T> | RefCallback<T> | null;
|
|
297
|
+
};
|
|
298
|
+
type InputHTMLAttributes<T = HTMLInputElement> = HTMLAttributes<T>;
|
|
299
|
+
type TextareaHTMLAttributes<T = HTMLTextAreaElement> = HTMLAttributes<T>;
|
|
300
|
+
type SelectHTMLAttributes<T = HTMLSelectElement> = HTMLAttributes<T>;
|
|
301
|
+
type ButtonHTMLAttributes<T = HTMLButtonElement> = HTMLAttributes<T>;
|
|
302
|
+
type AnchorHTMLAttributes<T = HTMLAnchorElement> = HTMLAttributes<T>;
|
|
303
|
+
type FormHTMLAttributes<T = HTMLFormElement> = HTMLAttributes<T>;
|
|
304
|
+
type ImgHTMLAttributes<T = HTMLImageElement> = HTMLAttributes<T>;
|
|
305
|
+
type SVGAttributes<T = SVGElement> = HTMLAttributes<T>;
|
|
105
306
|
//#endregion
|
|
106
|
-
export { Children, ErrorBoundary, Fragment, type Props,
|
|
307
|
+
export { AnchorHTMLAttributes, AnimationEvent, ButtonHTMLAttributes, type CSSProperties, ChangeEvent, Children, ClipboardEvent, CompatContext, Component, type Context, Dispatch, DragEvent, ErrorBoundary, FC, FocusEvent, FormEvent, FormHTMLAttributes, ForwardedRef, Fragment, FunctionComponent, HTMLAttributes, ImgHTMLAttributes, InputHTMLAttributes, JSXElementConstructor, KeyboardEvent, MouseEvent, MutableRefObject, PointerEvent, Profiler, type Props, PropsWithChildren, PropsWithRef, PureComponent, ReactElement, ReactNode, RefCallback, RefObject, SVGAttributes, SelectHTMLAttributes, SetStateAction, StrictMode, Suspense, SyntheticEvent, TextareaHTMLAttributes, TouchEvent, TransitionEvent, type VNode, type VNodeChild, WheelEvent, act, batch, cloneElement, createContext, createElement, createPortal, createRef, flushSync, forwardRef, h, isValidElement, lazy, memo, startTransition, use, useActionState, useCallback, useContext, useDebugValue, useDeferredValue, useEffect, useId, useImperativeHandle, useInsertionEffect, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore, useTransition, version };
|
|
107
308
|
//# sourceMappingURL=index2.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/react-compat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "React-compatible API shim for Pyreon — write React-style hooks that run on Pyreon's reactive engine",
|
|
5
5
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/react-compat#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"lib",
|
|
17
|
+
"!lib/**/*.map",
|
|
17
18
|
"src",
|
|
18
19
|
"README.md",
|
|
19
20
|
"LICENSE"
|
|
@@ -52,17 +53,20 @@
|
|
|
52
53
|
"build": "vl_rolldown_build",
|
|
53
54
|
"dev": "vl_rolldown_build-watch",
|
|
54
55
|
"test": "vitest run",
|
|
56
|
+
"test:browser": "vitest run --config ./vitest.browser.config.ts",
|
|
55
57
|
"typecheck": "tsc --noEmit",
|
|
56
58
|
"lint": "oxlint .",
|
|
57
59
|
"prepublishOnly": "bun run build"
|
|
58
60
|
},
|
|
59
61
|
"dependencies": {
|
|
60
|
-
"@pyreon/core": "^0.
|
|
61
|
-
"@pyreon/reactivity": "^0.
|
|
62
|
-
"@pyreon/runtime-dom": "^0.
|
|
62
|
+
"@pyreon/core": "^0.15.0",
|
|
63
|
+
"@pyreon/reactivity": "^0.15.0",
|
|
64
|
+
"@pyreon/runtime-dom": "^0.15.0"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@happy-dom/global-registrator": "^20.8.9",
|
|
68
|
+
"@pyreon/test-utils": "^0.13.2",
|
|
69
|
+
"@vitest/browser-playwright": "^4.1.4",
|
|
66
70
|
"happy-dom": "^20.8.3"
|
|
67
71
|
}
|
|
68
72
|
}
|
package/src/env.d.ts
ADDED