@pyreon/react-compat 0.13.0 → 0.14.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.
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"32dc1380-1","name":"jsx-runtime.ts"},{"uid":"32dc1380-3","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"32dc1380-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"32dc1380-0"},"32dc1380-3":{"renderedLength":7034,"gzipLength":1959,"brotliLength":0,"metaUid":"32dc1380-2"}},"nodeMetas":{"32dc1380-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"index.js":"32dc1380-1"},"imported":[{"uid":"32dc1380-4"},{"uid":"32dc1380-5"}],"importedBy":[{"uid":"32dc1380-2"}]},"32dc1380-2":{"id":"/src/index.ts","moduleParts":{"index.js":"32dc1380-3"},"imported":[{"uid":"32dc1380-4"},{"uid":"32dc1380-5"},{"uid":"32dc1380-0"}],"importedBy":[],"isEntry":true},"32dc1380-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"32dc1380-2"},{"uid":"32dc1380-0"}]},"32dc1380-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"32dc1380-2"},{"uid":"32dc1380-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"671d1924-1","name":"jsx-runtime.ts"},{"uid":"671d1924-3","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"671d1924-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"671d1924-0"},"671d1924-3":{"renderedLength":16429,"gzipLength":4587,"brotliLength":0,"metaUid":"671d1924-2"}},"nodeMetas":{"671d1924-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"index.js":"671d1924-1"},"imported":[{"uid":"671d1924-4"},{"uid":"671d1924-5"}],"importedBy":[{"uid":"671d1924-2"}]},"671d1924-2":{"id":"/src/index.ts","moduleParts":{"index.js":"671d1924-3"},"imported":[{"uid":"671d1924-4"},{"uid":"671d1924-5"},{"uid":"671d1924-0"}],"importedBy":[],"isEntry":true},"671d1924-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"671d1924-2"},{"uid":"671d1924-0"}]},"671d1924-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"671d1924-2"},{"uid":"671d1924-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"243e8c0a-1","name":"jsx-runtime.ts"},{"uid":"243e8c0a-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"243e8c0a-1":{"renderedLength":2522,"gzipLength":870,"brotliLength":0,"metaUid":"243e8c0a-0"},"243e8c0a-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"243e8c0a-2"}},"nodeMetas":{"243e8c0a-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"243e8c0a-1"},"imported":[{"uid":"243e8c0a-4"},{"uid":"243e8c0a-5"}],"importedBy":[{"uid":"243e8c0a-2"}]},"243e8c0a-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"243e8c0a-3"},"imported":[{"uid":"243e8c0a-0"}],"importedBy":[],"isEntry":true},"243e8c0a-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"243e8c0a-0"}]},"243e8c0a-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"243e8c0a-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"ab213c8a-1","name":"jsx-runtime.ts"},{"uid":"ab213c8a-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"ab213c8a-1":{"renderedLength":4797,"gzipLength":1465,"brotliLength":0,"metaUid":"ab213c8a-0"},"ab213c8a-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"ab213c8a-2"}},"nodeMetas":{"ab213c8a-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"ab213c8a-1"},"imported":[{"uid":"ab213c8a-4"},{"uid":"ab213c8a-5"}],"importedBy":[{"uid":"ab213c8a-2"}]},"ab213c8a-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"ab213c8a-3"},"imported":[{"uid":"ab213c8a-0"}],"importedBy":[],"isEntry":true},"ab213c8a-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"ab213c8a-0"}]},"ab213c8a-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"ab213c8a-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ErrorBoundary, Fragment, Portal, Suspense, createContext, h, h as createElement, h as h$1, lazy, useContext } from "@pyreon/core";
1
+ import { ErrorBoundary, Fragment, Portal, Suspense, createContext as createContext$1, createRef, h, h as createElement, h as h$1, lazy, provide, useContext as useContext$1 } from "@pyreon/core";
2
2
  import { batch } from "@pyreon/reactivity";
3
3
 
4
4
  //#region src/jsx-runtime.ts
@@ -31,33 +31,50 @@ function depsChanged(a, b) {
31
31
  function useState(initial) {
32
32
  const ctx = requireCtx();
33
33
  const idx = getHookIndex();
34
- if (ctx.hooks.length <= idx) ctx.hooks.push(typeof initial === "function" ? initial() : initial);
35
- const value = ctx.hooks[idx];
36
- const setter = (v) => {
37
- const current = ctx.hooks[idx];
38
- const next = typeof v === "function" ? v(current) : v;
39
- if (Object.is(current, next)) return;
40
- ctx.hooks[idx] = next;
41
- ctx.scheduleRerender();
42
- };
43
- return [value, setter];
34
+ if (ctx.hooks.length <= idx) {
35
+ const entry = {
36
+ value: typeof initial === "function" ? initial() : initial,
37
+ setter: null
38
+ };
39
+ entry.setter = (v) => {
40
+ const current = entry.value;
41
+ const next = typeof v === "function" ? v(current) : v;
42
+ if (Object.is(current, next)) return;
43
+ entry.value = next;
44
+ ctx.scheduleRerender();
45
+ };
46
+ ctx.hooks.push(entry);
47
+ }
48
+ const entry = ctx.hooks[idx];
49
+ return [entry.value, entry.setter];
44
50
  }
45
51
  /**
46
52
  * React-compatible `useReducer` — returns `[state, dispatch]`.
53
+ * Supports the 3-argument form: `useReducer(reducer, initialArg, init)`.
47
54
  */
48
- function useReducer(reducer, initial) {
55
+ function useReducer(reducer, initialArg, init) {
49
56
  const ctx = requireCtx();
50
57
  const idx = getHookIndex();
51
- if (ctx.hooks.length <= idx) ctx.hooks.push(typeof initial === "function" ? initial() : initial);
52
- const state = ctx.hooks[idx];
53
- const dispatch = (action) => {
54
- const current = ctx.hooks[idx];
55
- const next = reducer(current, action);
56
- if (Object.is(current, next)) return;
57
- ctx.hooks[idx] = next;
58
- ctx.scheduleRerender();
59
- };
60
- return [state, dispatch];
58
+ if (ctx.hooks.length <= idx) {
59
+ let initial;
60
+ if (init) initial = init(initialArg);
61
+ else if (typeof initialArg === "function") initial = initialArg();
62
+ else initial = initialArg;
63
+ const entry = {
64
+ value: initial,
65
+ dispatch: null
66
+ };
67
+ entry.dispatch = (action) => {
68
+ const current = entry.value;
69
+ const next = reducer(current, action);
70
+ if (Object.is(current, next)) return;
71
+ entry.value = next;
72
+ ctx.scheduleRerender();
73
+ };
74
+ ctx.hooks.push(entry);
75
+ }
76
+ const entry = ctx.hooks[idx];
77
+ return [entry.value, entry.dispatch];
61
78
  }
62
79
  /**
63
80
  * React-compatible `useEffect` — runs after render when deps change.
@@ -107,6 +124,30 @@ function useLayoutEffect(fn, deps) {
107
124
  }
108
125
  }
109
126
  /**
127
+ * React-compatible `useInsertionEffect` — runs synchronously before layout effects.
128
+ * Intended for CSS-in-JS libraries to inject styles before DOM reads.
129
+ */
130
+ function useInsertionEffect(fn, deps) {
131
+ const ctx = requireCtx();
132
+ const idx = getHookIndex();
133
+ if (ctx.hooks.length <= idx) {
134
+ const entry = {
135
+ fn,
136
+ deps,
137
+ cleanup: void 0
138
+ };
139
+ ctx.hooks.push(entry);
140
+ ctx.pendingInsertionEffects.push(entry);
141
+ } else {
142
+ const entry = ctx.hooks[idx];
143
+ if (depsChanged(entry.deps, deps)) {
144
+ entry.fn = fn;
145
+ entry.deps = deps;
146
+ ctx.pendingInsertionEffects.push(entry);
147
+ }
148
+ }
149
+ }
150
+ /**
110
151
  * React-compatible `useMemo` — returns the cached value, recomputed when deps change.
111
152
  */
112
153
  function useMemo(fn, deps) {
@@ -145,6 +186,70 @@ function useRef(initial) {
145
186
  }
146
187
  return ctx.hooks[idx];
147
188
  }
189
+ const COMPAT_CTX = Symbol.for("pyreon:compat-ctx");
190
+ const COMPAT_CTX_BRAND = COMPAT_CTX;
191
+ const NATIVE_COMPONENT = Symbol.for("pyreon:native-compat");
192
+ /**
193
+ * React-compatible `createContext` — creates a context with a Provider that
194
+ * supports nested Providers (inner overrides outer for its subtree) and
195
+ * notifies all `useContext` consumers when its value changes.
196
+ */
197
+ function createContext(defaultValue) {
198
+ const pyreonCtx = createContext$1({
199
+ value: defaultValue,
200
+ subscribers: /* @__PURE__ */ new Set()
201
+ });
202
+ const defaultSubscribers = /* @__PURE__ */ new Set();
203
+ const Provider = (props) => {
204
+ const frame = {
205
+ value: props.value,
206
+ subscribers: /* @__PURE__ */ new Set()
207
+ };
208
+ provide(pyreonCtx, frame);
209
+ return () => {
210
+ const { value, children } = props;
211
+ if (!Object.is(frame.value, value)) {
212
+ frame.value = value;
213
+ for (const sub of frame.subscribers) sub();
214
+ }
215
+ return children ?? null;
216
+ };
217
+ };
218
+ Provider[NATIVE_COMPONENT] = true;
219
+ return {
220
+ [COMPAT_CTX_BRAND]: true,
221
+ _defaultValue: defaultValue,
222
+ _pyreonCtx: pyreonCtx,
223
+ _subscribers: defaultSubscribers,
224
+ Provider
225
+ };
226
+ }
227
+ /**
228
+ * React-compatible `useContext` — reads the current context value and
229
+ * subscribes the calling component to future value changes.
230
+ *
231
+ * Reads from Pyreon's tree-scoped context stack (correct nesting) and
232
+ * subscribes to the nearest Provider's subscriber set for re-rendering.
233
+ *
234
+ * Works with both compat contexts (from this module's `createContext`) and
235
+ * Pyreon native contexts (from `@pyreon/core`).
236
+ */
237
+ function useContext(context) {
238
+ if (COMPAT_CTX in context) {
239
+ const frame = useContext$1(context._pyreonCtx);
240
+ const renderCtx = getCurrentCtx();
241
+ if (renderCtx) {
242
+ const idx = getHookIndex();
243
+ if (renderCtx.hooks.length <= idx) {
244
+ const sub = () => renderCtx.scheduleRerender();
245
+ frame.subscribers.add(sub);
246
+ renderCtx.hooks.push({ _contextUnsub: () => frame.subscribers.delete(sub) });
247
+ }
248
+ }
249
+ return frame.value;
250
+ }
251
+ return useContext$1(context);
252
+ }
148
253
  let _idCounter = 0;
149
254
  /**
150
255
  * React-compatible `useId` — returns a stable unique string per hook call.
@@ -155,26 +260,47 @@ function useId() {
155
260
  if (ctx.hooks.length <= idx) ctx.hooks.push(`:r${(_idCounter++).toString(36)}:`);
156
261
  return ctx.hooks[idx];
157
262
  }
263
+ function shallowEqual(a, b) {
264
+ const keysA = Object.keys(a);
265
+ const keysB = Object.keys(b);
266
+ if (keysA.length !== keysB.length) return false;
267
+ for (const k of keysA) if (!Object.is(a[k], b[k])) return false;
268
+ return true;
269
+ }
158
270
  /**
159
271
  * React-compatible `memo` — wraps a component to skip re-render when props
160
272
  * are shallowly equal.
273
+ *
274
+ * Each component INSTANCE gets its own props/result cache via a hook slot,
275
+ * so two `<MemoComp />` usages don't share memoization state.
161
276
  */
162
277
  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;
278
+ const compare = areEqual ?? shallowEqual;
279
+ const MEMO_MARKER = Symbol.for("pyreon:memo");
280
+ let _fallbackPrevProps = null;
281
+ let _fallbackPrevResult = null;
282
+ const memoized = (props) => {
283
+ const ctx = getCurrentCtx();
284
+ if (ctx) {
285
+ const idx = getHookIndex();
286
+ if (ctx.hooks.length <= idx) ctx.hooks.push({
287
+ prevProps: null,
288
+ prevResult: null
289
+ });
290
+ const cache = ctx.hooks[idx];
291
+ if (cache.prevProps !== null && compare(cache.prevProps, props)) return cache.prevResult;
292
+ cache.prevProps = props;
293
+ cache.prevResult = component(props);
294
+ return cache.prevResult;
295
+ }
296
+ if (_fallbackPrevProps !== null && compare(_fallbackPrevProps, props)) return _fallbackPrevResult;
297
+ _fallbackPrevProps = props;
298
+ _fallbackPrevResult = component(props);
299
+ return _fallbackPrevResult;
177
300
  };
301
+ memoized[MEMO_MARKER] = true;
302
+ memoized.displayName = component.displayName || component.name || "Memo";
303
+ return memoized;
178
304
  }
179
305
  /**
180
306
  * React-compatible `useTransition` — no concurrent mode in Pyreon.
@@ -214,10 +340,12 @@ function createPortal(children, target) {
214
340
  * The render function receives (props, ref) — we merge ref into props.
215
341
  */
216
342
  function forwardRef(render) {
217
- return (props) => {
343
+ const forwarded = (props) => {
218
344
  const { ref, ...rest } = props;
219
345
  return render(rest, ref ?? null);
220
346
  };
347
+ forwarded.displayName = render.displayName || render.name || "ForwardRef";
348
+ return forwarded;
221
349
  }
222
350
  /**
223
351
  * React-compatible `cloneElement` — creates a new VNode with merged props.
@@ -245,19 +373,27 @@ const Children = {
245
373
  map(children, fn) {
246
374
  const flat = flattenChildren(children);
247
375
  const result = [];
376
+ let validIndex = 0;
248
377
  for (let i = 0; i < flat.length; i++) {
249
378
  const child = flat[i];
250
379
  if (child == null || child === true || child === false) continue;
251
- result.push(fn(child, i));
380
+ const mapped = fn(child, validIndex);
381
+ if (mapped && typeof mapped === "object" && "type" in mapped && "props" in mapped) {
382
+ const vnode = mapped;
383
+ if (vnode.key == null) vnode.key = `.${validIndex}`;
384
+ }
385
+ result.push(mapped);
386
+ validIndex++;
252
387
  }
253
388
  return result;
254
389
  },
255
390
  forEach(children, fn) {
256
391
  const flat = flattenChildren(children);
392
+ let validIndex = 0;
257
393
  for (let i = 0; i < flat.length; i++) {
258
394
  const child = flat[i];
259
395
  if (child == null || child === true || child === false) continue;
260
- fn(child, i);
396
+ fn(child, validIndex++);
261
397
  }
262
398
  },
263
399
  count(children) {
@@ -275,7 +411,187 @@ const Children = {
275
411
  return arr[0];
276
412
  }
277
413
  };
414
+ /**
415
+ * React-compatible `useSyncExternalStore` — subscribes to an external store.
416
+ * Re-subscribes automatically when the `subscribe` function identity changes.
417
+ */
418
+ function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
419
+ const ctx = requireCtx();
420
+ const idx = getHookIndex();
421
+ if (typeof window === "undefined" && getServerSnapshot) {
422
+ if (ctx.hooks.length <= idx) ctx.hooks.push({
423
+ subscribe,
424
+ unsubscribe: void 0,
425
+ snapshot: getServerSnapshot()
426
+ });
427
+ return ctx.hooks[idx].snapshot;
428
+ }
429
+ if (ctx.hooks.length <= idx) {
430
+ const snapshot = getSnapshot();
431
+ const entry = {
432
+ subscribe,
433
+ unsubscribe: void 0,
434
+ snapshot
435
+ };
436
+ const onChange = () => {
437
+ const next = getSnapshot();
438
+ if (!Object.is(entry.snapshot, next)) {
439
+ entry.snapshot = next;
440
+ ctx.scheduleRerender();
441
+ }
442
+ };
443
+ entry.unsubscribe = subscribe(onChange);
444
+ ctx.hooks.push(entry);
445
+ return snapshot;
446
+ }
447
+ const entry = ctx.hooks[idx];
448
+ if (entry.subscribe !== subscribe) {
449
+ if (entry.unsubscribe) entry.unsubscribe();
450
+ const onChange = () => {
451
+ const next = getSnapshot();
452
+ if (!Object.is(entry.snapshot, next)) {
453
+ entry.snapshot = next;
454
+ ctx.scheduleRerender();
455
+ }
456
+ };
457
+ entry.unsubscribe = subscribe(onChange);
458
+ entry.subscribe = subscribe;
459
+ }
460
+ entry.snapshot = getSnapshot();
461
+ return entry.snapshot;
462
+ }
463
+ const _promiseCache = /* @__PURE__ */ new WeakMap();
464
+ /**
465
+ * React-compatible `use` — reads a Context or suspends on a Promise.
466
+ * Can be called conditionally (unlike other hooks).
467
+ *
468
+ * IMPORTANT: Promises must have a stable identity across renders.
469
+ * Create promises outside the component or memoize them. Calling
470
+ * `use(fetch('/api'))` creates a new promise each render and will
471
+ * cause infinite suspension.
472
+ */
473
+ function use(resource) {
474
+ if (resource && typeof resource === "object" && COMPAT_CTX in resource) return useContext(resource);
475
+ if (resource && typeof resource === "object" && "id" in resource && "defaultValue" in resource) return useContext$1(resource);
476
+ const promise = resource;
477
+ let entry = _promiseCache.get(promise);
478
+ if (!entry) {
479
+ entry = { status: "pending" };
480
+ _promiseCache.set(promise, entry);
481
+ promise.then((value) => {
482
+ entry.status = "resolved";
483
+ entry.value = value;
484
+ }, (error) => {
485
+ entry.status = "rejected";
486
+ entry.error = error;
487
+ });
488
+ }
489
+ if (entry.status === "resolved") return entry.value;
490
+ if (entry.status === "rejected") throw entry.error;
491
+ throw promise;
492
+ }
493
+ /**
494
+ * React-compatible `useActionState` — manages async action state with pending indicator.
495
+ */
496
+ function useActionState(action, initialState) {
497
+ const [state, setState] = useState(initialState);
498
+ const [isPending, setIsPending] = useState(false);
499
+ const dispatch = (payload) => {
500
+ setIsPending(true);
501
+ const result = action(state, payload);
502
+ if (result instanceof Promise) result.then((next) => {
503
+ setState(next);
504
+ setIsPending(false);
505
+ });
506
+ else {
507
+ setState(result);
508
+ setIsPending(false);
509
+ }
510
+ };
511
+ return [
512
+ state,
513
+ dispatch,
514
+ isPending
515
+ ];
516
+ }
517
+ /**
518
+ * React-compatible `startTransition` — runs the callback synchronously.
519
+ * No concurrent mode in Pyreon, so transitions are immediate.
520
+ */
521
+ function startTransition(fn) {
522
+ fn();
523
+ }
524
+ /**
525
+ * React-compatible `isValidElement` — checks if a value is a VNode.
526
+ */
527
+ function isValidElement(value) {
528
+ return value != null && typeof value === "object" && "type" in value && "props" in value;
529
+ }
530
+ /**
531
+ * React-compatible `useDebugValue` — no-op in Pyreon (no React DevTools integration).
532
+ */
533
+ function useDebugValue(_value, _format) {}
534
+ /**
535
+ * React-compatible `flushSync` — runs the callback synchronously.
536
+ *
537
+ * BEHAVIORAL DIFFERENCE: In Pyreon's compat model, state updates are
538
+ * batched via microtask. flushSync runs the callback and returns its
539
+ * result, but the DOM updates triggered by state changes inside the
540
+ * callback still fire asynchronously. For DOM measurement after state
541
+ * updates, use `await act(() => setState(...))` in tests, or
542
+ * `requestAnimationFrame` in production code.
543
+ */
544
+ function flushSync(fn) {
545
+ return fn();
546
+ }
547
+ /**
548
+ * React-compatible `act` — flushes pending microtasks for testing.
549
+ */
550
+ async function act(fn) {
551
+ const result = fn();
552
+ if (result instanceof Promise) await result;
553
+ await new Promise((r) => queueMicrotask(r));
554
+ await new Promise((r) => queueMicrotask(r));
555
+ }
556
+ const version = "19.0.0-pyreon";
557
+ /**
558
+ * React-compatible `StrictMode` — pass-through in Pyreon (no double-invoke behavior).
559
+ */
560
+ function StrictMode(props) {
561
+ return props.children ?? null;
562
+ }
563
+ /**
564
+ * React-compatible `Profiler` — pass-through in Pyreon (no profiling integration).
565
+ */
566
+ function Profiler(props) {
567
+ return props.children ?? null;
568
+ }
569
+ /**
570
+ * React-compatible `Component` class stub.
571
+ * Class components are not fully supported — use function components with hooks.
572
+ */
573
+ var Component = class {
574
+ props;
575
+ state;
576
+ constructor(props) {
577
+ this.props = props;
578
+ this.state = {};
579
+ }
580
+ setState(_partial) {
581
+ console.warn("[Pyreon] Class component setState is not supported. Use function components with hooks.");
582
+ }
583
+ forceUpdate() {
584
+ console.warn("[Pyreon] Class component forceUpdate is not supported. Use function components with hooks.");
585
+ }
586
+ render() {
587
+ return null;
588
+ }
589
+ };
590
+ /**
591
+ * React-compatible `PureComponent` class stub.
592
+ */
593
+ var PureComponent = class extends Component {};
278
594
 
279
595
  //#endregion
280
- export { Children, ErrorBoundary, Fragment, Suspense, batch, cloneElement, createContext, createElement, createPortal, forwardRef, h, lazy, memo, useCallback, useContext, useDeferredValue, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useTransition };
596
+ export { Children, Component, ErrorBoundary, Fragment, Profiler, PureComponent, StrictMode, Suspense, 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 };
281
597
  //# sourceMappingURL=index.js.map