@pyreon/react-compat 0.2.1 → 0.3.1

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.
@@ -1,109 +1,206 @@
1
- import { ErrorBoundary, Fragment, Portal, Suspense, createContext, createRef, h, h as createElement, lazy, onErrorCaptured, onMount, onMount as useLayoutEffect, onUnmount, onUpdate, useContext } from "@pyreon/core";
2
- import { batch, computed, createSelector, effect, getCurrentScope, runUntracked, signal } from "@pyreon/reactivity";
1
+ import { ErrorBoundary, Fragment, Portal, Suspense, createContext, h, h as createElement, lazy, useContext } from "@pyreon/core";
2
+ import { batch } from "@pyreon/reactivity";
3
3
 
4
+ //#region src/jsx-runtime.ts
5
+
6
+ function getCurrentCtx() {
7
+ return _currentCtx;
8
+ }
9
+ function getHookIndex() {
10
+ return _hookIndex++;
11
+ }
12
+
13
+ //#endregion
4
14
  //#region src/index.ts
15
+ function requireCtx() {
16
+ const ctx = getCurrentCtx();
17
+ if (!ctx) throw new Error("Hook called outside of a component render");
18
+ return ctx;
19
+ }
20
+ function depsChanged(a, b) {
21
+ if (a === void 0 || b === void 0) return true;
22
+ if (a.length !== b.length) return true;
23
+ for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return true;
24
+ return false;
25
+ }
5
26
  /**
6
- * Drop-in for React's `useState`.
7
- * Returns `[getter, setter]` call `getter()` to read, `setter(v)` to write.
8
- *
9
- * Unlike React: the getter is a signal, so any component or effect that reads
10
- * it will re-run automatically. No dep arrays needed.
27
+ * React-compatible `useState` returns `[value, setter]`.
28
+ * Triggers a component re-render when the setter is called.
11
29
  */
12
30
  function useState(initial) {
13
- const s = signal(typeof initial === "function" ? initial() : initial);
31
+ const ctx = requireCtx();
32
+ const idx = getHookIndex();
33
+ if (ctx.hooks.length <= idx) ctx.hooks.push(typeof initial === "function" ? initial() : initial);
34
+ const value = ctx.hooks[idx];
14
35
  const setter = v => {
15
- if (typeof v === "function") s.update(v);else s.set(v);
36
+ const current = ctx.hooks[idx];
37
+ const next = typeof v === "function" ? v(current) : v;
38
+ if (Object.is(current, next)) return;
39
+ ctx.hooks[idx] = next;
40
+ ctx.scheduleRerender();
16
41
  };
17
- return [s, setter];
42
+ return [value, setter];
18
43
  }
19
44
  /**
20
- * Drop-in for React's `useReducer`.
45
+ * React-compatible `useReducer` returns `[state, dispatch]`.
21
46
  */
22
47
  function useReducer(reducer, initial) {
23
- const s = signal(typeof initial === "function" ? initial() : initial);
24
- const dispatch = action => s.update(prev => reducer(prev, action));
25
- return [s, dispatch];
48
+ const ctx = requireCtx();
49
+ const idx = getHookIndex();
50
+ if (ctx.hooks.length <= idx) ctx.hooks.push(typeof initial === "function" ? initial() : initial);
51
+ const state = ctx.hooks[idx];
52
+ const dispatch = action => {
53
+ const current = ctx.hooks[idx];
54
+ const next = reducer(current, action);
55
+ if (Object.is(current, next)) return;
56
+ ctx.hooks[idx] = next;
57
+ ctx.scheduleRerender();
58
+ };
59
+ return [state, dispatch];
26
60
  }
27
61
  /**
28
- * Drop-in for React's `useEffect`.
29
- *
30
- * The `deps` array is IGNORED — Pyreon tracks reactive dependencies automatically.
31
- * If `deps` is `[]` (mount-only), wrap the body in `runUntracked(() => ...)`.
32
- *
33
- * Returns a cleanup the same way React does (return a function from `fn`).
62
+ * React-compatible `useEffect` runs after render when deps change.
63
+ * Returns cleanup on unmount and before re-running.
34
64
  */
35
65
  function useEffect(fn, deps) {
36
- if (deps !== void 0 && deps.length === 0) onMount(() => {
37
- const cleanup = runUntracked(fn);
38
- if (typeof cleanup === "function") onUnmount(cleanup);
39
- });else {
40
- const e = effect(fn);
41
- onUnmount(() => {
42
- e.dispose();
43
- });
66
+ const ctx = requireCtx();
67
+ const idx = getHookIndex();
68
+ if (ctx.hooks.length <= idx) {
69
+ const entry = {
70
+ fn,
71
+ deps,
72
+ cleanup: void 0
73
+ };
74
+ ctx.hooks.push(entry);
75
+ ctx.pendingEffects.push(entry);
76
+ } else {
77
+ const entry = ctx.hooks[idx];
78
+ if (depsChanged(entry.deps, deps)) {
79
+ entry.fn = fn;
80
+ entry.deps = deps;
81
+ ctx.pendingEffects.push(entry);
82
+ }
44
83
  }
45
84
  }
46
85
  /**
47
- * Drop-in for React's `useMemo`.
48
- * The `deps` array is IGNORED — Pyreon's `computed` tracks dependencies automatically.
49
- * Returns a getter: call `value()` to read the memoized result.
86
+ * React-compatible `useLayoutEffect` runs synchronously after DOM mutations.
50
87
  */
51
- function useMemo(fn, _deps) {
52
- return computed(fn);
88
+ function useLayoutEffect(fn, deps) {
89
+ const ctx = requireCtx();
90
+ const idx = getHookIndex();
91
+ if (ctx.hooks.length <= idx) {
92
+ const entry = {
93
+ fn,
94
+ deps,
95
+ cleanup: void 0
96
+ };
97
+ ctx.hooks.push(entry);
98
+ ctx.pendingLayoutEffects.push(entry);
99
+ } else {
100
+ const entry = ctx.hooks[idx];
101
+ if (depsChanged(entry.deps, deps)) {
102
+ entry.fn = fn;
103
+ entry.deps = deps;
104
+ ctx.pendingLayoutEffects.push(entry);
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * React-compatible `useMemo` — returns the cached value, recomputed when deps change.
110
+ */
111
+ function useMemo(fn, deps) {
112
+ const ctx = requireCtx();
113
+ const idx = getHookIndex();
114
+ if (ctx.hooks.length <= idx) {
115
+ const value = fn();
116
+ ctx.hooks.push({
117
+ value,
118
+ deps
119
+ });
120
+ return value;
121
+ }
122
+ const entry = ctx.hooks[idx];
123
+ if (depsChanged(entry.deps, deps)) {
124
+ entry.value = fn();
125
+ entry.deps = deps;
126
+ }
127
+ return entry.value;
53
128
  }
54
129
  /**
55
- * Drop-in for React's `useCallback`.
56
- * In Pyreon, components run once so callbacks are never recreated — returns `fn` as-is.
130
+ * React-compatible `useCallback` — returns the cached function when deps haven't changed.
57
131
  */
58
- function useCallback(fn, _deps) {
59
- return fn;
132
+ function useCallback(fn, deps) {
133
+ return useMemo(() => fn, deps);
60
134
  }
61
135
  /**
62
- * Drop-in for React's `useRef`.
63
- * Returns `{ current: T }` — same shape as React's ref object.
136
+ * React-compatible `useRef` returns `{ current }` persisted across re-renders.
64
137
  */
65
138
  function useRef(initial) {
66
- const ref = createRef();
67
- if (initial !== void 0) ref.current = initial;
68
- return ref;
139
+ const ctx = requireCtx();
140
+ const idx = getHookIndex();
141
+ if (ctx.hooks.length <= idx) {
142
+ const ref = {
143
+ current: initial !== void 0 ? initial : null
144
+ };
145
+ ctx.hooks.push(ref);
146
+ }
147
+ return ctx.hooks[idx];
69
148
  }
70
149
  /**
71
- * Drop-in for React's `useId` — returns a stable unique string per component instance.
72
- *
73
- * Uses the component's effectScope as the key so the counter starts at 0 for every
74
- * component on both server and client — IDs are deterministic and hydration-safe.
150
+ * React-compatible `useId` — returns a stable unique string per hook call.
75
151
  */
76
-
77
152
  function useId() {
78
- const scope = getCurrentScope();
79
- if (!scope) return `:r${Math.random().toString(36).slice(2, 9)}:`;
80
- const count = _idCounters.get(scope) ?? 0;
81
- _idCounters.set(scope, count + 1);
82
- return `:r${count.toString(36)}:`;
153
+ const ctx = requireCtx();
154
+ const idx = getHookIndex();
155
+ if (ctx.hooks.length <= idx) ctx.hooks.push(`:r${(_idCounter++).toString(36)}:`);
156
+ return ctx.hooks[idx];
83
157
  }
84
158
  /**
85
- * Drop-in for React's `memo` — wraps a component.
86
- * In Pyreon, components run once (no re-renders), so memoization is a no-op.
87
- * Kept for API compatibility when migrating React code.
159
+ * React-compatible `memo` — wraps a component to skip re-render when props
160
+ * are shallowly equal.
88
161
  */
89
- function memo(component) {
90
- return component;
162
+ function memo(component, areEqual) {
163
+ const compare = areEqual ?? ((a, b) => {
164
+ const keysA = Object.keys(a);
165
+ const keysB = Object.keys(b);
166
+ if (keysA.length !== keysB.length) return false;
167
+ for (const k of keysA) if (!Object.is(a[k], b[k])) return false;
168
+ return true;
169
+ });
170
+ let prevProps = null;
171
+ let prevResult = null;
172
+ return props => {
173
+ if (prevProps !== null && compare(prevProps, props)) return prevResult;
174
+ prevProps = props;
175
+ prevResult = component(props);
176
+ return prevResult;
177
+ };
91
178
  }
92
179
  /**
93
- * Drop-in for React's `useTransition` — no-op in Pyreon (no concurrent mode).
94
- * Returns `[false, (fn) => fn()]` to keep code runnable without changes.
180
+ * React-compatible `useTransition` — no concurrent mode in Pyreon.
95
181
  */
96
182
  function useTransition() {
97
183
  return [false, fn => fn()];
98
184
  }
99
185
  /**
100
- * Drop-in for React's `useDeferredValue` — returns the value as-is in Pyreon.
186
+ * React-compatible `useDeferredValue` — returns the value as-is.
101
187
  */
102
188
  function useDeferredValue(value) {
103
189
  return value;
104
190
  }
105
191
  /**
106
- * Drop-in for React's `createPortal(children, target)`.
192
+ * React-compatible `useImperativeHandle`.
193
+ */
194
+ function useImperativeHandle(ref, init, deps) {
195
+ useLayoutEffect(() => {
196
+ if (ref) ref.current = init();
197
+ return () => {
198
+ if (ref) ref.current = null;
199
+ };
200
+ }, deps);
201
+ }
202
+ /**
203
+ * React-compatible `createPortal(children, target)`.
107
204
  */
108
205
  function createPortal(children, target) {
109
206
  return Portal({
@@ -111,19 +208,7 @@ function createPortal(children, target) {
111
208
  children
112
209
  });
113
210
  }
114
- /**
115
- * Drop-in for React's `useImperativeHandle`.
116
- * In Pyreon, expose methods via a ref prop directly — this is a compatibility shim.
117
- */
118
- function useImperativeHandle(ref, init, _deps) {
119
- onMount(() => {
120
- if (ref) ref.current = init();
121
- });
122
- onUnmount(() => {
123
- if (ref) ref.current = null;
124
- });
125
- }
126
211
 
127
212
  //#endregion
128
- export { ErrorBoundary, Fragment, Suspense, batch, createContext, createElement, createPortal, createSelector, h, lazy, memo, onMount, onUnmount, onUpdate, useCallback, useContext, useDeferredValue, useEffect, useEffect as useLayoutEffect_, onErrorCaptured as useErrorBoundary, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useTransition };
213
+ export { ErrorBoundary, Fragment, Suspense, batch, createContext, createElement, createPortal, h, lazy, memo, useCallback, useContext, useDeferredValue, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useTransition };
129
214
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/jsx-runtime.ts","../../src/index.ts"],"mappings":"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"}
@@ -1,73 +1,66 @@
1
- import { CleanupFn, ErrorBoundary, Fragment, Props, Suspense, VNode as ReactNode, VNodeChild, VNodeChild as VNodeChild$1, createContext, h, h as createElement, lazy, onErrorCaptured, onMount, onMount as useLayoutEffect, onUnmount, onUpdate, useContext } from "@pyreon/core";
2
- import { batch, createSelector } from "@pyreon/reactivity";
1
+ import { ErrorBoundary, Fragment, Props, Suspense, VNode as ReactNode, VNodeChild, VNodeChild as VNodeChild$1, createContext, h, h as createElement, lazy, useContext } from "@pyreon/core";
2
+ import { batch } from "@pyreon/reactivity";
3
3
 
4
4
  //#region src/index.d.ts
5
5
  /**
6
- * Drop-in for React's `useState`.
7
- * Returns `[getter, setter]` call `getter()` to read, `setter(v)` to write.
8
- *
9
- * Unlike React: the getter is a signal, so any component or effect that reads
10
- * it will re-run automatically. No dep arrays needed.
6
+ * React-compatible `useState` returns `[value, setter]`.
7
+ * Triggers a component re-render when the setter is called.
11
8
  */
12
- declare function useState<T>(initial: T | (() => T)): [() => T, (v: T | ((prev: T) => T)) => void];
9
+ declare function useState<T>(initial: T | (() => T)): [T, (v: T | ((prev: T) => T)) => void];
13
10
  /**
14
- * Drop-in for React's `useReducer`.
11
+ * React-compatible `useReducer` returns `[state, dispatch]`.
15
12
  */
16
- declare function useReducer<S, A>(reducer: (state: S, action: A) => S, initial: S | (() => S)): [() => S, (action: A) => void];
13
+ declare function useReducer<S, A>(reducer: (state: S, action: A) => S, initial: S | (() => S)): [S, (action: A) => void];
17
14
  /**
18
- * Drop-in for React's `useEffect`.
19
- *
20
- * The `deps` array is IGNORED — Pyreon tracks reactive dependencies automatically.
21
- * If `deps` is `[]` (mount-only), wrap the body in `runUntracked(() => ...)`.
22
- *
23
- * Returns a cleanup the same way React does (return a function from `fn`).
15
+ * React-compatible `useEffect` runs after render when deps change.
16
+ * Returns cleanup on unmount and before re-running.
24
17
  */
25
- declare function useEffect(fn: () => CleanupFn | void, deps?: unknown[]): void;
18
+ declare function useEffect(fn: () => (() => void) | void, deps?: unknown[]): void;
26
19
  /**
27
- * Drop-in for React's `useMemo`.
28
- * The `deps` array is IGNORED — Pyreon's `computed` tracks dependencies automatically.
29
- * Returns a getter: call `value()` to read the memoized result.
20
+ * React-compatible `useLayoutEffect` runs synchronously after DOM mutations.
30
21
  */
31
- declare function useMemo<T>(fn: () => T, _deps?: unknown[]): () => T;
22
+ declare function useLayoutEffect(fn: () => (() => void) | void, deps?: unknown[]): void;
32
23
  /**
33
- * Drop-in for React's `useCallback`.
34
- * In Pyreon, components run once so callbacks are never recreated — returns `fn` as-is.
24
+ * React-compatible `useMemo` returns the cached value, recomputed when deps change.
35
25
  */
36
- declare function useCallback<T extends (...args: any[]) => any>(fn: T, _deps?: unknown[]): T;
26
+ declare function useMemo<T>(fn: () => T, deps: unknown[]): T;
37
27
  /**
38
- * Drop-in for React's `useRef`.
39
- * Returns `{ current: T }` — same shape as React's ref object.
28
+ * React-compatible `useCallback` — returns the cached function when deps haven't changed.
29
+ */
30
+ declare function useCallback<T extends (...args: never[]) => unknown>(fn: T, deps: unknown[]): T;
31
+ /**
32
+ * React-compatible `useRef` — returns `{ current }` persisted across re-renders.
40
33
  */
41
34
  declare function useRef<T>(initial?: T): {
42
35
  current: T | null;
43
36
  };
37
+ /**
38
+ * React-compatible `useId` — returns a stable unique string per hook call.
39
+ */
44
40
  declare function useId(): string;
45
41
  /**
46
- * Drop-in for React's `memo` — wraps a component.
47
- * In Pyreon, components run once (no re-renders), so memoization is a no-op.
48
- * Kept for API compatibility when migrating React code.
42
+ * React-compatible `memo` — wraps a component to skip re-render when props
43
+ * are shallowly equal.
49
44
  */
50
- declare function memo<P extends Record<string, unknown>>(component: (props: P) => VNodeChild$1): (props: P) => VNodeChild$1;
45
+ declare function memo<P extends Record<string, unknown>>(component: (props: P) => VNodeChild$1, areEqual?: (prevProps: P, nextProps: P) => boolean): (props: P) => VNodeChild$1;
51
46
  /**
52
- * Drop-in for React's `useTransition` — no-op in Pyreon (no concurrent mode).
53
- * Returns `[false, (fn) => fn()]` to keep code runnable without changes.
47
+ * React-compatible `useTransition` — no concurrent mode in Pyreon.
54
48
  */
55
49
  declare function useTransition(): [boolean, (fn: () => void) => void];
56
50
  /**
57
- * Drop-in for React's `useDeferredValue` — returns the value as-is in Pyreon.
51
+ * React-compatible `useDeferredValue` — returns the value as-is.
58
52
  */
59
53
  declare function useDeferredValue<T>(value: T): T;
60
54
  /**
61
- * Drop-in for React's `createPortal(children, target)`.
62
- */
63
- declare function createPortal(children: VNodeChild$1, target: Element): VNodeChild$1;
64
- /**
65
- * Drop-in for React's `useImperativeHandle`.
66
- * In Pyreon, expose methods via a ref prop directly — this is a compatibility shim.
55
+ * React-compatible `useImperativeHandle`.
67
56
  */
68
57
  declare function useImperativeHandle<T>(ref: {
69
58
  current: T | null;
70
- } | null | undefined, init: () => T, _deps?: unknown[]): void;
59
+ } | null | undefined, init: () => T, deps?: unknown[]): void;
60
+ /**
61
+ * React-compatible `createPortal(children, target)`.
62
+ */
63
+ declare function createPortal(children: VNodeChild$1, target: Element): VNodeChild$1;
71
64
  //#endregion
72
- export { ErrorBoundary, Fragment, type Props, type ReactNode, Suspense, type VNodeChild, batch, createContext, createElement, createPortal, createSelector, h, lazy, memo, onMount, onUnmount, onUpdate, useCallback, useContext, useDeferredValue, useEffect, useEffect as useLayoutEffect_, onErrorCaptured as useErrorBoundary, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useTransition };
65
+ export { ErrorBoundary, Fragment, type Props, type ReactNode, Suspense, type VNodeChild, batch, createContext, createElement, createPortal, h, lazy, memo, useCallback, useContext, useDeferredValue, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useTransition };
73
66
  //# sourceMappingURL=index2.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/index.ts"],"mappings":";;;;;;AAwEA;;;;;iBAdgB,QAAA,GAAA,CAAY,OAAA,EAAS,CAAA,UAAW,CAAA,WAAY,CAAA,GAAI,CAAA,EAAG,CAAA,KAAM,IAAA,EAAM,CAAA,KAAM,CAAA;;;;iBAcrE,UAAA,MAAA,CACd,OAAA,GAAU,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,KAAM,CAAA,EAClC,OAAA,EAAS,CAAA,UAAW,CAAA,WACZ,CAAA,GAAI,MAAA,EAAQ,CAAA;;;;;;;;;iBAiBN,SAAA,CAAU,EAAA,QAAU,SAAA,SAAkB,IAAA;;;;;AAAtD;iBA+BgB,OAAA,GAAA,CAAW,EAAA,QAAU,CAAA,EAAG,KAAA,qBAA0B,CAAA;;;;;iBASlD,WAAA,eAA0B,IAAA,gBAAA,CAAqB,EAAA,EAAI,CAAA,EAAG,KAAA,eAAoB,CAAA;;;AAT1F;;iBAmBgB,MAAA,GAAA,CAAU,OAAA,GAAU,CAAA;EAAM,OAAA,EAAS,CAAA;AAAA;AAAA,iBAwBnC,KAAA,CAAA;AAlChB;;;;;AAAA,iBAiDgB,IAAA,WAAe,MAAA,kBAAA,CAC7B,SAAA,GAAY,KAAA,EAAO,CAAA,KAAM,YAAA,IACvB,KAAA,EAAO,CAAA,KAAM,YAAA;;;;;iBAQD,aAAA,CAAA,cAA4B,EAAA;;AAjD5C;;iBAwDgB,gBAAA,GAAA,CAAoB,KAAA,EAAO,CAAA,GAAI,CAAA;;;;iBAyB/B,YAAA,CAAa,QAAA,EAAU,YAAA,EAAY,MAAA,EAAQ,OAAA,GAAU,YAAA;;;;;iBAUrD,mBAAA,GAAA,CACd,GAAA;EAAO,OAAA,EAAS,CAAA;AAAA,sBAChB,IAAA,QAAY,CAAA,EACZ,KAAA"}
1
+ {"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/index.ts"],"mappings":";;;;;;;;iBA8CgB,QAAA,GAAA,CAAY,OAAA,EAAS,CAAA,UAAW,CAAA,KAAM,CAAA,GAAI,CAAA,EAAG,CAAA,KAAM,IAAA,EAAM,CAAA,KAAM,CAAA;;;;iBAyB/D,UAAA,MAAA,CACd,OAAA,GAAU,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,KAAM,CAAA,EAClC,OAAA,EAAS,CAAA,UAAW,CAAA,KAClB,CAAA,GAAI,MAAA,EAAQ,CAAA;AAHhB;;;;AAAA,iBA8BgB,SAAA,CAAU,EAAA,6BAA+B,IAAA;;;;iBAuBzC,eAAA,CAAgB,EAAA,6BAA+B,IAAA;;;;iBAuB/C,OAAA,GAAA,CAAW,EAAA,QAAU,CAAA,EAAG,IAAA,cAAkB,CAAA;;;;iBAqB1C,WAAA,eAA0B,IAAA,sBAAA,CAA2B,EAAA,EAAI,CAAA,EAAG,IAAA,cAAkB,CAAA;;;;iBAS9E,MAAA,GAAA,CAAU,OAAA,GAAU,CAAA;EAAM,OAAA,EAAS,CAAA;AAAA;;;;iBAuBnC,KAAA,CAAA;AAnGhB;;;;AAAA,iBAoHgB,IAAA,WAAe,MAAA,kBAAA,CAC7B,SAAA,GAAY,KAAA,EAAO,CAAA,KAAM,YAAA,EACzB,QAAA,IAAY,SAAA,EAAW,CAAA,EAAG,SAAA,EAAW,CAAA,gBACnC,KAAA,EAAO,CAAA,KAAM,YAAA;AAhGjB;;;AAAA,iBA6HgB,aAAA,CAAA,cAA4B,EAAA;;AAtG5C;;iBA6GgB,gBAAA,GAAA,CAAoB,KAAA,EAAO,CAAA,GAAI,CAAA;;;;iBAS/B,mBAAA,GAAA,CACd,GAAA;EAAO,OAAA,EAAS,CAAA;AAAA,sBAChB,IAAA,QAAY,CAAA,EACZ,IAAA;;AApGF;;iBAuHgB,YAAA,CAAa,QAAA,EAAU,YAAA,EAAY,MAAA,EAAQ,OAAA,GAAU,YAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/react-compat",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "React-compatible API shim for Pyreon — write React-style hooks that run on Pyreon's reactive engine",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,6 +33,16 @@
33
33
  "bun": "./src/dom.ts",
34
34
  "import": "./lib/dom.js",
35
35
  "types": "./lib/types/dom.d.ts"
36
+ },
37
+ "./jsx-runtime": {
38
+ "bun": "./src/jsx-runtime.ts",
39
+ "import": "./lib/jsx-runtime.js",
40
+ "types": "./lib/types/jsx-runtime.d.ts"
41
+ },
42
+ "./jsx-dev-runtime": {
43
+ "bun": "./src/jsx-runtime.ts",
44
+ "import": "./lib/jsx-runtime.js",
45
+ "types": "./lib/types/jsx-runtime.d.ts"
36
46
  }
37
47
  },
38
48
  "scripts": {
@@ -44,9 +54,9 @@
44
54
  "prepublishOnly": "bun run build"
45
55
  },
46
56
  "dependencies": {
47
- "@pyreon/core": "^0.2.1",
48
- "@pyreon/reactivity": "^0.2.1",
49
- "@pyreon/runtime-dom": "^0.2.1"
57
+ "@pyreon/core": "^0.3.1",
58
+ "@pyreon/reactivity": "^0.3.1",
59
+ "@pyreon/runtime-dom": "^0.3.1"
50
60
  },
51
61
  "devDependencies": {
52
62
  "@happy-dom/global-registrator": "^20.8.3",