@pyreon/core 0.22.0 → 0.23.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 CHANGED
@@ -1,98 +1,216 @@
1
1
  # @pyreon/core
2
2
 
3
- Core component model, VNode types, lifecycle hooks, and control-flow components for Pyreon.
3
+ Component model, JSX runtime, lifecycle, context, and control-flow components for Pyreon.
4
+
5
+ `@pyreon/core` provides `h()`, the JSX automatic runtime, lifecycle hooks (`onMount`/`onUnmount`/`onUpdate`/`onErrorCaptured`), a two-tier context system (static vs reactive), control-flow components (`Show`, `Switch`/`Match`, `For`, `Suspense`, `ErrorBoundary`, `Portal`, `Dynamic`), code-splitting via `lazy()`, and props utilities that preserve reactivity through HOC pipelines. **Components run ONCE** — re-rendering on signal change is not the model; reactivity is per-binding via accessors read inside JSX text thunks, effects, or computeds. Sits one layer above `@pyreon/reactivity` and is consumed by both `runtime-dom` (CSR) and `runtime-server` (SSR).
4
6
 
5
7
  ## Install
6
8
 
7
9
  ```bash
8
- bun add @pyreon/core
10
+ bun add @pyreon/core @pyreon/reactivity
11
+ ```
12
+
13
+ ## TypeScript / JSX setup
14
+
15
+ In your `tsconfig.json`:
16
+
17
+ ```json
18
+ {
19
+ "compilerOptions": {
20
+ "jsx": "preserve",
21
+ "jsxImportSource": "@pyreon/core"
22
+ }
23
+ }
9
24
  ```
10
25
 
11
- ## Quick Start
26
+ The compiler (`@pyreon/compiler`, via `@pyreon/vite-plugin`) then transforms JSX into `_tpl()` + `_bind()` templates against this runtime.
27
+
28
+ ## Quick start
12
29
 
13
30
  ```tsx
14
- import { onMount, onUnmount, createContext, useContext } from '@pyreon/core'
31
+ import {
32
+ onMount, createContext, createReactiveContext, provide, useContext,
33
+ Show, Switch, Match, For, Suspense, ErrorBoundary, lazy,
34
+ } from '@pyreon/core'
35
+ import { signal } from '@pyreon/reactivity'
36
+
37
+ const ModeCtx = createReactiveContext<'light' | 'dark'>('light')
15
38
 
16
- function Counter() {
39
+ function Timer() {
40
+ const count = signal(0)
17
41
  onMount(() => {
18
- console.log('mounted')
42
+ const id = setInterval(() => count.update(n => n + 1), 1000)
43
+ return () => clearInterval(id)
19
44
  })
45
+ return <div>{() => count()}</div>
46
+ }
47
+
48
+ function Page(props: { items: { id: number; name: string }[] }) {
49
+ const mode = signal<'light' | 'dark'>('dark')
50
+ provide(ModeCtx, () => mode())
51
+
52
+ return (
53
+ <Switch fallback={<p>None</p>}>
54
+ <Match when={() => props.items.length > 0}>
55
+ <For each={props.items} by={i => i.id}>{i => <li>{i.name}</li>}</For>
56
+ </Match>
57
+ </Switch>
58
+ )
59
+ }
20
60
 
21
- return <div>Hello Pyreon</div>
61
+ const Heavy = lazy(() => import('./Heavy'))
62
+ function App() {
63
+ return (
64
+ <ErrorBoundary fallback={(e) => <p>{String(e)}</p>}>
65
+ <Suspense fallback={<div>Loading…</div>}>
66
+ <Heavy />
67
+ </Suspense>
68
+ </ErrorBoundary>
69
+ )
22
70
  }
23
71
  ```
24
72
 
25
- ## API
73
+ ## The reactive-vs-static rule
74
+
75
+ Components run once. What's reactive depends on **where** you read a signal:
26
76
 
27
- ### VNode Creation
77
+ ```tsx
78
+ // REACTIVE — compiler wraps DOM text in an accessor
79
+ <div>{name()}</div>
28
80
 
29
- - **`h<P>(type, props, ...children): VNode`** -- Creates a virtual node. Accepts element tags, component functions, or Fragment.
30
- - **`Fragment`** -- Groups children without adding a wrapper DOM element.
31
- - **`EMPTY_PROPS`** -- Shared empty props object.
81
+ // REACTIVE explicit accessor
82
+ <div>{() => `Hi ${name()}`}</div>
32
83
 
33
- ### Components
84
+ // REACTIVE — props read inside a reactive scope
85
+ <Comp title={name()} />
34
86
 
35
- - **`defineComponent(fn)`** -- Wraps a function as a named component.
36
- - **`runWithHooks(instance, fn)`** -- Executes a function within a component's hook context.
37
- - **`propagateError(error, instance)`** -- Propagates an error up the component tree.
38
- - **`dispatchToErrorBoundary(error, instance)`** -- Sends an error to the nearest ErrorBoundary.
87
+ // STATIC destructured at component setup, captured once
88
+ const { items } = props
89
+ return <For each={items} ...>...</For> // items is frozen at first read
90
+
91
+ // REACTIVE — read live
92
+ return <For each={props.items} ...>...</For>
93
+ ```
39
94
 
40
- ### Lifecycle Hooks
95
+ `const x = props.y` IS reactive: the compiler inlines `props.y` back at the use site when `x` is a `const`. `let x = props.y` is static (mutable, not safe to inline).
41
96
 
42
- - **`onMount(fn: () => CleanupFn | void)`** -- Runs after the component mounts. Optionally return a cleanup function.
43
- - **`onUnmount(fn)`** -- Runs when the component is removed.
44
- - **`onUpdate(fn)`** -- Runs after each reactive update.
45
- - **`onErrorCaptured(fn)`** -- Captures errors thrown by descendant components.
97
+ ## Lifecycle
46
98
 
47
- Lifecycle hook arrays are lazy-allocated -- `LifecycleHooks.mount`/`.unmount`/`.update`/`.error` start as `null` and are only allocated on first hook registration. Components with no hooks (the majority) pay zero allocation cost.
99
+ ```tsx
100
+ onMount(() => {
101
+ const ws = new WebSocket(url)
102
+ return () => ws.close() // cleanup runs on unmount
103
+ })
104
+
105
+ onUnmount(() => { /* … */ })
106
+ onUpdate(() => { /* … */ })
107
+ onErrorCaptured((err, info) => { /* return true to stop propagation */ })
108
+ ```
48
109
 
49
- ### Props Reactivity
110
+ `onMount`'s return value is the cleanup function — there's no separate `useEffect`-style pair. Hook arrays are lazy-allocated; components with no hooks pay zero cost.
50
111
 
51
- - **`makeReactiveProps(raw)`** -- Converts compiler-emitted `_rp()` wrappers into getter properties. Uses a scan-first strategy: checks for any branded reactive prop before allocating the result object. Static-only components return `raw` immediately with no allocation.
52
- - **`_rp(fn)`** -- Brands a function as a reactive prop wrapper (compiler-emitted, not user-facing).
53
- - **`_wrapSpread(source)`** -- Compiler-emitted helper that makes JSX spread on a component reactivity-safe. For `<Comp {...source}>`, the compiler emits `<Comp {..._wrapSpread(source)}>`. `_wrapSpread` walks `source`'s own keys without firing getters and re-brands each getter-shaped value as an `_rp` thunk pointing back at the live source. JS spread then carries the brands as plain data properties; `makeReactiveProps` converts them back to getters on the consumer side -- so reactive props survive the spread end-to-end. Fast path: when `source` has no getter descriptors, returns the source unchanged (zero cost). Not user-facing; emitted automatically by `@pyreon/compiler` for any component JSX with a spread. See `docs/patterns/reactive-spread.md` for the full contract.
112
+ ## Context
54
113
 
55
- ### Context
114
+ Two flavors, deliberately distinct:
56
115
 
57
- - **`createContext<T>(defaultValue?): Context<T>`** -- Creates a context with an optional default.
58
- - **`useContext(ctx): T`** -- Reads the nearest provided context value.
59
- - **`provide(ctx, value)`** -- Provides a context value for the current component's subtree (auto-cleans up on unmount).
60
- - **`withContext(ctx, value, fn)`** -- Runs `fn` with the given context value.
61
- - **`pushContext(map)` / `popContext()`** -- Low-level context stack manipulation.
116
+ ```tsx
117
+ // Static context: useContext returns T directly, safe to destructure
118
+ const ThemeCtx = createContext<'light' | 'dark'>('light')
119
+ const theme = useContext(ThemeCtx) // 'light' | 'dark'
120
+
121
+ // Reactive context: useContext returns () => T, call it inside reactive scopes
122
+ const ModeCtx = createReactiveContext<'light' | 'dark'>('light')
123
+ const getMode = useContext(ModeCtx)
124
+ return <div>{() => getMode()}</div>
125
+ ```
62
126
 
63
- ### Refs
127
+ `provide(ctx, value)` pushes a context frame and auto-cleans up on unmount. `withContext(ctx, value, fn)` is the bounded form for non-component scopes.
64
128
 
65
- - **`createRef<T>(): Ref<T>`** -- Creates a mutable ref object.
129
+ ## Control flow
66
130
 
67
- ### Control-Flow Components
131
+ ```tsx
132
+ <Show when={isReady()}>{() => <Page />}</Show>
133
+ <Show when={count} fallback={<Loading />}>{(n) => <p>{n}</p>}</Show>
68
134
 
69
- - **`Show`** -- Conditionally renders children based on a `when` prop.
70
- - **`Switch` / `Match`** -- Multi-branch conditional rendering.
71
- - **`For`** -- Keyed list rendering with efficient reconciliation.
72
- - **`Portal`** -- Renders children into a different DOM container.
73
- - **`Suspense`** -- Shows fallback content while async children resolve.
74
- - **`ErrorBoundary`** -- Catches errors in descendant components and renders a fallback.
135
+ <Switch fallback={<NotFound />}>
136
+ <Match when={isAdmin()}><AdminPanel /></Match>
137
+ <Match when={isUser()}><UserPanel /></Match>
138
+ </Switch>
75
139
 
76
- ### Props Utilities
140
+ <For each={items} by={item => item.id}>
141
+ {(item) => <li>{item.name}</li>}
142
+ </For>
143
+
144
+ <Portal mount={document.body}><Modal /></Portal>
145
+ <Dynamic component={tag()} {...props} />
146
+ <Defer>{() => <Heavy />}</Defer> // mount after first paint
147
+ ```
148
+
149
+ `<For>` uses **`by`** (not `key`) — JSX reserves `key` as a VNode reconciliation prop. `Show` / `Match` accept either a value (`when={isOpen()}`) or an accessor (`when={() => isOpen()}`) — both work, but only the accessor form re-evaluates on signal change.
150
+
151
+ ## Suspense + lazy
152
+
153
+ ```tsx
154
+ const Heavy = lazy(() => import('./Heavy'))
155
+
156
+ <Suspense fallback={<div>Loading…</div>}>
157
+ <Heavy />
158
+ </Suspense>
159
+ ```
160
+
161
+ `lazy()` integrates with `Suspense` — async work inside the lazy module pauses rendering until resolved. SSR streams the fallback then patches in the resolved subtree.
162
+
163
+ ## Props utilities
164
+
165
+ ```tsx
166
+ import { splitProps, mergeProps, cx, createUniqueId } from '@pyreon/core'
167
+
168
+ function Button(props: ButtonProps) {
169
+ const [local, rest] = splitProps(props, ['variant', 'size'])
170
+ const merged = mergeProps({ type: 'button' }, rest)
171
+ const id = createUniqueId() // 'pyreon-1', SSR-safe
172
+ return (
173
+ <button id={id} {...merged} class={cx('btn', `btn-${local.variant}`, local.size && `size-${local.size}`)}>
174
+ {props.children}
175
+ </button>
176
+ )
177
+ }
178
+ ```
179
+
180
+ `splitProps` and `mergeProps` copy property **descriptors** (not values), so getter-shaped reactive props survive. Plain `result[key] = source[key]` fires the getter at copy time and collapses reactivity — use these helpers instead.
181
+
182
+ ## ErrorBoundary
183
+
184
+ ```tsx
185
+ <ErrorBoundary fallback={(err, reset) => (
186
+ <div role="alert">
187
+ <p>{String(err)}</p>
188
+ <button onClick={reset}>Retry</button>
189
+ </div>
190
+ )}>
191
+ <App />
192
+ </ErrorBoundary>
193
+ ```
77
194
 
78
- - **`splitProps(props, keys)`** -- Splits a props object into `[picked, rest]`, preserving signal reactivity.
79
- - **`mergeProps(...sources)`** -- Merges multiple props objects; last source wins. Preserves reactivity.
80
- - **`createUniqueId(): string`** -- Returns an SSR-safe unique ID (`"pyreon-1"`, `"pyreon-2"`, etc.).
195
+ Captures any error thrown in descendants. Pair with `registerErrorHandler` / `reportError` for telemetry.
81
196
 
82
- ### Class Utility
197
+ ## Compiler-emitted helpers
83
198
 
84
- - **`cx(...values: ClassValue[]): string`** -- Combines class values (strings, arrays, objects, nested mix) into a single class string.
199
+ `_rp(fn)`, `_wrapSpread(source)`, `makeReactiveProps(raw)`, `REACTIVE_PROP` emitted by `@pyreon/compiler` and consumed by `runtime-dom` / `runtime-server`. Not user-facing in normal code. If you write a manual HOC pipeline that copies props in plain JS (not via JSX spread), reach for `splitProps`/`mergeProps` descriptor preservation is load-bearing for reactivity.
85
200
 
86
- ### Utilities
201
+ `nativeCompat(Component)` — marker that tells `@pyreon/{react,preact,vue,solid}-compat` jsx() runtimes to route the component through `h(type, props)` directly, skipping the compat wrapper. Only relevant for hand-rolled Pyreon-flavored helpers used inside compat-mode apps.
87
202
 
88
- - **`mapArray(source, mapFn)`** -- Reactively maps over an array source.
89
- - **`registerErrorHandler(handler)` / `reportError(error, context)`** -- Global error telemetry.
203
+ ## Common conventions
90
204
 
91
- ### Types
205
+ - `class`, not `className`
206
+ - `for`, not `htmlFor`
207
+ - `onInput`, not `onChange`, for per-keystroke input updates
208
+ - `style={{ … }}` accepts a CSS-object; `style="…"` accepts a CSS string
209
+ - `data-*` / `aria-*` attributes typed via template-literal index signatures (catches typos)
92
210
 
93
- `VNode`, `VNodeChild`, `VNodeChildAtom`, `VNodeChildAccessor`, `Props`, `ComponentFn`, `ExtractProps`, `HigherOrderComponent`, `ComponentInstance`, `LifecycleHooks`, `CleanupFn`, `NativeItem`, `Ref`, `Context`, `LazyComponent`, `ShowProps`, `SwitchProps`, `MatchProps`, `ForProps`, `PortalProps`, `ErrorContext`, `ErrorHandler`, `ClassValue`, `TargetedEvent`, `PyreonHTMLAttributes`, `CSSProperties`, `StyleValue`, `CanvasAttributes`
211
+ ## Documentation
94
212
 
95
- **VNodeChild union ordering**: `VNodeChild = VNodeChildAccessor | VNodeChildAtom | VNodeChildAtom[]` — the accessor type is FIRST so TypeScript matches `{() => cond && <X />}` against the function arm without falling through to `VNodeChildAtom` and erroring on `false | VNode`.
213
+ Full docs: [docs.pyreon.dev/docs/core](https://docs.pyreon.dev/docs/core) (or `docs/docs/core.md` in this repo).
96
214
 
97
215
  ## License
98
216
 
@@ -0,0 +1,48 @@
1
+ //#region src/h.ts
2
+ /**
3
+ * Marker for fragment nodes — renders children without a wrapper element.
4
+ *
5
+ * MUST use `Symbol.for(...)` (global registry, keyed by string), NOT
6
+ * `Symbol(...)` (fresh per evaluation). `h.ts` is inlined into BOTH the
7
+ * main `lib/index.js` and the `lib/jsx-runtime.js` published bundles —
8
+ * each bundle's evaluation of a bare `Symbol(...)` would produce a
9
+ * DISTINCT Symbol identity. JSX `<>` compiles to `jsx(Fragment, ...)` and
10
+ * resolves to jsx-runtime's identity; `runtime-server` checks
11
+ * `vnode.type === Fragment` against the main-entry identity. Mismatch
12
+ * fell through to `renderElement` and crashed SSG with
13
+ * `TypeError: Cannot convert a Symbol value to a string`.
14
+ * `Symbol.for()` keys by string in a global registry shared across all
15
+ * bundle evaluations — same identity everywhere.
16
+ */
17
+ const Fragment = Symbol.for("Pyreon.Fragment");
18
+ /**
19
+ * Hyperscript function — the compiled output of JSX.
20
+ * `<div class="x">hello</div>` → `h("div", { class: "x" }, "hello")`
21
+ *
22
+ * Generic on P so TypeScript validates props match the component's signature
23
+ * at the call site, then stores the result in the loosely-typed VNode.
24
+ */
25
+ /** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */
26
+ const EMPTY_PROPS = {};
27
+ function h(type, props, ...children) {
28
+ return {
29
+ type,
30
+ props: props ?? EMPTY_PROPS,
31
+ children: normalizeChildren(children),
32
+ key: props?.key ?? null
33
+ };
34
+ }
35
+ function normalizeChildren(children) {
36
+ for (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);
37
+ return children;
38
+ }
39
+ function flattenChildren(children) {
40
+ const result = [];
41
+ for (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));
42
+ else result.push(child);
43
+ return result;
44
+ }
45
+
46
+ //#endregion
47
+ export { Fragment as n, h as r, EMPTY_PROPS as t };
48
+ //# sourceMappingURL=h-CYSD6aBx.js.map
@@ -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":"d1de8643-1","name":"lifecycle.ts"},{"uid":"d1de8643-3","name":"component.ts"},{"uid":"d1de8643-5","name":"compat-marker.ts"},{"uid":"d1de8643-7","name":"compat-shared.ts"},{"uid":"d1de8643-9","name":"context.ts"},{"uid":"d1de8643-11","name":"h.ts"},{"uid":"d1de8643-13","name":"dynamic.ts"},{"uid":"d1de8643-15","name":"telemetry.ts"},{"uid":"d1de8643-17","name":"error-boundary.ts"},{"uid":"d1de8643-19","name":"for.ts"},{"uid":"d1de8643-21","name":"ref.ts"},{"uid":"d1de8643-23","name":"defer.ts"},{"uid":"d1de8643-25","name":"lazy.ts"},{"uid":"d1de8643-27","name":"map-array.ts"},{"uid":"d1de8643-29","name":"portal.ts"},{"uid":"d1de8643-31","name":"props.ts"},{"uid":"d1de8643-33","name":"show.ts"},{"uid":"d1de8643-35","name":"style.ts"},{"uid":"d1de8643-37","name":"suspense.ts"},{"uid":"d1de8643-39","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"d1de8643-1":{"renderedLength":3090,"gzipLength":1316,"brotliLength":0,"metaUid":"d1de8643-0"},"d1de8643-3":{"renderedLength":1471,"gzipLength":693,"brotliLength":0,"metaUid":"d1de8643-2"},"d1de8643-5":{"renderedLength":3173,"gzipLength":1409,"brotliLength":0,"metaUid":"d1de8643-4"},"d1de8643-7":{"renderedLength":2346,"gzipLength":1033,"brotliLength":0,"metaUid":"d1de8643-6"},"d1de8643-9":{"renderedLength":3600,"gzipLength":1542,"brotliLength":0,"metaUid":"d1de8643-8"},"d1de8643-11":{"renderedLength":1813,"gzipLength":957,"brotliLength":0,"metaUid":"d1de8643-10"},"d1de8643-13":{"renderedLength":490,"gzipLength":292,"brotliLength":0,"metaUid":"d1de8643-12"},"d1de8643-15":{"renderedLength":1990,"gzipLength":950,"brotliLength":0,"metaUid":"d1de8643-14"},"d1de8643-17":{"renderedLength":1659,"gzipLength":843,"brotliLength":0,"metaUid":"d1de8643-16"},"d1de8643-19":{"renderedLength":700,"gzipLength":478,"brotliLength":0,"metaUid":"d1de8643-18"},"d1de8643-21":{"renderedLength":86,"gzipLength":98,"brotliLength":0,"metaUid":"d1de8643-20"},"d1de8643-23":{"renderedLength":4387,"gzipLength":1891,"brotliLength":0,"metaUid":"d1de8643-22"},"d1de8643-25":{"renderedLength":461,"gzipLength":273,"brotliLength":0,"metaUid":"d1de8643-24"},"d1de8643-27":{"renderedLength":1018,"gzipLength":571,"brotliLength":0,"metaUid":"d1de8643-26"},"d1de8643-29":{"renderedLength":818,"gzipLength":491,"brotliLength":0,"metaUid":"d1de8643-28"},"d1de8643-31":{"renderedLength":6310,"gzipLength":2344,"brotliLength":0,"metaUid":"d1de8643-30"},"d1de8643-33":{"renderedLength":2022,"gzipLength":854,"brotliLength":0,"metaUid":"d1de8643-32"},"d1de8643-35":{"renderedLength":1858,"gzipLength":825,"brotliLength":0,"metaUid":"d1de8643-34"},"d1de8643-37":{"renderedLength":1104,"gzipLength":614,"brotliLength":0,"metaUid":"d1de8643-36"},"d1de8643-39":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"d1de8643-38"}},"nodeMetas":{"d1de8643-0":{"id":"/src/lifecycle.ts","moduleParts":{"index.js":"d1de8643-1"},"imported":[],"importedBy":[{"uid":"d1de8643-38"},{"uid":"d1de8643-2"},{"uid":"d1de8643-8"},{"uid":"d1de8643-16"},{"uid":"d1de8643-22"}]},"d1de8643-2":{"id":"/src/component.ts","moduleParts":{"index.js":"d1de8643-3"},"imported":[{"uid":"d1de8643-0"}],"importedBy":[{"uid":"d1de8643-38"},{"uid":"d1de8643-16"}]},"d1de8643-4":{"id":"/src/compat-marker.ts","moduleParts":{"index.js":"d1de8643-5"},"imported":[],"importedBy":[{"uid":"d1de8643-38"},{"uid":"d1de8643-16"}]},"d1de8643-6":{"id":"/src/compat-shared.ts","moduleParts":{"index.js":"d1de8643-7"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-8":{"id":"/src/context.ts","moduleParts":{"index.js":"d1de8643-9"},"imported":[{"uid":"d1de8643-40"},{"uid":"d1de8643-0"}],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-10":{"id":"/src/h.ts","moduleParts":{"index.js":"d1de8643-11"},"imported":[],"importedBy":[{"uid":"d1de8643-38"},{"uid":"d1de8643-12"},{"uid":"d1de8643-22"},{"uid":"d1de8643-24"},{"uid":"d1de8643-36"}]},"d1de8643-12":{"id":"/src/dynamic.ts","moduleParts":{"index.js":"d1de8643-13"},"imported":[{"uid":"d1de8643-10"}],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-14":{"id":"/src/telemetry.ts","moduleParts":{"index.js":"d1de8643-15"},"imported":[{"uid":"d1de8643-40"}],"importedBy":[{"uid":"d1de8643-38"},{"uid":"d1de8643-16"}]},"d1de8643-16":{"id":"/src/error-boundary.ts","moduleParts":{"index.js":"d1de8643-17"},"imported":[{"uid":"d1de8643-40"},{"uid":"d1de8643-4"},{"uid":"d1de8643-2"},{"uid":"d1de8643-0"},{"uid":"d1de8643-14"}],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-18":{"id":"/src/for.ts","moduleParts":{"index.js":"d1de8643-19"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-20":{"id":"/src/ref.ts","moduleParts":{"index.js":"d1de8643-21"},"imported":[],"importedBy":[{"uid":"d1de8643-38"},{"uid":"d1de8643-22"}]},"d1de8643-22":{"id":"/src/defer.ts","moduleParts":{"index.js":"d1de8643-23"},"imported":[{"uid":"d1de8643-40"},{"uid":"d1de8643-10"},{"uid":"d1de8643-0"},{"uid":"d1de8643-20"}],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-24":{"id":"/src/lazy.ts","moduleParts":{"index.js":"d1de8643-25"},"imported":[{"uid":"d1de8643-40"},{"uid":"d1de8643-10"}],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-26":{"id":"/src/map-array.ts","moduleParts":{"index.js":"d1de8643-27"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-28":{"id":"/src/portal.ts","moduleParts":{"index.js":"d1de8643-29"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-30":{"id":"/src/props.ts","moduleParts":{"index.js":"d1de8643-31"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-32":{"id":"/src/show.ts","moduleParts":{"index.js":"d1de8643-33"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-34":{"id":"/src/style.ts","moduleParts":{"index.js":"d1de8643-35"},"imported":[],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-36":{"id":"/src/suspense.ts","moduleParts":{"index.js":"d1de8643-37"},"imported":[{"uid":"d1de8643-10"}],"importedBy":[{"uid":"d1de8643-38"}]},"d1de8643-38":{"id":"/src/index.ts","moduleParts":{"index.js":"d1de8643-39"},"imported":[{"uid":"d1de8643-2"},{"uid":"d1de8643-4"},{"uid":"d1de8643-6"},{"uid":"d1de8643-8"},{"uid":"d1de8643-12"},{"uid":"d1de8643-16"},{"uid":"d1de8643-18"},{"uid":"d1de8643-10"},{"uid":"d1de8643-22"},{"uid":"d1de8643-24"},{"uid":"d1de8643-0"},{"uid":"d1de8643-26"},{"uid":"d1de8643-28"},{"uid":"d1de8643-30"},{"uid":"d1de8643-20"},{"uid":"d1de8643-32"},{"uid":"d1de8643-34"},{"uid":"d1de8643-36"},{"uid":"d1de8643-14"}],"importedBy":[],"isEntry":true},"d1de8643-40":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"d1de8643-8"},{"uid":"d1de8643-16"},{"uid":"d1de8643-22"},{"uid":"d1de8643-24"},{"uid":"d1de8643-14"}]}},"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":"1b1bcb41-1","name":"lifecycle.ts"},{"uid":"1b1bcb41-3","name":"component.ts"},{"uid":"1b1bcb41-5","name":"compat-marker.ts"},{"uid":"1b1bcb41-7","name":"compat-shared.ts"},{"uid":"1b1bcb41-9","name":"context.ts"},{"uid":"1b1bcb41-11","name":"dynamic.ts"},{"uid":"1b1bcb41-13","name":"telemetry.ts"},{"uid":"1b1bcb41-15","name":"error-boundary.ts"},{"uid":"1b1bcb41-17","name":"for.ts"},{"uid":"1b1bcb41-19","name":"ref.ts"},{"uid":"1b1bcb41-21","name":"defer.ts"},{"uid":"1b1bcb41-23","name":"lazy.ts"},{"uid":"1b1bcb41-25","name":"map-array.ts"},{"uid":"1b1bcb41-27","name":"portal.ts"},{"uid":"1b1bcb41-29","name":"props.ts"},{"uid":"1b1bcb41-31","name":"show.ts"},{"uid":"1b1bcb41-33","name":"style.ts"},{"uid":"1b1bcb41-35","name":"suspense.ts"},{"uid":"1b1bcb41-37","name":"index.ts"}]}]},{"name":"jsx-dev-runtime.js","children":[{"name":"src/jsx-dev-runtime.ts","uid":"1b1bcb41-39"}]},{"name":"jsx-runtime.js","children":[{"name":"src/jsx-runtime.ts","uid":"1b1bcb41-41"}]},{"name":"_chunks/h-CYSD6aBx.js","children":[{"name":"src/h.ts","uid":"1b1bcb41-43"}]}],"isRoot":true},"nodeParts":{"1b1bcb41-1":{"renderedLength":3090,"gzipLength":1316,"brotliLength":0,"metaUid":"1b1bcb41-0"},"1b1bcb41-3":{"renderedLength":1908,"gzipLength":881,"brotliLength":0,"metaUid":"1b1bcb41-2"},"1b1bcb41-5":{"renderedLength":3173,"gzipLength":1409,"brotliLength":0,"metaUid":"1b1bcb41-4"},"1b1bcb41-7":{"renderedLength":2346,"gzipLength":1033,"brotliLength":0,"metaUid":"1b1bcb41-6"},"1b1bcb41-9":{"renderedLength":5216,"gzipLength":2147,"brotliLength":0,"metaUid":"1b1bcb41-8"},"1b1bcb41-11":{"renderedLength":490,"gzipLength":292,"brotliLength":0,"metaUid":"1b1bcb41-10"},"1b1bcb41-13":{"renderedLength":1990,"gzipLength":950,"brotliLength":0,"metaUid":"1b1bcb41-12"},"1b1bcb41-15":{"renderedLength":1666,"gzipLength":843,"brotliLength":0,"metaUid":"1b1bcb41-14"},"1b1bcb41-17":{"renderedLength":700,"gzipLength":478,"brotliLength":0,"metaUid":"1b1bcb41-16"},"1b1bcb41-19":{"renderedLength":86,"gzipLength":98,"brotliLength":0,"metaUid":"1b1bcb41-18"},"1b1bcb41-21":{"renderedLength":4387,"gzipLength":1891,"brotliLength":0,"metaUid":"1b1bcb41-20"},"1b1bcb41-23":{"renderedLength":461,"gzipLength":273,"brotliLength":0,"metaUid":"1b1bcb41-22"},"1b1bcb41-25":{"renderedLength":1018,"gzipLength":571,"brotliLength":0,"metaUid":"1b1bcb41-24"},"1b1bcb41-27":{"renderedLength":818,"gzipLength":491,"brotliLength":0,"metaUid":"1b1bcb41-26"},"1b1bcb41-29":{"renderedLength":6310,"gzipLength":2344,"brotliLength":0,"metaUid":"1b1bcb41-28"},"1b1bcb41-31":{"renderedLength":2022,"gzipLength":854,"brotliLength":0,"metaUid":"1b1bcb41-30"},"1b1bcb41-33":{"renderedLength":1858,"gzipLength":825,"brotliLength":0,"metaUid":"1b1bcb41-32"},"1b1bcb41-35":{"renderedLength":1104,"gzipLength":614,"brotliLength":0,"metaUid":"1b1bcb41-34"},"1b1bcb41-37":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"1b1bcb41-36"},"1b1bcb41-39":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"1b1bcb41-38"},"1b1bcb41-41":{"renderedLength":1789,"gzipLength":834,"brotliLength":0,"metaUid":"1b1bcb41-40"},"1b1bcb41-43":{"renderedLength":1813,"gzipLength":957,"brotliLength":0,"metaUid":"1b1bcb41-42"}},"nodeMetas":{"1b1bcb41-0":{"id":"/src/lifecycle.ts","moduleParts":{"index.js":"1b1bcb41-1"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"},{"uid":"1b1bcb41-2"},{"uid":"1b1bcb41-8"},{"uid":"1b1bcb41-14"},{"uid":"1b1bcb41-20"}]},"1b1bcb41-2":{"id":"/src/component.ts","moduleParts":{"index.js":"1b1bcb41-3"},"imported":[{"uid":"1b1bcb41-0"}],"importedBy":[{"uid":"1b1bcb41-36"},{"uid":"1b1bcb41-14"}]},"1b1bcb41-4":{"id":"/src/compat-marker.ts","moduleParts":{"index.js":"1b1bcb41-5"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"},{"uid":"1b1bcb41-14"}]},"1b1bcb41-6":{"id":"/src/compat-shared.ts","moduleParts":{"index.js":"1b1bcb41-7"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-8":{"id":"/src/context.ts","moduleParts":{"index.js":"1b1bcb41-9"},"imported":[{"uid":"1b1bcb41-44"},{"uid":"1b1bcb41-0"}],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-10":{"id":"/src/dynamic.ts","moduleParts":{"index.js":"1b1bcb41-11"},"imported":[{"uid":"1b1bcb41-42"}],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-12":{"id":"/src/telemetry.ts","moduleParts":{"index.js":"1b1bcb41-13"},"imported":[{"uid":"1b1bcb41-44"}],"importedBy":[{"uid":"1b1bcb41-36"},{"uid":"1b1bcb41-14"}]},"1b1bcb41-14":{"id":"/src/error-boundary.ts","moduleParts":{"index.js":"1b1bcb41-15"},"imported":[{"uid":"1b1bcb41-44"},{"uid":"1b1bcb41-4"},{"uid":"1b1bcb41-2"},{"uid":"1b1bcb41-0"},{"uid":"1b1bcb41-12"}],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-16":{"id":"/src/for.ts","moduleParts":{"index.js":"1b1bcb41-17"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-18":{"id":"/src/ref.ts","moduleParts":{"index.js":"1b1bcb41-19"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"},{"uid":"1b1bcb41-20"}]},"1b1bcb41-20":{"id":"/src/defer.ts","moduleParts":{"index.js":"1b1bcb41-21"},"imported":[{"uid":"1b1bcb41-44"},{"uid":"1b1bcb41-42"},{"uid":"1b1bcb41-0"},{"uid":"1b1bcb41-18"}],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-22":{"id":"/src/lazy.ts","moduleParts":{"index.js":"1b1bcb41-23"},"imported":[{"uid":"1b1bcb41-44"},{"uid":"1b1bcb41-42"}],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-24":{"id":"/src/map-array.ts","moduleParts":{"index.js":"1b1bcb41-25"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-26":{"id":"/src/portal.ts","moduleParts":{"index.js":"1b1bcb41-27"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-28":{"id":"/src/props.ts","moduleParts":{"index.js":"1b1bcb41-29"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-30":{"id":"/src/show.ts","moduleParts":{"index.js":"1b1bcb41-31"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-32":{"id":"/src/style.ts","moduleParts":{"index.js":"1b1bcb41-33"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-34":{"id":"/src/suspense.ts","moduleParts":{"index.js":"1b1bcb41-35"},"imported":[{"uid":"1b1bcb41-42"}],"importedBy":[{"uid":"1b1bcb41-36"}]},"1b1bcb41-36":{"id":"/src/index.ts","moduleParts":{"index.js":"1b1bcb41-37"},"imported":[{"uid":"1b1bcb41-2"},{"uid":"1b1bcb41-4"},{"uid":"1b1bcb41-6"},{"uid":"1b1bcb41-8"},{"uid":"1b1bcb41-10"},{"uid":"1b1bcb41-14"},{"uid":"1b1bcb41-16"},{"uid":"1b1bcb41-42"},{"uid":"1b1bcb41-20"},{"uid":"1b1bcb41-22"},{"uid":"1b1bcb41-0"},{"uid":"1b1bcb41-24"},{"uid":"1b1bcb41-26"},{"uid":"1b1bcb41-28"},{"uid":"1b1bcb41-18"},{"uid":"1b1bcb41-30"},{"uid":"1b1bcb41-32"},{"uid":"1b1bcb41-34"},{"uid":"1b1bcb41-12"}],"importedBy":[],"isEntry":true},"1b1bcb41-38":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-dev-runtime.js":"1b1bcb41-39"},"imported":[{"uid":"1b1bcb41-40"}],"importedBy":[],"isEntry":true},"1b1bcb41-40":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"1b1bcb41-41"},"imported":[{"uid":"1b1bcb41-42"}],"importedBy":[{"uid":"1b1bcb41-38"}],"isEntry":true},"1b1bcb41-42":{"id":"/src/h.ts","moduleParts":{"_chunks/h-CYSD6aBx.js":"1b1bcb41-43"},"imported":[],"importedBy":[{"uid":"1b1bcb41-36"},{"uid":"1b1bcb41-10"},{"uid":"1b1bcb41-20"},{"uid":"1b1bcb41-22"},{"uid":"1b1bcb41-34"},{"uid":"1b1bcb41-40"}]},"1b1bcb41-44":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"1b1bcb41-8"},{"uid":"1b1bcb41-14"},{"uid":"1b1bcb41-20"},{"uid":"1b1bcb41-22"},{"uid":"1b1bcb41-12"}]}},"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,3 +1,4 @@
1
+ import { n as Fragment, r as h, t as EMPTY_PROPS } from "./_chunks/h-CYSD6aBx.js";
1
2
  import { effect, getReactiveTrace, setSnapshotCapture, signal } from "@pyreon/reactivity";
2
3
 
3
4
  //#region src/lifecycle.ts
@@ -145,8 +146,19 @@ const _errorBoundaryStack = [];
145
146
  function pushErrorBoundary(handler) {
146
147
  _errorBoundaryStack.push(handler);
147
148
  }
148
- function popErrorBoundary() {
149
- _errorBoundaryStack.pop();
149
+ /**
150
+ * Remove a SPECIFIC handler from the error-boundary stack by reference
151
+ * identity. Each `ErrorBoundary` registers `onUnmount(() => popErrorBoundary(handler))`
152
+ * with its OWN handler — so unmount in any order (LIFO, FIFO, middle-out)
153
+ * correctly removes the right handler.
154
+ */
155
+ function popErrorBoundary(handler) {
156
+ if (handler === void 0) {
157
+ _errorBoundaryStack.pop();
158
+ return;
159
+ }
160
+ const idx = _errorBoundaryStack.lastIndexOf(handler);
161
+ if (idx !== -1) _errorBoundaryStack.splice(idx, 1);
150
162
  }
151
163
  /**
152
164
  * Dispatch an error to the nearest active ErrorBoundary.
@@ -334,11 +346,42 @@ process.env.NODE_ENV;
334
346
  function pushContext(values) {
335
347
  getStack().push(values);
336
348
  }
349
+ /**
350
+ * Pop the LAST frame from the context stack.
351
+ *
352
+ * NOTE: position-based pop. Safe ONLY when the caller can guarantee that the
353
+ * top of the stack is the frame they want to remove (the strict LIFO contract).
354
+ * The `provide()` helper does NOT use this — it uses identity-based removal
355
+ * via `removeContextFrame` because reactive boundaries can push snapshot
356
+ * frames between a component's `provide(ctx, value)` and its eventual
357
+ * unmount, making the top-of-stack unsafe to assume.
358
+ */
337
359
  function popContext() {
338
360
  const stack = getStack();
339
361
  if (stack.length === 0) return;
340
362
  stack.pop();
341
363
  }
364
+ /**
365
+ * Remove a SPECIFIC frame from the context stack by reference identity.
366
+ *
367
+ * Internal — used by `provide()` and `withContext()` to safely clean up
368
+ * their pushed frame on unmount even when other frames have been pushed
369
+ * between push and pop (e.g. a reactive boundary's `restoreContextStack`
370
+ * pushing snapshot frames during the descendant's lifecycle). The
371
+ * symmetric position-based `popContext()` would pop the wrong frame in
372
+ * that case and orphan the descendant's provider frame on the live stack
373
+ * — the root cause of the 321k-entry context-stack leak under repeated
374
+ * reactive remounts.
375
+ *
376
+ * Uses `lastIndexOf` (LIFO match) — picks the most-recently-pushed frame
377
+ * with that exact reference, so `provide(ctx, a); provide(ctx, b)` followed
378
+ * by two unmounts removes them in reverse order.
379
+ */
380
+ function removeContextFrame(frame) {
381
+ const stack = getStack();
382
+ const idx = stack.lastIndexOf(frame);
383
+ if (idx !== -1) stack.splice(idx, 1);
384
+ }
342
385
  function useContext(context) {
343
386
  const stack = getStack();
344
387
  for (let i = stack.length - 1; i >= 0; i--) {
@@ -359,19 +402,21 @@ function useContext(context) {
359
402
  * }
360
403
  */
361
404
  function provide(context, value) {
362
- pushContext(new Map([[context.id, value]]));
363
- onUnmount(() => popContext());
405
+ const frame = new Map([[context.id, value]]);
406
+ pushContext(frame);
407
+ onUnmount(() => removeContextFrame(frame));
364
408
  }
365
409
  /**
366
410
  * Provide a value for `context` during `fn()`.
367
411
  * Used by the renderer when it encounters a `<Provider>` component.
368
412
  */
369
413
  function withContext(context, value, fn) {
370
- pushContext(new Map([[context.id, value]]));
414
+ const frame = new Map([[context.id, value]]);
415
+ pushContext(frame);
371
416
  try {
372
417
  fn();
373
418
  } finally {
374
- popContext();
419
+ removeContextFrame(frame);
375
420
  }
376
421
  }
377
422
  /**
@@ -400,12 +445,16 @@ function captureContextStack() {
400
445
  */
401
446
  function restoreContextStack(snapshot, fn) {
402
447
  const stack = getStack();
403
- const insertIndex = stack.length;
404
448
  for (const frame of snapshot) stack.push(frame);
405
449
  try {
406
450
  return fn();
407
451
  } finally {
408
- stack.splice(insertIndex, snapshot.length);
452
+ for (let i = snapshot.length - 1; i >= 0; i--) {
453
+ const frame = snapshot[i];
454
+ if (!frame) continue;
455
+ const idx = stack.lastIndexOf(frame);
456
+ if (idx !== -1) stack.splice(idx, 1);
457
+ }
409
458
  }
410
459
  }
411
460
  setSnapshotCapture({
@@ -413,52 +462,6 @@ setSnapshotCapture({
413
462
  restore: (snap, fn) => restoreContextStack(snap, fn)
414
463
  });
415
464
 
416
- //#endregion
417
- //#region src/h.ts
418
- /**
419
- * Marker for fragment nodes — renders children without a wrapper element.
420
- *
421
- * MUST use `Symbol.for(...)` (global registry, keyed by string), NOT
422
- * `Symbol(...)` (fresh per evaluation). `h.ts` is inlined into BOTH the
423
- * main `lib/index.js` and the `lib/jsx-runtime.js` published bundles —
424
- * each bundle's evaluation of a bare `Symbol(...)` would produce a
425
- * DISTINCT Symbol identity. JSX `<>` compiles to `jsx(Fragment, ...)` and
426
- * resolves to jsx-runtime's identity; `runtime-server` checks
427
- * `vnode.type === Fragment` against the main-entry identity. Mismatch
428
- * fell through to `renderElement` and crashed SSG with
429
- * `TypeError: Cannot convert a Symbol value to a string`.
430
- * `Symbol.for()` keys by string in a global registry shared across all
431
- * bundle evaluations — same identity everywhere.
432
- */
433
- const Fragment = Symbol.for("Pyreon.Fragment");
434
- /**
435
- * Hyperscript function — the compiled output of JSX.
436
- * `<div class="x">hello</div>` → `h("div", { class: "x" }, "hello")`
437
- *
438
- * Generic on P so TypeScript validates props match the component's signature
439
- * at the call site, then stores the result in the loosely-typed VNode.
440
- */
441
- /** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */
442
- const EMPTY_PROPS = {};
443
- function h(type, props, ...children) {
444
- return {
445
- type,
446
- props: props ?? EMPTY_PROPS,
447
- children: normalizeChildren(children),
448
- key: props?.key ?? null
449
- };
450
- }
451
- function normalizeChildren(children) {
452
- for (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);
453
- return children;
454
- }
455
- function flattenChildren(children) {
456
- const result = [];
457
- for (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));
458
- else result.push(child);
459
- return result;
460
- }
461
-
462
465
  //#endregion
463
466
  //#region src/dynamic.ts
464
467
  const __DEV__$4 = process.env.NODE_ENV !== "production";
@@ -577,7 +580,7 @@ function ErrorBoundary(props) {
577
580
  return true;
578
581
  };
579
582
  pushErrorBoundary(handler);
580
- onUnmount(() => popErrorBoundary());
583
+ onUnmount(() => popErrorBoundary(handler));
581
584
  return () => {
582
585
  const err = error();
583
586
  if (err != null) return props.fallback(err, reset);
@@ -1198,5 +1201,5 @@ function Suspense(props) {
1198
1201
  }
1199
1202
 
1200
1203
  //#endregion
1201
- export { CSS_UNITLESS, Defer, Dynamic, EMPTY_PROPS, ErrorBoundary, For, ForSymbol, Fragment, Match, MatchSymbol, NATIVE_COMPAT_MARKER, Portal, PortalSymbol, REACTIVE_PROP, Show, Suspense, Switch, _rp, _wrapSpread, captureContextStack, createContext, createReactiveContext, createRef, createUniqueId, cx, defineComponent, dispatchToErrorBoundary, h, isNativeCompat, lazy, makeReactiveProps, mapArray, mapCompatDomProps, mergeProps, nativeCompat, normalizeStyleValue, onErrorCaptured, onMount, onUnmount, onUpdate, popContext, propagateError, provide, pushContext, registerErrorHandler, reportError, restoreContextStack, runWithHooks, setContextStackProvider, shallowEqualProps, splitProps, toKebabCase, useContext, withContext };
1204
+ export { CSS_UNITLESS, Defer, Dynamic, EMPTY_PROPS, ErrorBoundary, For, ForSymbol, Fragment, Match, MatchSymbol, NATIVE_COMPAT_MARKER, Portal, PortalSymbol, REACTIVE_PROP, Show, Suspense, Switch, _rp, _wrapSpread, captureContextStack, createContext, createReactiveContext, createRef, createUniqueId, cx, defineComponent, dispatchToErrorBoundary, h, isNativeCompat, lazy, makeReactiveProps, mapArray, mapCompatDomProps, mergeProps, nativeCompat, normalizeStyleValue, onErrorCaptured, onMount, onUnmount, onUpdate, popContext, propagateError, provide, pushContext, registerErrorHandler, removeContextFrame, reportError, restoreContextStack, runWithHooks, setContextStackProvider, shallowEqualProps, splitProps, toKebabCase, useContext, withContext };
1202
1205
  //# sourceMappingURL=index.js.map