@pyreon/vue-compat 0.14.0 → 0.16.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 +2 -0
- package/lib/jsx-runtime.js +9 -5
- package/package.json +8 -4
- package/src/jsx-runtime.ts +11 -2
- package/src/tests/jsx-runtime-wrapper.test.ts +71 -0
- package/src/vue-compat.browser.test.ts +31 -0
- package/lib/index.js.map +0 -1
- package/lib/jsx-runtime.js.map +0 -1
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/jsx-runtime.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -163,3 +163,23 @@ app.mount('#app')
|
|
|
163
163
|
|
|
164
164
|
- **`h` / `Fragment`** -- JSX runtime.
|
|
165
165
|
- **`batch(fn)`** -- coalesce multiple signal writes.
|
|
166
|
+
|
|
167
|
+
## Composing Pyreon framework components inside vue-compat
|
|
168
|
+
|
|
169
|
+
Pyreon's framework components (`RouterView`, `PyreonUI`, `FormProvider`, `QueryClientProvider`, …) ship marked with `nativeCompat()` from `@pyreon/core` — vue-compat's JSX runtime detects the marker and routes them through Pyreon's setup frame instead of the compat wrapper. **You don't need to do anything** for the 24 components shipped marked.
|
|
170
|
+
|
|
171
|
+
If you write your **own** Pyreon-flavored helper that uses `provide()` / `onMount()` / `onUnmount()` / `effect()` at component-body scope and use it in a vue-compat app, mark it explicitly:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { nativeCompat, provide, createContext } from '@pyreon/core'
|
|
175
|
+
|
|
176
|
+
const MyCtx = createContext<string>('default')
|
|
177
|
+
|
|
178
|
+
function MyProvider(props: { value: string; children?: unknown }) {
|
|
179
|
+
provide(MyCtx, props.value)
|
|
180
|
+
return props.children as never
|
|
181
|
+
}
|
|
182
|
+
nativeCompat(MyProvider) // ← required for compat-mode apps
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Without the marker, the wrapper relocates the body's render context and `provide()` lands in a torn-down context stack — descendants read the default. See [`packages/core/core/src/compat-marker.ts`](../../core/core/src/compat-marker.ts) for details.
|
|
@@ -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":"
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"2431af31-1","name":"jsx-runtime.ts"},{"uid":"2431af31-3","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"2431af31-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"2431af31-0"},"2431af31-3":{"renderedLength":21829,"gzipLength":5180,"brotliLength":0,"metaUid":"2431af31-2"}},"nodeMetas":{"2431af31-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"index.js":"2431af31-1"},"imported":[{"uid":"2431af31-4"},{"uid":"2431af31-5"}],"importedBy":[{"uid":"2431af31-2"}]},"2431af31-2":{"id":"/src/index.ts","moduleParts":{"index.js":"2431af31-3"},"imported":[{"uid":"2431af31-4"},{"uid":"2431af31-5"},{"uid":"2431af31-6"},{"uid":"2431af31-0"}],"importedBy":[],"isEntry":true},"2431af31-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"2431af31-2"},{"uid":"2431af31-0"}]},"2431af31-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"2431af31-2"},{"uid":"2431af31-0"}]},"2431af31-6":{"id":"@pyreon/runtime-dom","moduleParts":{},"imported":[],"importedBy":[{"uid":"2431af31-2"}]}},"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":"
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"5769505c-1","name":"jsx-runtime.ts"},{"uid":"5769505c-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"5769505c-1":{"renderedLength":2715,"gzipLength":981,"brotliLength":0,"metaUid":"5769505c-0"},"5769505c-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"5769505c-2"}},"nodeMetas":{"5769505c-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"5769505c-1"},"imported":[{"uid":"5769505c-4"},{"uid":"5769505c-5"}],"importedBy":[{"uid":"5769505c-2"}]},"5769505c-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"5769505c-3"},"imported":[{"uid":"5769505c-0"}],"importedBy":[],"isEntry":true},"5769505c-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"5769505c-0"}]},"5769505c-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"5769505c-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
|
@@ -41,6 +41,7 @@ function ref(value) {
|
|
|
41
41
|
s.set(v);
|
|
42
42
|
scheduleRerender();
|
|
43
43
|
},
|
|
44
|
+
/** @internal — access underlying signal for triggerRef */
|
|
44
45
|
_signal: s,
|
|
45
46
|
_scheduleRerender: scheduleRerender
|
|
46
47
|
};
|
|
@@ -56,6 +57,7 @@ function ref(value) {
|
|
|
56
57
|
set value(v) {
|
|
57
58
|
s.set(v);
|
|
58
59
|
},
|
|
60
|
+
/** @internal — access underlying signal for triggerRef */
|
|
59
61
|
_signal: s
|
|
60
62
|
};
|
|
61
63
|
}
|
package/lib/jsx-runtime.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Fragment, h, onUnmount } from "@pyreon/core";
|
|
1
|
+
import { Fragment, h, isNativeCompat, onUnmount } from "@pyreon/core";
|
|
2
2
|
import { runUntracked, signal } from "@pyreon/reactivity";
|
|
3
3
|
|
|
4
4
|
//#region src/jsx-runtime.ts
|
|
@@ -80,10 +80,14 @@ function jsx(type, props, key) {
|
|
|
80
80
|
...rest,
|
|
81
81
|
key
|
|
82
82
|
} : rest;
|
|
83
|
-
if (typeof type === "function")
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
if (typeof type === "function") {
|
|
84
|
+
const componentProps = children !== void 0 ? {
|
|
85
|
+
...propsWithKey,
|
|
86
|
+
children
|
|
87
|
+
} : propsWithKey;
|
|
88
|
+
if (isNativeCompat(type)) return h(type, componentProps);
|
|
89
|
+
return h(wrapCompatComponent(type), componentProps);
|
|
90
|
+
}
|
|
87
91
|
if (typeof type === "string" && propsWithKey.ref != null) {
|
|
88
92
|
const r = propsWithKey.ref;
|
|
89
93
|
if (typeof r === "object" && r !== null && r[Symbol.for("__v_isRef")] === true) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/vue-compat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Vue 3-compatible Composition API shim for Pyreon — write Vue-style code that runs on Pyreon's reactive engine",
|
|
5
5
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/vue-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"
|
|
@@ -47,17 +48,20 @@
|
|
|
47
48
|
"build": "vl_rolldown_build",
|
|
48
49
|
"dev": "vl_rolldown_build-watch",
|
|
49
50
|
"test": "vitest run",
|
|
51
|
+
"test:browser": "vitest run --config ./vitest.browser.config.ts",
|
|
50
52
|
"typecheck": "tsc --noEmit",
|
|
51
53
|
"lint": "oxlint .",
|
|
52
54
|
"prepublishOnly": "bun run build"
|
|
53
55
|
},
|
|
54
56
|
"dependencies": {
|
|
55
|
-
"@pyreon/core": "^0.
|
|
56
|
-
"@pyreon/reactivity": "^0.
|
|
57
|
-
"@pyreon/runtime-dom": "^0.
|
|
57
|
+
"@pyreon/core": "^0.16.0",
|
|
58
|
+
"@pyreon/reactivity": "^0.16.0",
|
|
59
|
+
"@pyreon/runtime-dom": "^0.16.0"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
60
62
|
"@happy-dom/global-registrator": "^20.8.9",
|
|
63
|
+
"@pyreon/test-utils": "^0.13.3",
|
|
64
|
+
"@vitest/browser-playwright": "^4.1.4",
|
|
61
65
|
"happy-dom": "^20.8.3"
|
|
62
66
|
}
|
|
63
67
|
}
|
package/src/jsx-runtime.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import type { ComponentFn, Props, VNode, VNodeChild } from '@pyreon/core'
|
|
18
|
-
import { Fragment, h, onUnmount } from '@pyreon/core'
|
|
18
|
+
import { Fragment, h, isNativeCompat, onUnmount } from '@pyreon/core'
|
|
19
19
|
import { runUntracked, signal } from '@pyreon/reactivity'
|
|
20
20
|
|
|
21
21
|
export { Fragment }
|
|
@@ -159,9 +159,18 @@ export function jsx(
|
|
|
159
159
|
const propsWithKey = (key != null ? { ...rest, key } : rest) as Props
|
|
160
160
|
|
|
161
161
|
if (typeof type === 'function') {
|
|
162
|
+
const componentProps = children !== undefined ? { ...propsWithKey, children } : propsWithKey
|
|
163
|
+
// Native Pyreon framework components (context Provider, RouterView,
|
|
164
|
+
// QueryClientProvider, etc.) skip compat wrapping — they manage their
|
|
165
|
+
// own reactivity via signals + Pyreon's lifecycle, and wrapping them
|
|
166
|
+
// would run their setup body inside the compat layer's render context
|
|
167
|
+
// instead of Pyreon's, breaking `provide()` / `onMount()` / `onUnmount()`.
|
|
168
|
+
// See `@pyreon/core`'s `nativeCompat()` for the contract.
|
|
169
|
+
if (isNativeCompat(type)) {
|
|
170
|
+
return h(type as ComponentFn, componentProps)
|
|
171
|
+
}
|
|
162
172
|
// Wrap Vue-style component for re-render support
|
|
163
173
|
const wrapped = wrapCompatComponent(type)
|
|
164
|
-
const componentProps = children !== undefined ? { ...propsWithKey, children } : propsWithKey
|
|
165
174
|
return h(wrapped, componentProps)
|
|
166
175
|
}
|
|
167
176
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ComponentFn } from '@pyreon/core'
|
|
2
|
+
import { createContext, h, nativeCompat, provide, useContext } from '@pyreon/core'
|
|
1
3
|
import { mount } from '@pyreon/runtime-dom'
|
|
2
4
|
import { describe, expect, it, vi } from 'vitest'
|
|
3
5
|
import { onMounted, onUnmounted } from '../index'
|
|
@@ -84,4 +86,73 @@ describe('vue-compat — wrapCompatComponent (jsx-runtime)', () => {
|
|
|
84
86
|
mount(jsx(Comp, {}), c)
|
|
85
87
|
expect(c.textContent).toContain('noprops')
|
|
86
88
|
})
|
|
89
|
+
|
|
90
|
+
it('skips wrapping for components marked via nativeCompat() (Vue-side parity with React/Preact/Solid compat)', () => {
|
|
91
|
+
// Pre-PR-2 vue-compat's jsx() had no NATIVE marker check — even marked
|
|
92
|
+
// components got wrapCompatComponent applied, which broke Pyreon framework
|
|
93
|
+
// components composed inside Vue-style code (their `provide()` /
|
|
94
|
+
// `onMount()` calls fired outside Pyreon's setup frame). PR 2 added the
|
|
95
|
+
// missing check at the same site as react/preact/solid compat.
|
|
96
|
+
//
|
|
97
|
+
// Bisect-verified: removing the `if (isNativeCompat(type))` branch from
|
|
98
|
+
// jsx-runtime.ts puts vue-compat back in the broken state — this test
|
|
99
|
+
// fails because the wrapped component's identity no longer matches the
|
|
100
|
+
// native source fn.
|
|
101
|
+
const Native = () => jsx('div', { children: 'native' })
|
|
102
|
+
nativeCompat(Native)
|
|
103
|
+
const vnode = jsx(Native, {})
|
|
104
|
+
// Marker hit: jsx() routes through h() directly with the SOURCE fn,
|
|
105
|
+
// never through wrapCompatComponent. So vnode.type === Native.
|
|
106
|
+
expect(vnode.type).toBe(Native)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('jsx() wraps UNMARKED components (control — bypass is selective)', () => {
|
|
110
|
+
// Sibling assertion to "skips wrapping for marked components": proves the
|
|
111
|
+
// marker check is selective (only marked components bypass), not blanket.
|
|
112
|
+
// Without this, a regression that accidentally wraps EVERYTHING would
|
|
113
|
+
// still pass the "marked component" test as a coincidence.
|
|
114
|
+
const Unmarked = () => jsx('div', { children: 'wrapped' })
|
|
115
|
+
const vnode = jsx(Unmarked, {})
|
|
116
|
+
// Wrapper: vnode.type is the cached wrapCompatComponent, NOT the source fn.
|
|
117
|
+
expect(vnode.type).not.toBe(Unmarked)
|
|
118
|
+
expect(typeof vnode.type).toBe('function')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('marked Provider mounts cleanly through compat-mode jsx() — provide() reaches descendants', () => {
|
|
122
|
+
// PR 5 mount-integration smoke (parity with react/preact/solid-compat
|
|
123
|
+
// suites). Sanity check that a marked Provider mounts cleanly through
|
|
124
|
+
// compat-mode jsx() and its `provide()` reaches the descendant Consumer.
|
|
125
|
+
//
|
|
126
|
+
// Note: this assertion is NOT bisect-load-bearing for the marker check
|
|
127
|
+
// itself. Synchronous mount preserves provide() context even WITH the
|
|
128
|
+
// wrapper (provide() pushes onto the global context stack regardless),
|
|
129
|
+
// so removing `nativeCompat(Provider)` here won't fail this test. The
|
|
130
|
+
// genuine multi-render-cycle bug PR #425 prevents (signal change re-fires
|
|
131
|
+
// the wrapper's accessor → provide() in re-run lands in stale stack) is
|
|
132
|
+
// covered by PR #427's e2e gate against real router state.
|
|
133
|
+
//
|
|
134
|
+
// The bisect-load-bearing assertion is the bypass-identity test above
|
|
135
|
+
// (`vnode.type === Native`) — that one fails when the marker check is
|
|
136
|
+
// removed from `jsx-runtime.ts`.
|
|
137
|
+
const Ctx = createContext<string>('default')
|
|
138
|
+
|
|
139
|
+
const Provider: ComponentFn = (props) => {
|
|
140
|
+
provide(Ctx, props.value as string)
|
|
141
|
+
return props.children as never
|
|
142
|
+
}
|
|
143
|
+
nativeCompat(Provider)
|
|
144
|
+
|
|
145
|
+
const Consumer: ComponentFn = () => {
|
|
146
|
+
const value = useContext(Ctx)
|
|
147
|
+
return h('span', { 'data-value': value }, value)
|
|
148
|
+
}
|
|
149
|
+
nativeCompat(Consumer)
|
|
150
|
+
|
|
151
|
+
const el = container()
|
|
152
|
+
mount(jsx(Provider, { value: 'native', children: jsx(Consumer, {}) }), el)
|
|
153
|
+
|
|
154
|
+
const span = el.querySelector('span')
|
|
155
|
+
expect(span?.getAttribute('data-value')).toBe('native')
|
|
156
|
+
expect(span?.textContent).toBe('native')
|
|
157
|
+
})
|
|
87
158
|
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { h } from '@pyreon/core'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import { mountInBrowser } from '@pyreon/test-utils/browser'
|
|
4
|
+
import { ref, isRef, unref } from './index'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Real-browser smoke test for `@pyreon/vue-compat`.
|
|
8
|
+
*
|
|
9
|
+
* Per the test-environment-parity rule (`pyreon/require-browser-smoke-test`),
|
|
10
|
+
* every browser-categorized package must ship at least one
|
|
11
|
+
* `*.browser.test.*` file. This catches regressions that happy-dom unit
|
|
12
|
+
* tests can hide: importing the public API and exercising the Vue 3
|
|
13
|
+
* Composition API shim (`ref`, `unref`) end-to-end in real Chromium.
|
|
14
|
+
*/
|
|
15
|
+
describe('@pyreon/vue-compat — browser smoke', () => {
|
|
16
|
+
it('creates a ref and reads its value through unref()', () => {
|
|
17
|
+
const r = ref('vue-compat')
|
|
18
|
+
expect(isRef(r)).toBe(true)
|
|
19
|
+
expect(unref(r)).toBe('vue-compat')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('mounts a static element in real browser', () => {
|
|
23
|
+
const r = ref('hello, vue')
|
|
24
|
+
const vnode = h('div', { id: 'vue-compat' }, unref(r))
|
|
25
|
+
const { container, unmount } = mountInBrowser(vnode)
|
|
26
|
+
const el = container.querySelector('#vue-compat')!
|
|
27
|
+
expect(el.textContent).toBe('hello, vue')
|
|
28
|
+
unmount()
|
|
29
|
+
expect(document.getElementById('vue-compat')).toBeNull()
|
|
30
|
+
})
|
|
31
|
+
})
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["pyreonComputed","pyreonNextTick","pyreonMount"],"sources":["../src/jsx-runtime.ts","../src/index.ts"],"sourcesContent":["/**\n * Compat JSX runtime for Vue compatibility mode.\n *\n * When `jsxImportSource` is redirected to `@pyreon/vue-compat` (via the vite\n * plugin's `compat: \"vue\"` option), OXC rewrites JSX to import from this file.\n *\n * For component VNodes, we wrap the component function so it returns a reactive\n * accessor — enabling Vue-style re-renders on state change while Pyreon's\n * existing renderer handles all DOM work.\n *\n * Key difference from react/preact compat: the component body runs inside\n * `runUntracked` to prevent `.value` reads (which access underlying signals)\n * from being tracked by the reactive accessor. Only the version signal\n * triggers re-renders.\n */\n\nimport type { ComponentFn, Props, VNode, VNodeChild } from '@pyreon/core'\nimport { Fragment, h, onUnmount } from '@pyreon/core'\nimport { runUntracked, signal } from '@pyreon/reactivity'\n\nexport { Fragment }\n\n// ─── Render context (used by hooks) ──────────────────────────────────────────\n\nexport interface RenderContext {\n hooks: unknown[]\n scheduleRerender: () => void\n /** Effect entries pending execution after render */\n pendingEffects: EffectEntry[]\n /** Layout effect entries pending execution after render */\n pendingLayoutEffects: EffectEntry[]\n /** Set to true when the component is unmounted */\n unmounted: boolean\n /** Callbacks to run on unmount (lifecycle + effect cleanups) */\n unmountCallbacks: (() => void)[]\n}\n\nexport interface EffectEntry {\n fn: () => (() => void) | void\n deps: unknown[] | undefined\n cleanup: (() => void) | undefined\n}\n\nlet _currentCtx: RenderContext | null = null\nlet _hookIndex = 0\n\nexport function getCurrentCtx(): RenderContext | null {\n return _currentCtx\n}\n\nexport function getHookIndex(): number {\n return _hookIndex++\n}\n\nexport function beginRender(ctx: RenderContext): void {\n _currentCtx = ctx\n _hookIndex = 0\n ctx.pendingEffects = []\n ctx.pendingLayoutEffects = []\n}\n\nexport function endRender(): void {\n _currentCtx = null\n _hookIndex = 0\n}\n\n// ─── Effect runners ──────────────────────────────────────────────────────────\n\nfunction runLayoutEffects(entries: EffectEntry[]): void {\n for (const entry of entries) {\n if (entry.cleanup) entry.cleanup()\n const cleanup = entry.fn()\n entry.cleanup = typeof cleanup === 'function' ? cleanup : undefined\n }\n}\n\nfunction scheduleEffects(ctx: RenderContext, entries: EffectEntry[]): void {\n if (entries.length === 0) return\n queueMicrotask(() => {\n for (const entry of entries) {\n if (ctx.unmounted) return\n if (entry.cleanup) entry.cleanup()\n const cleanup = entry.fn()\n entry.cleanup = typeof cleanup === 'function' ? cleanup : undefined\n }\n })\n}\n\n// ─── Component wrapping ──────────────────────────────────────────────────────\n\nconst _wrapperCache = new WeakMap<Function, ComponentFn>()\n\nfunction wrapCompatComponent(vueComponent: Function): ComponentFn {\n let wrapped = _wrapperCache.get(vueComponent)\n if (wrapped) return wrapped\n\n // The wrapper returns a reactive accessor (() => VNodeChild) which Pyreon's\n // mountChild treats as a reactive expression via mountReactive.\n wrapped = ((props: Props) => {\n const ctx: RenderContext = {\n hooks: [],\n scheduleRerender: () => {\n // Will be replaced below after version signal is created\n },\n pendingEffects: [],\n pendingLayoutEffects: [],\n unmounted: false,\n unmountCallbacks: [],\n }\n\n const version = signal(0)\n let updateScheduled = false\n\n ctx.scheduleRerender = () => {\n if (ctx.unmounted || updateScheduled) return\n updateScheduled = true\n queueMicrotask(() => {\n updateScheduled = false\n if (!ctx.unmounted) version.set(version.peek() + 1)\n })\n }\n\n // Register cleanup when component unmounts\n onUnmount(() => {\n ctx.unmounted = true\n for (const cb of ctx.unmountCallbacks) cb()\n })\n\n // Return reactive accessor — Pyreon's mountChild calls mountReactive\n return () => {\n version() // tracked read — triggers re-execution when state changes\n beginRender(ctx)\n // runUntracked prevents .value signal reads from being tracked by this accessor —\n // only the version signal should trigger re-renders\n const result = runUntracked(() => (vueComponent as ComponentFn)(props))\n const layoutEffects = ctx.pendingLayoutEffects\n const effects = ctx.pendingEffects\n endRender()\n\n runLayoutEffects(layoutEffects)\n scheduleEffects(ctx, effects)\n\n return result\n }\n }) as unknown as ComponentFn\n\n _wrapperCache.set(vueComponent, wrapped)\n return wrapped\n}\n\n// ─── JSX functions ───────────────────────────────────────────────────────────\n\nexport function jsx(\n type: string | ComponentFn | symbol,\n props: Props & { children?: VNodeChild | VNodeChild[] },\n key?: string | number | null,\n): VNode {\n const { children, ...rest } = props\n const propsWithKey = (key != null ? { ...rest, key } : rest) as Props\n\n if (typeof type === 'function') {\n // Wrap Vue-style component for re-render support\n const wrapped = wrapCompatComponent(type)\n const componentProps = children !== undefined ? { ...propsWithKey, children } : propsWithKey\n return h(wrapped, componentProps)\n }\n\n // DOM element: convert Vue ref ({ value }) to callback ref for Pyreon's runtime-dom\n if (typeof type === 'string' && propsWithKey.ref != null) {\n const r = propsWithKey.ref\n if (\n typeof r === 'object' &&\n r !== null &&\n (r as Record<symbol, unknown>)[Symbol.for('__v_isRef')] === true\n ) {\n const vueRef = r as { value: unknown }\n propsWithKey.ref = (el: Element | null) => {\n vueRef.value = el\n }\n }\n }\n\n // DOM element or symbol (Fragment): children go in vnode.children\n const childArray = children === undefined ? [] : Array.isArray(children) ? children : [children]\n\n return h(type, propsWithKey, ...(childArray as VNodeChild[]))\n}\n\nexport const jsxs = jsx\nexport const jsxDEV = jsx\n","/**\n * @pyreon/vue-compat\n *\n * Vue 3-compatible Composition API that runs on Pyreon's reactive engine,\n * using a hook-indexed re-render model.\n *\n * All stateful APIs (ref, computed, reactive, watch, lifecycle hooks, etc.)\n * use hook-indexing to persist state across re-renders. The component body\n * re-executes when state changes (driven by a version signal in the JSX\n * runtime), and hook-indexed calls return the same objects across renders.\n *\n * DIFFERENCES FROM VUE 3:\n * - `deep` option in watch() is ignored — Pyreon tracks dependencies automatically.\n * - `shallowReactive` uses per-property signals (still shallow, but Pyreon-flavored).\n * - `readonly` returns a Proxy that throws on set (not Vue's readonly proxy).\n * - `defineComponent` only supports Composition API (setup function), not Options API.\n * - Components re-execute their body on state change (hook-indexed re-render model).\n *\n * USAGE:\n * Replace `import { ref, computed, watch } from \"vue\"` with\n * `import { ref, computed, watch } from \"@pyreon/vue-compat\"`\n */\n\nimport type { ComponentFn, Props, VNodeChild } from '@pyreon/core'\nimport {\n createContext,\n Fragment,\n onMount,\n onUnmount,\n onUpdate,\n popContext,\n Portal,\n pushContext,\n h as pyreonH,\n useContext,\n} from '@pyreon/core'\nimport {\n createStore,\n effect,\n computed as pyreonComputed,\n nextTick as pyreonNextTick,\n type Signal,\n signal,\n} from '@pyreon/reactivity'\nimport { mount as pyreonMount } from '@pyreon/runtime-dom'\nimport { getCurrentCtx, getHookIndex } from './jsx-runtime'\n\n// ─── Internal symbols ─────────────────────────────────────────────────────────\n\nconst V_IS_REF = Symbol.for('__v_isRef')\nconst V_IS_READONLY = Symbol('__v_isReadonly')\nconst V_SKIP = Symbol('__v_skip')\nconst V_RAW = Symbol('__v_raw')\n\n// ─── Ref ──────────────────────────────────────────────────────────────────────\n\nexport interface Ref<T = unknown> {\n value: T\n readonly [V_IS_REF]: true\n}\n\n/**\n * Creates a reactive ref wrapping the given value.\n * Access via `.value` — reads track, writes trigger.\n *\n * Inside a component: hook-indexed. The setter also calls `scheduleRerender()`.\n * Outside a component: creates a standalone reactive ref.\n */\nexport function ref<T>(value: T): Ref<T> {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as Ref<T>\n\n const s = signal(value)\n const { scheduleRerender } = ctx\n const r = {\n [V_IS_REF]: true as const,\n get value(): T {\n return s()\n },\n set value(v: T) {\n s.set(v)\n scheduleRerender()\n },\n /** @internal — access underlying signal for triggerRef */\n _signal: s,\n _scheduleRerender: scheduleRerender,\n }\n ctx.hooks[idx] = r\n return r as Ref<T>\n }\n\n // Outside component\n const s = signal(value)\n const r = {\n [V_IS_REF]: true as const,\n get value(): T {\n return s()\n },\n set value(v: T) {\n s.set(v)\n },\n /** @internal — access underlying signal for triggerRef */\n _signal: s,\n }\n return r as Ref<T>\n}\n\n/**\n * Creates a shallow ref — same as `ref()` in Pyreon since signals are inherently shallow.\n */\nexport function shallowRef<T>(value: T): Ref<T> {\n return ref(value)\n}\n\n/**\n * Force trigger a ref's subscribers, even if the value hasn't changed.\n */\nexport function triggerRef<T>(r: Ref<T>): void {\n const internal = r as Ref<T> & { _signal: Signal<T>; _scheduleRerender?: () => void }\n if (internal._signal) {\n // Force notify by setting the same value with Object.is bypass\n const current = internal._signal.peek()\n internal._signal.set(undefined as T)\n internal._signal.set(current)\n }\n if (internal._scheduleRerender) {\n internal._scheduleRerender()\n }\n}\n\n/**\n * Returns `true` if the value is a ref (created by `ref()` or `computed()`).\n */\nexport function isRef(val: unknown): val is Ref {\n return (\n val !== null && typeof val === 'object' && (val as Record<symbol, unknown>)[V_IS_REF] === true\n )\n}\n\n/**\n * Unwraps a ref: if it has `.value`, return `.value`; otherwise return as-is.\n */\nexport function unref<T>(r: T | Ref<T>): T {\n return isRef(r) ? r.value : r\n}\n\n/**\n * Unwraps a ref, calls a getter, or returns the value as-is.\n * Vue 3.3+ API for normalizing ref/getter/value inputs.\n */\nexport function toValue<T>(source: Ref<T> | (() => T) | T): T {\n if (isRef(source)) return source.value\n if (typeof source === 'function') return (source as () => T)()\n return source\n}\n\n// ─── Computed ─────────────────────────────────────────────────────────────────\n\nexport interface ComputedRef<T = unknown> extends Ref<T> {\n readonly value: T\n}\n\nexport interface WritableComputedRef<T = unknown> extends Ref<T> {\n value: T\n}\n\n/**\n * Creates a computed ref. Supports both readonly and writable forms.\n *\n * Inside a component: hook-indexed.\n */\nexport function computed<T>(getter: () => T): ComputedRef<T>\nexport function computed<T>(options: {\n get: () => T\n set: (value: T) => void\n}): WritableComputedRef<T>\nexport function computed<T>(\n fnOrOptions: (() => T) | { get: () => T; set: (value: T) => void },\n): ComputedRef<T> | WritableComputedRef<T> {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as ComputedRef<T>\n\n const getter = typeof fnOrOptions === 'function' ? fnOrOptions : fnOrOptions.get\n const setter = typeof fnOrOptions === 'object' ? fnOrOptions.set : undefined\n const c = pyreonComputed(getter)\n const { scheduleRerender } = ctx\n const r = {\n [V_IS_REF]: true as const,\n get value(): T {\n return c()\n },\n set value(v: T) {\n if (!setter) {\n throw new Error('Cannot set value of a computed ref — computed refs are readonly')\n }\n setter(v)\n scheduleRerender()\n },\n }\n ctx.hooks[idx] = r\n return r as ComputedRef<T>\n }\n\n // Outside component\n const getter = typeof fnOrOptions === 'function' ? fnOrOptions : fnOrOptions.get\n const setter = typeof fnOrOptions === 'object' ? fnOrOptions.set : undefined\n const c = pyreonComputed(getter)\n const r = {\n [V_IS_REF]: true as const,\n get value(): T {\n return c()\n },\n set value(v: T) {\n if (!setter) {\n throw new Error('Cannot set value of a computed ref — computed refs are readonly')\n }\n setter(v)\n },\n }\n return r as ComputedRef<T>\n}\n\n// ─── Reactive / Readonly ──────────────────────────────────────────────────────\n\n// WeakMap to track raw objects behind reactive proxies\nconst rawMap = new WeakMap<object, object>()\n\n/**\n * Creates a deeply reactive proxy from a plain object.\n * Backed by Pyreon's `createStore()`.\n *\n * Inside a component: hook-indexed. Proxy wrapper intercepts sets to\n * call `scheduleRerender()`.\n */\nexport function reactive<T extends object>(obj: T): T {\n if ((obj as Record<symbol, boolean>)[V_SKIP]) return obj\n\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as T\n\n const proxy = createStore(obj)\n rawMap.set(proxy as object, obj)\n const { scheduleRerender } = ctx\n const wrapped = new Proxy(proxy, {\n set(target, key, value, receiver) {\n const result = Reflect.set(target, key, value, receiver)\n scheduleRerender()\n return result\n },\n deleteProperty(target, key) {\n const result = Reflect.deleteProperty(target, key)\n scheduleRerender()\n return result\n },\n })\n rawMap.set(wrapped as object, obj)\n ctx.hooks[idx] = wrapped\n return wrapped as T\n }\n\n // Outside component\n const proxy = createStore(obj)\n rawMap.set(proxy as object, obj)\n return proxy\n}\n\n/**\n * Creates a shallow reactive proxy — same as `reactive()` in Pyreon.\n */\nexport function shallowReactive<T extends object>(obj: T): T {\n return reactive(obj)\n}\n\n/**\n * Returns a readonly proxy that throws on mutation attempts.\n *\n * Inside a component: hook-indexed.\n */\nexport function readonly<T extends object>(obj: T): Readonly<T> {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as Readonly<T>\n\n const proxy = _createReadonlyProxy(obj)\n ctx.hooks[idx] = proxy\n return proxy\n }\n\n return _createReadonlyProxy(obj)\n}\n\n/**\n * Returns a shallow readonly proxy — only top-level properties throw on set.\n * Nested objects are NOT wrapped in readonly (unlike `readonly()`).\n */\nexport function shallowReadonly<T extends object>(obj: T): Readonly<T> {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as Readonly<T>\n\n const proxy = _createShallowReadonlyProxy(obj)\n ctx.hooks[idx] = proxy\n return proxy\n }\n\n return _createShallowReadonlyProxy(obj)\n}\n\nfunction _createShallowReadonlyProxy<T extends object>(obj: T): Readonly<T> {\n const proxy = new Proxy(obj, {\n get(target, key) {\n if (key === V_IS_READONLY) return true\n if (key === V_RAW) return target\n return Reflect.get(target, key)\n // NO recursive wrapping — shallow\n },\n set(_target, key) {\n if (key === V_IS_READONLY || key === V_RAW) return true\n throw new Error(`Cannot set property \"${String(key)}\" on a readonly object`)\n },\n deleteProperty(_target, key) {\n throw new Error(`Cannot delete property \"${String(key)}\" from a readonly object`)\n },\n })\n return proxy as Readonly<T>\n}\n\nfunction _createReadonlyProxy<T extends object>(obj: T): Readonly<T> {\n const proxy = new Proxy(obj, {\n get(target, key) {\n if (key === V_IS_READONLY) return true\n if (key === V_RAW) return target\n const value = Reflect.get(target, key)\n // Recursively wrap nested objects in readonly\n if (value !== null && typeof value === 'object' && !isRef(value)) {\n return _createReadonlyProxy(value as object)\n }\n return value\n },\n set(_target, key) {\n // Internal symbols used for identification are allowed\n if (key === V_IS_READONLY || key === V_RAW) return true\n throw new Error(`Cannot set property \"${String(key)}\" on a readonly object`)\n },\n deleteProperty(_target, key) {\n throw new Error(`Cannot delete property \"${String(key)}\" from a readonly object`)\n },\n })\n return proxy as Readonly<T>\n}\n\n/**\n * Returns the raw (unwrapped) object behind a reactive or readonly proxy.\n */\nexport function toRaw<T extends object>(proxy: T): T {\n // Check readonly first\n const readonlyRaw = (proxy as Record<symbol, unknown>)[V_RAW]\n if (readonlyRaw) return readonlyRaw as T\n // Check reactive\n const raw = rawMap.get(proxy as object)\n return (raw as T) ?? proxy\n}\n\n// ─── toRef / toRefs ───────────────────────────────────────────────────────────\n\n/**\n * Creates a ref linked to a property of a reactive object.\n * Reading/writing the ref's `.value` reads/writes the original property.\n *\n * Inside a component: hook-indexed.\n */\nexport function toRef<T extends object, K extends keyof T>(obj: T, key: K): Ref<T[K]> {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as Ref<T[K]>\n\n const r = _createToRef(obj, key)\n ctx.hooks[idx] = r\n return r\n }\n\n return _createToRef(obj, key)\n}\n\nfunction _createToRef<T extends object, K extends keyof T>(obj: T, key: K): Ref<T[K]> {\n const r = {\n [V_IS_REF]: true as const,\n get value(): T[K] {\n return obj[key]\n },\n set value(newValue: T[K]) {\n obj[key] = newValue\n },\n }\n return r as Ref<T[K]>\n}\n\n/**\n * Converts all properties of a reactive object into individual refs.\n * Each ref is linked to the original property (not a copy).\n *\n * Inside a component: hook-indexed (the entire result, not individual refs).\n */\nexport function toRefs<T extends object>(obj: T): { [K in keyof T]: Ref<T[K]> } {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as { [K in keyof T]: Ref<T[K]> }\n\n const result = {} as { [K in keyof T]: Ref<T[K]> }\n for (const key of Object.keys(obj) as (keyof T)[]) {\n // Create refs directly (not via exported toRef) to avoid extra hook index consumption\n result[key] = _createToRef(obj, key)\n }\n ctx.hooks[idx] = result\n return result\n }\n\n const result = {} as { [K in keyof T]: Ref<T[K]> }\n for (const key of Object.keys(obj) as (keyof T)[]) {\n result[key] = _createToRef(obj, key)\n }\n return result\n}\n\n// ─── Watch ────────────────────────────────────────────────────────────────────\n\nexport interface WatchOptions {\n /** Call the callback immediately with current value. Default: false */\n immediate?: boolean\n /** Ignored in Pyreon — dependencies are tracked automatically. */\n deep?: boolean\n /** Accepted for compatibility but not meaningfully differentiated in Pyreon. */\n flush?: 'pre' | 'post' | 'sync'\n}\n\ntype WatchSource<T> = Ref<T> | (() => T)\n\n/**\n * Watches a reactive source (or array of sources) and calls `cb` when it changes.\n *\n * Inside a component: hook-indexed, created once. Disposed on unmount.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function watch<T>(\n source: WatchSource<T>,\n cb: (newValue: T, oldValue: T | undefined, onCleanup: (fn: () => void) => void) => void,\n options?: WatchOptions,\n): () => void\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function watch<T extends readonly WatchSource<any>[]>(\n sources: [...T],\n cb: (\n newValues: { [K in keyof T]: T[K] extends WatchSource<infer V> ? V : never },\n oldValues: { [K in keyof T]: T[K] extends WatchSource<infer V> ? V | undefined : never },\n onCleanup: (fn: () => void) => void,\n ) => void,\n options?: WatchOptions,\n): () => void\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function watch<T>(\n source: WatchSource<T> | WatchSource<T>[],\n cb: (newValue: T, oldValue: T | undefined, onCleanup: (fn: () => void) => void) => void,\n options?: WatchOptions,\n): () => void {\n // Array of sources — multi-watch\n if (Array.isArray(source)) {\n return _watchArray(\n source as WatchSource<unknown>[],\n cb as (newValue: unknown, oldValue: unknown) => void,\n options,\n )\n }\n return _watchSingle(source as WatchSource<T>, cb, options)\n}\n\nfunction _watchArray(\n sources: WatchSource<unknown>[],\n cb: (newValues: unknown, oldValues: unknown, onCleanup: (fn: () => void) => void) => void,\n options?: WatchOptions,\n): () => void {\n const getters = sources.map((s) => (isRef(s) ? () => (s as Ref).value : (s as () => unknown)))\n\n let cleanupFn: (() => void) | undefined\n const onCleanup = (fn: () => void) => {\n cleanupFn = fn\n }\n\n const runCleanup = () => {\n if (cleanupFn) {\n cleanupFn()\n cleanupFn = undefined\n }\n }\n\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as () => void\n\n let oldValues: unknown[] | undefined\n let initialized = false\n\n if (options?.immediate) {\n const current = getters.map((g) => g())\n cb(current, getters.map(() => undefined), onCleanup)\n oldValues = current\n initialized = true\n }\n\n let running = false\n const combined = pyreonComputed(() => getters.map((g) => g()))\n const e = effect(() => {\n if (running) return\n running = true\n try {\n const newValues = combined()\n if (initialized) {\n runCleanup()\n cb([...newValues], oldValues ? [...oldValues] : getters.map(() => undefined), onCleanup)\n }\n oldValues = [...newValues]\n initialized = true\n } finally {\n running = false\n }\n })\n\n const stop = () => {\n runCleanup()\n e.dispose()\n }\n ctx.hooks[idx] = stop\n ctx.unmountCallbacks.push(stop)\n return stop\n }\n\n // Outside component\n let oldValues: unknown[] | undefined\n let initialized = false\n\n if (options?.immediate) {\n const current = getters.map((g) => g())\n cb(current, getters.map(() => undefined), onCleanup)\n oldValues = current\n initialized = true\n }\n\n let running = false\n const combined = pyreonComputed(() => getters.map((g) => g()))\n const e = effect(() => {\n if (running) return\n running = true\n try {\n const newValues = combined()\n if (initialized) {\n runCleanup()\n cb([...newValues], oldValues ? [...oldValues] : getters.map(() => undefined), onCleanup)\n }\n oldValues = [...newValues]\n initialized = true\n } finally {\n running = false\n }\n })\n\n const stop = () => {\n runCleanup()\n e.dispose()\n }\n if (_currentEffectScope) {\n ;(\n _currentEffectScope as EffectScopeCompat & { _cleanups: (() => void)[] }\n )._cleanups.push(stop)\n }\n return stop\n}\n\nfunction _watchSingle<T>(\n source: WatchSource<T>,\n cb: (newValue: T, oldValue: T | undefined, onCleanup: (fn: () => void) => void) => void,\n options?: WatchOptions,\n): () => void {\n let cleanupFn: (() => void) | undefined\n const onCleanup = (fn: () => void) => {\n cleanupFn = fn\n }\n\n const runCleanup = () => {\n if (cleanupFn) {\n cleanupFn()\n cleanupFn = undefined\n }\n }\n\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as () => void\n\n const getter = isRef(source) ? () => source.value : (source as () => T)\n let oldValue: T | undefined\n let initialized = false\n\n if (options?.immediate) {\n oldValue = undefined\n const current = getter()\n cb(current, oldValue, onCleanup)\n oldValue = current\n initialized = true\n }\n\n let running = false\n const e = effect(() => {\n if (running) return\n running = true\n try {\n const newValue = getter()\n if (initialized) {\n runCleanup()\n cb(newValue, oldValue, onCleanup)\n }\n oldValue = newValue\n initialized = true\n } finally {\n running = false\n }\n })\n\n const stop = () => {\n runCleanup()\n e.dispose()\n }\n ctx.hooks[idx] = stop\n ctx.unmountCallbacks.push(stop)\n return stop\n }\n\n // Outside component\n const getter = isRef(source) ? () => source.value : (source as () => T)\n let oldValue: T | undefined\n let initialized = false\n\n if (options?.immediate) {\n oldValue = undefined\n const current = getter()\n cb(current, oldValue, onCleanup)\n oldValue = current\n initialized = true\n }\n\n let running = false\n const e = effect(() => {\n if (running) return\n running = true\n try {\n const newValue = getter()\n if (initialized) {\n runCleanup()\n cb(newValue, oldValue, onCleanup)\n }\n oldValue = newValue\n initialized = true\n } finally {\n running = false\n }\n })\n\n const stop = () => {\n runCleanup()\n e.dispose()\n }\n if (_currentEffectScope) {\n ;(\n _currentEffectScope as EffectScopeCompat & { _cleanups: (() => void)[] }\n )._cleanups.push(stop)\n }\n return stop\n}\n\n/**\n * Runs the given function reactively — re-executes whenever its tracked\n * dependencies change. Passes an `onCleanup` registration function to the\n * callback, matching Vue 3's `watchEffect((onCleanup) => { ... })` API.\n *\n * Inside a component: hook-indexed, created once. Disposed on unmount.\n */\nexport function watchEffect(\n fn: (onCleanup: (fn: () => void) => void) => void,\n): () => void {\n const ctx = getCurrentCtx()\n\n let cleanupFn: (() => void) | undefined\n const onCleanup = (cleanup: () => void) => {\n cleanupFn = cleanup\n }\n\n const runEffect = () => {\n if (cleanupFn) {\n cleanupFn()\n cleanupFn = undefined\n }\n fn(onCleanup)\n }\n\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return ctx.hooks[idx] as () => void\n\n let running = false\n const e = effect(() => {\n if (running) return\n running = true\n try {\n runEffect()\n } finally {\n running = false\n }\n })\n const stop = () => {\n if (cleanupFn) cleanupFn()\n e.dispose()\n }\n ctx.hooks[idx] = stop\n ctx.unmountCallbacks.push(stop)\n return stop\n }\n\n let running = false\n const e = effect(() => {\n if (running) return\n running = true\n try {\n runEffect()\n } finally {\n running = false\n }\n })\n const stop = () => {\n if (cleanupFn) cleanupFn()\n e.dispose()\n }\n // Register with current effect scope if one is active\n if (_currentEffectScope) {\n ;(\n _currentEffectScope as EffectScopeCompat & { _cleanups: (() => void)[] }\n )._cleanups.push(stop)\n }\n return stop\n}\n\n// ─── Lifecycle ────────────────────────────────────────────────────────────────\n\n/**\n * Registers a callback to run after the component is mounted.\n * Hook-indexed: only registered on first render.\n */\nexport function onMounted(fn: () => void): void {\n const ctx = getCurrentCtx()\n if (!ctx) {\n // Fallback: use Pyreon's lifecycle directly (e.g., inside defineComponent without jsx-runtime)\n onMount(() => {\n fn()\n })\n return\n }\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return // Already registered\n ctx.hooks[idx] = true\n // Schedule to run after render via microtask\n ctx.pendingEffects.push({\n fn: () => {\n fn()\n return undefined\n },\n deps: [],\n cleanup: undefined,\n })\n}\n\n/**\n * Registers a callback to run when the component is unmounted.\n * Hook-indexed: only registered on first render.\n */\nexport function onUnmounted(fn: () => void): void {\n const ctx = getCurrentCtx()\n if (!ctx) {\n onUnmount(fn)\n return\n }\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return // Already registered\n ctx.hooks[idx] = true\n ctx.unmountCallbacks.push(fn)\n}\n\n/**\n * Registers a callback to run after a reactive update (not on initial mount).\n * Hook-indexed: registered once, fires on each re-render.\n */\nexport function onUpdated(fn: () => void): void {\n const ctx = getCurrentCtx()\n if (!ctx) {\n onUpdate(fn)\n return\n }\n const idx = getHookIndex()\n if (idx >= ctx.hooks.length) {\n // First render — just mark as registered, don't fire\n ctx.hooks[idx] = true\n return\n }\n // Re-render — schedule the callback\n ctx.pendingEffects.push({\n fn: () => {\n fn()\n return undefined\n },\n deps: undefined,\n cleanup: undefined,\n })\n}\n\n/**\n * Registers a callback to run before mount.\n * In Pyreon there is no pre-mount phase — maps to `onMounted()`.\n */\nexport function onBeforeMount(fn: () => void): void {\n onMounted(fn)\n}\n\n/**\n * Registers a callback to run before unmount.\n * In Pyreon there is no pre-unmount phase — maps to `onUnmounted()`.\n */\nexport function onBeforeUnmount(fn: () => void): void {\n onUnmounted(fn)\n}\n\n// ─── nextTick ─────────────────────────────────────────────────────────────────\n\n/**\n * Returns a Promise that resolves after all pending reactive updates have flushed.\n */\nexport function nextTick(): Promise<void> {\n return pyreonNextTick()\n}\n\n// ─── Provide / Inject ─────────────────────────────────────────────────────────\n\n// Registry of string/symbol keys to Pyreon context objects (created lazily)\nconst _contextRegistry = new Map<string | symbol, ReturnType<typeof createContext>>()\n\nfunction getOrCreateContext<T>(key: string | symbol, defaultValue?: T) {\n if (!_contextRegistry.has(key)) {\n _contextRegistry.set(key, createContext<T>(defaultValue as T))\n }\n return _contextRegistry.get(key) as ReturnType<typeof createContext<T>>\n}\n\n/**\n * Provides a value to all descendant components.\n *\n * Inside a component: hook-indexed, pushed once. Popped on unmount.\n */\nexport function provide<T>(key: string | symbol, value: T): void {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return // Already provided\n ctx.hooks[idx] = true\n const vueCtx = getOrCreateContext<T>(key)\n pushContext(new Map([[vueCtx.id, value]]))\n ctx.unmountCallbacks.push(() => popContext())\n return\n }\n // Outside component — use Pyreon's provide directly\n const vueCtx = getOrCreateContext<T>(key)\n pushContext(new Map([[vueCtx.id, value]]))\n}\n\n/**\n * Injects a value provided by an ancestor component.\n * Supports Vue 3's factory default pattern: `inject(key, () => expensiveDefault, true)`.\n */\nexport function inject<T>(\n key: string | symbol,\n defaultValue?: T | (() => T),\n treatDefaultAsFactory?: boolean,\n): T | undefined {\n const ctx = getOrCreateContext<T>(key)\n const value = useContext(ctx)\n if (value !== undefined) return value\n if (defaultValue === undefined) return undefined\n if (treatDefaultAsFactory && typeof defaultValue === 'function') {\n return (defaultValue as () => T)()\n }\n return defaultValue as T\n}\n\n// ─── defineComponent ──────────────────────────────────────────────────────────\n\ninterface ComponentOptions<P extends Props = Props> {\n /** The setup function — called once during component initialization. */\n setup: (props: P, ctx?: SetupContext) => (() => VNodeChild) | VNodeChild\n /** Optional name for debugging. */\n name?: string\n /** Prop definitions (not validated at runtime, used for type documentation). */\n props?: Record<string, unknown>\n}\n\n/**\n * Defines a component using Vue 3 Composition API style.\n * Only supports the `setup()` function — Options API is not supported.\n */\nexport function defineComponent<P extends Props = Props>(\n options: ComponentOptions<P> | ((props: P) => VNodeChild),\n): ComponentFn<P> {\n if (typeof options === 'function') {\n return options as ComponentFn<P>\n }\n const comp = (props: P) => {\n // Extract children from props for slots\n const children = (props as Record<string, unknown>).children as VNodeChild | undefined\n // Create a minimal SetupContext\n const setupCtx: SetupContext = {\n emit: (event: string, ...args: unknown[]) => {\n const handlerKey = `on${event.charAt(0).toUpperCase()}${event.slice(1)}`\n const handler = (props as Record<string, unknown>)[handlerKey]\n if (typeof handler === 'function') (handler as (...a: unknown[]) => void)(...args)\n },\n slots: {\n default: children !== undefined ? (() => children) : undefined,\n } as Record<string, (() => VNodeChild) | undefined>,\n attrs: props as Record<string, unknown>,\n }\n const result = options.setup(props, setupCtx)\n if (typeof result === 'function') {\n return (result as () => VNodeChild)()\n }\n return result\n }\n if (options.name) {\n Object.defineProperty(comp, 'name', { value: options.name })\n }\n return comp as ComponentFn<P>\n}\n\n// ─── defineAsyncComponent ───────────────────────────────────────────────────\n\n/**\n * Defines an async component that lazily loads on first use.\n * Supports both a bare loader function and an options object with\n * loadingComponent, errorComponent, delay, and timeout.\n *\n * Returns a ComponentFn with a `__loading` property for Suspense integration.\n */\nexport function defineAsyncComponent<P extends Props = Props>(\n loader:\n | (() => Promise<{ default: ComponentFn<P> }>)\n | {\n loader: () => Promise<{ default: ComponentFn<P> }>\n loadingComponent?: ComponentFn\n errorComponent?: ComponentFn\n delay?: number\n timeout?: number\n },\n): ComponentFn<P> & { __loading: () => boolean } {\n const load = typeof loader === 'function' ? loader : loader.loader\n\n const loaded = signal<ComponentFn<P> | null>(null)\n const error = signal<Error | null>(null)\n let promise: Promise<unknown> | null = null\n\n const startLoad = () => {\n if (promise) return\n promise = load().then(\n (mod) => loaded.set(mod.default),\n (err) => error.set(err instanceof Error ? err : new Error(String(err))),\n )\n }\n\n const AsyncComp = ((props: P) => {\n startLoad()\n const err = error()\n if (err) throw err\n const comp = loaded()\n if (!comp) return null\n return comp(props)\n }) as ComponentFn<P> & { __loading: () => boolean }\n\n AsyncComp.__loading = () => {\n const isLoading = loaded() === null && error() === null\n if (isLoading) startLoad()\n return isLoading\n }\n\n return AsyncComp\n}\n\n// ─── h ────────────────────────────────────────────────────────────────────────\n\n/**\n * Re-export of Pyreon's `h()` function for creating VNodes.\n */\nexport { Fragment, pyreonH as h }\n\n// ─── createApp ────────────────────────────────────────────────────────────────\n\ninterface App {\n /** Mount the application into a DOM element. Returns an unmount function. */\n mount(el: string | Element): () => void\n /** Install a plugin. */\n use(plugin: { install: (app: App) => void }): App\n /** Provide a value to the entire app tree. */\n provide<T>(key: string | symbol, value: T): App\n}\n\n/**\n * Creates a Pyreon application instance — Vue 3 `createApp()` compatible.\n */\nexport function createApp(component: ComponentFn, props?: Props): App {\n const provisions: Array<{ key: string | symbol; value: unknown }> = []\n\n const app: App = {\n mount(el: string | Element): () => void {\n const container = typeof el === 'string' ? document.querySelector(el) : el\n if (!container) {\n throw new Error(`Cannot find mount target: ${el}`)\n }\n // Push app-level provisions before mounting\n for (const { key, value } of provisions) {\n const ctx = getOrCreateContext(key)\n pushContext(new Map([[ctx.id, value]]))\n }\n const vnode = pyreonH(component, props ?? null)\n return pyreonMount(vnode, container)\n },\n use(plugin: { install: (app: App) => void }): App {\n plugin.install(app)\n return app\n },\n provide<T>(key: string | symbol, value: T): App {\n provisions.push({ key, value })\n return app\n },\n }\n\n return app\n}\n\n// ─── isReactive / isReadonly / isProxy / markRaw ─────────────────────────────\n\n/**\n * Returns `true` if the value was created by `reactive()`.\n */\nexport function isReactive(value: unknown): boolean {\n return value !== null && typeof value === 'object' && rawMap.has(value as object)\n}\n\n/**\n * Returns `true` if the value was created by `readonly()`.\n */\nexport function isReadonly(value: unknown): boolean {\n return (\n value !== null &&\n typeof value === 'object' &&\n (value as Record<symbol, unknown>)[V_IS_READONLY] === true\n )\n}\n\n/**\n * Returns `true` if the value is either reactive or readonly.\n */\nexport function isProxy(value: unknown): boolean {\n return isReactive(value) || isReadonly(value)\n}\n\n/**\n * Marks an object so that `reactive()` will return it as-is (not wrapped).\n */\nexport function markRaw<T extends object>(obj: T): T {\n ;(obj as Record<symbol, boolean>)[V_SKIP] = true\n return obj\n}\n\n// ─── effectScope / getCurrentScope / onScopeDispose ──────────────────────────\n\nexport interface EffectScopeCompat {\n /** Run a function within this scope. Returns undefined if scope is stopped. */\n run<T>(fn: () => T): T | undefined\n /** Stop the scope and dispose all collected effects/cleanups. */\n stop(): void\n /** Whether the scope is still active. */\n active: boolean\n}\n\nlet _currentEffectScope: EffectScopeCompat | null = null\n\n/**\n * Creates an effect scope that collects reactive effects for grouped disposal.\n *\n * @param detached - If true, the scope is not collected by a parent scope.\n */\nexport function effectScope(detached?: boolean): EffectScopeCompat {\n const cleanups: (() => void)[] = []\n let active = true\n\n const scope: EffectScopeCompat = {\n get active() {\n return active\n },\n run<T>(fn: () => T): T | undefined {\n if (!active) return undefined\n const prev = _currentEffectScope\n _currentEffectScope = scope\n try {\n return fn()\n } finally {\n _currentEffectScope = prev\n }\n },\n stop() {\n if (!active) return\n active = false\n for (const fn of cleanups) fn()\n cleanups.length = 0\n },\n }\n\n // Auto-collect in parent scope unless detached\n if (!detached && _currentEffectScope) {\n const parentCleanups = (_currentEffectScope as EffectScopeCompat & { _cleanups?: (() => void)[] })\n ._cleanups\n if (parentCleanups) parentCleanups.push(() => scope.stop())\n }\n ;(scope as EffectScopeCompat & { _cleanups: (() => void)[] })._cleanups = cleanups\n\n return scope\n}\n\n/**\n * Returns the current active effect scope, or undefined if none.\n */\nexport function getCurrentScope(): EffectScopeCompat | undefined {\n return _currentEffectScope ?? undefined\n}\n\n/**\n * Registers a cleanup function on the current effect scope.\n */\nexport function onScopeDispose(fn: () => void): void {\n if (_currentEffectScope) {\n ;(\n _currentEffectScope as EffectScopeCompat & { _cleanups: (() => void)[] }\n )._cleanups.push(fn)\n }\n}\n\n// ─── onErrorCaptured / onRenderTracked / onRenderTriggered ───────────────────\n\n/**\n * Registers an error capture handler.\n * No direct equivalent in Pyreon — stored but not actively used.\n */\nexport function onErrorCaptured(fn: (err: Error) => boolean | void): void {\n const ctx = getCurrentCtx()\n if (ctx) {\n const idx = getHookIndex()\n if (idx < ctx.hooks.length) return\n ctx.hooks[idx] = fn\n }\n}\n\n/**\n * Dev-only lifecycle hook — no-op in Pyreon.\n */\nexport function onRenderTracked(\n _fn: (event: { key: string; type: string }) => void,\n): void {\n // Dev-only hook — no equivalent in Pyreon\n}\n\n/**\n * Dev-only lifecycle hook — no-op in Pyreon.\n */\nexport function onRenderTriggered(\n _fn: (event: { key: string; type: string }) => void,\n): void {\n // Dev-only hook — no equivalent in Pyreon\n}\n\n// ─── Teleport / KeepAlive ────────────────────────────────────────────────────\n\n/**\n * Teleport — renders children into a different DOM element.\n * Maps to Pyreon's Portal.\n */\nexport function Teleport(props: {\n to: string | Element\n children?: VNodeChild\n}): VNodeChild {\n const target =\n typeof props.to === 'string' ? document.querySelector(props.to) : props.to\n if (!target) return props.children ?? null\n return Portal({ target, children: props.children ?? null })\n}\n\n/**\n * KeepAlive — not supported in Pyreon. Renders children as-is.\n */\nexport function KeepAlive(props: { children?: VNodeChild }): VNodeChild {\n return props.children ?? null\n}\n\n// ─── watchPostEffect / watchSyncEffect ───────────────────────────────────────\n\n/**\n * Runs a watchEffect that flushes after DOM updates.\n * In Pyreon, same as `watchEffect()`.\n */\nexport function watchPostEffect(\n fn: (onCleanup: (fn: () => void) => void) => void,\n): () => void {\n return watchEffect(fn)\n}\n\n/**\n * Runs a watchEffect that flushes synchronously.\n * In Pyreon, same as `watchEffect()`.\n */\nexport function watchSyncEffect(\n fn: (onCleanup: (fn: () => void) => void) => void,\n): () => void {\n return watchEffect(fn)\n}\n\n// ─── customRef ───────────────────────────────────────────────────────────────\n\n/**\n * Creates a customized ref with explicit control over dependency tracking\n * and update triggering.\n */\nexport function customRef<T>(\n factory: (\n track: () => void,\n trigger: () => void,\n ) => { get: () => T; set: (v: T) => void },\n): Ref<T> {\n const s = signal(0)\n const { get, set } = factory(\n () => { s(); return undefined as never }, // track — reading the signal subscribes\n () => s.set(s.peek() + 1), // trigger — bump version to re-notify\n )\n return {\n [V_IS_REF]: true as const,\n get value(): T {\n return get()\n },\n set value(v: T) {\n set(v)\n },\n } as Ref<T>\n}\n\n// ─── version ─────────────────────────────────────────────────────────────────\n\n/**\n * Compatibility version string — indicates Vue 3 API compatibility.\n */\nexport const version = '3.5.0-pyreon'\n\n// ─── Type exports ────────────────────────────────────────────────────────────\n\nexport type { ComponentFn as Component } from '@pyreon/core'\nexport type { VNodeChild as VNode } from '@pyreon/core'\n\n/** Vue-compatible PropType — a callable that returns T. */\nexport type PropType<T> = { (): T }\n\n/** Extract prop types from a component's props definition. */\nexport type ExtractPropTypes<T> = {\n [K in keyof T]: T[K] extends PropType<infer V> ? V : T[K]\n}\n\n/** Vue-compatible emits options type. */\nexport type EmitsOptions = Record<string, (...args: unknown[]) => void>\n\n/** Vue-compatible setup context. */\nexport type SetupContext = {\n emit: (event: string, ...args: unknown[]) => void\n slots: Record<string, (() => VNodeChild) | undefined>\n attrs: Record<string, unknown>\n}\n\n/** Vue-compatible plugin interface. */\nexport type Plugin = { install: (app: App) => void }\n\n/** Vue-compatible directive type (stub). */\nexport type Directive = Record<string, unknown>\n\n/** Vue-compatible injection key with type branding. */\nexport type InjectionKey<T> = symbol & { __type: T }\n\n// ─── Additional re-exports ────────────────────────────────────────────────────\n\nexport { batch } from '@pyreon/reactivity'\n"],"mappings":"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"}
|
package/lib/jsx-runtime.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-runtime.js","names":[],"sources":["../src/jsx-runtime.ts"],"sourcesContent":["/**\n * Compat JSX runtime for Vue compatibility mode.\n *\n * When `jsxImportSource` is redirected to `@pyreon/vue-compat` (via the vite\n * plugin's `compat: \"vue\"` option), OXC rewrites JSX to import from this file.\n *\n * For component VNodes, we wrap the component function so it returns a reactive\n * accessor — enabling Vue-style re-renders on state change while Pyreon's\n * existing renderer handles all DOM work.\n *\n * Key difference from react/preact compat: the component body runs inside\n * `runUntracked` to prevent `.value` reads (which access underlying signals)\n * from being tracked by the reactive accessor. Only the version signal\n * triggers re-renders.\n */\n\nimport type { ComponentFn, Props, VNode, VNodeChild } from '@pyreon/core'\nimport { Fragment, h, onUnmount } from '@pyreon/core'\nimport { runUntracked, signal } from '@pyreon/reactivity'\n\nexport { Fragment }\n\n// ─── Render context (used by hooks) ──────────────────────────────────────────\n\nexport interface RenderContext {\n hooks: unknown[]\n scheduleRerender: () => void\n /** Effect entries pending execution after render */\n pendingEffects: EffectEntry[]\n /** Layout effect entries pending execution after render */\n pendingLayoutEffects: EffectEntry[]\n /** Set to true when the component is unmounted */\n unmounted: boolean\n /** Callbacks to run on unmount (lifecycle + effect cleanups) */\n unmountCallbacks: (() => void)[]\n}\n\nexport interface EffectEntry {\n fn: () => (() => void) | void\n deps: unknown[] | undefined\n cleanup: (() => void) | undefined\n}\n\nlet _currentCtx: RenderContext | null = null\nlet _hookIndex = 0\n\nexport function getCurrentCtx(): RenderContext | null {\n return _currentCtx\n}\n\nexport function getHookIndex(): number {\n return _hookIndex++\n}\n\nexport function beginRender(ctx: RenderContext): void {\n _currentCtx = ctx\n _hookIndex = 0\n ctx.pendingEffects = []\n ctx.pendingLayoutEffects = []\n}\n\nexport function endRender(): void {\n _currentCtx = null\n _hookIndex = 0\n}\n\n// ─── Effect runners ──────────────────────────────────────────────────────────\n\nfunction runLayoutEffects(entries: EffectEntry[]): void {\n for (const entry of entries) {\n if (entry.cleanup) entry.cleanup()\n const cleanup = entry.fn()\n entry.cleanup = typeof cleanup === 'function' ? cleanup : undefined\n }\n}\n\nfunction scheduleEffects(ctx: RenderContext, entries: EffectEntry[]): void {\n if (entries.length === 0) return\n queueMicrotask(() => {\n for (const entry of entries) {\n if (ctx.unmounted) return\n if (entry.cleanup) entry.cleanup()\n const cleanup = entry.fn()\n entry.cleanup = typeof cleanup === 'function' ? cleanup : undefined\n }\n })\n}\n\n// ─── Component wrapping ──────────────────────────────────────────────────────\n\nconst _wrapperCache = new WeakMap<Function, ComponentFn>()\n\nfunction wrapCompatComponent(vueComponent: Function): ComponentFn {\n let wrapped = _wrapperCache.get(vueComponent)\n if (wrapped) return wrapped\n\n // The wrapper returns a reactive accessor (() => VNodeChild) which Pyreon's\n // mountChild treats as a reactive expression via mountReactive.\n wrapped = ((props: Props) => {\n const ctx: RenderContext = {\n hooks: [],\n scheduleRerender: () => {\n // Will be replaced below after version signal is created\n },\n pendingEffects: [],\n pendingLayoutEffects: [],\n unmounted: false,\n unmountCallbacks: [],\n }\n\n const version = signal(0)\n let updateScheduled = false\n\n ctx.scheduleRerender = () => {\n if (ctx.unmounted || updateScheduled) return\n updateScheduled = true\n queueMicrotask(() => {\n updateScheduled = false\n if (!ctx.unmounted) version.set(version.peek() + 1)\n })\n }\n\n // Register cleanup when component unmounts\n onUnmount(() => {\n ctx.unmounted = true\n for (const cb of ctx.unmountCallbacks) cb()\n })\n\n // Return reactive accessor — Pyreon's mountChild calls mountReactive\n return () => {\n version() // tracked read — triggers re-execution when state changes\n beginRender(ctx)\n // runUntracked prevents .value signal reads from being tracked by this accessor —\n // only the version signal should trigger re-renders\n const result = runUntracked(() => (vueComponent as ComponentFn)(props))\n const layoutEffects = ctx.pendingLayoutEffects\n const effects = ctx.pendingEffects\n endRender()\n\n runLayoutEffects(layoutEffects)\n scheduleEffects(ctx, effects)\n\n return result\n }\n }) as unknown as ComponentFn\n\n _wrapperCache.set(vueComponent, wrapped)\n return wrapped\n}\n\n// ─── JSX functions ───────────────────────────────────────────────────────────\n\nexport function jsx(\n type: string | ComponentFn | symbol,\n props: Props & { children?: VNodeChild | VNodeChild[] },\n key?: string | number | null,\n): VNode {\n const { children, ...rest } = props\n const propsWithKey = (key != null ? { ...rest, key } : rest) as Props\n\n if (typeof type === 'function') {\n // Wrap Vue-style component for re-render support\n const wrapped = wrapCompatComponent(type)\n const componentProps = children !== undefined ? { ...propsWithKey, children } : propsWithKey\n return h(wrapped, componentProps)\n }\n\n // DOM element: convert Vue ref ({ value }) to callback ref for Pyreon's runtime-dom\n if (typeof type === 'string' && propsWithKey.ref != null) {\n const r = propsWithKey.ref\n if (\n typeof r === 'object' &&\n r !== null &&\n (r as Record<symbol, unknown>)[Symbol.for('__v_isRef')] === true\n ) {\n const vueRef = r as { value: unknown }\n propsWithKey.ref = (el: Element | null) => {\n vueRef.value = el\n }\n }\n }\n\n // DOM element or symbol (Fragment): children go in vnode.children\n const childArray = children === undefined ? [] : Array.isArray(children) ? children : [children]\n\n return h(type, propsWithKey, ...(childArray as VNodeChild[]))\n}\n\nexport const jsxs = jsx\nexport const jsxDEV = jsx\n"],"mappings":";;;;AA2CA,IAAI,cAAoC;AACxC,IAAI,aAAa;AAUjB,SAAgB,YAAY,KAA0B;AACpD,eAAc;AACd,cAAa;AACb,KAAI,iBAAiB,EAAE;AACvB,KAAI,uBAAuB,EAAE;;AAG/B,SAAgB,YAAkB;AAChC,eAAc;AACd,cAAa;;AAKf,SAAS,iBAAiB,SAA8B;AACtD,MAAK,MAAM,SAAS,SAAS;AAC3B,MAAI,MAAM,QAAS,OAAM,SAAS;EAClC,MAAM,UAAU,MAAM,IAAI;AAC1B,QAAM,UAAU,OAAO,YAAY,aAAa,UAAU;;;AAI9D,SAAS,gBAAgB,KAAoB,SAA8B;AACzE,KAAI,QAAQ,WAAW,EAAG;AAC1B,sBAAqB;AACnB,OAAK,MAAM,SAAS,SAAS;AAC3B,OAAI,IAAI,UAAW;AACnB,OAAI,MAAM,QAAS,OAAM,SAAS;GAClC,MAAM,UAAU,MAAM,IAAI;AAC1B,SAAM,UAAU,OAAO,YAAY,aAAa,UAAU;;GAE5D;;AAKJ,MAAM,gCAAgB,IAAI,SAAgC;AAE1D,SAAS,oBAAoB,cAAqC;CAChE,IAAI,UAAU,cAAc,IAAI,aAAa;AAC7C,KAAI,QAAS,QAAO;AAIpB,aAAY,UAAiB;EAC3B,MAAM,MAAqB;GACzB,OAAO,EAAE;GACT,wBAAwB;GAGxB,gBAAgB,EAAE;GAClB,sBAAsB,EAAE;GACxB,WAAW;GACX,kBAAkB,EAAE;GACrB;EAED,MAAM,UAAU,OAAO,EAAE;EACzB,IAAI,kBAAkB;AAEtB,MAAI,yBAAyB;AAC3B,OAAI,IAAI,aAAa,gBAAiB;AACtC,qBAAkB;AAClB,wBAAqB;AACnB,sBAAkB;AAClB,QAAI,CAAC,IAAI,UAAW,SAAQ,IAAI,QAAQ,MAAM,GAAG,EAAE;KACnD;;AAIJ,kBAAgB;AACd,OAAI,YAAY;AAChB,QAAK,MAAM,MAAM,IAAI,iBAAkB,KAAI;IAC3C;AAGF,eAAa;AACX,YAAS;AACT,eAAY,IAAI;GAGhB,MAAM,SAAS,mBAAoB,aAA6B,MAAM,CAAC;GACvE,MAAM,gBAAgB,IAAI;GAC1B,MAAM,UAAU,IAAI;AACpB,cAAW;AAEX,oBAAiB,cAAc;AAC/B,mBAAgB,KAAK,QAAQ;AAE7B,UAAO;;;AAIX,eAAc,IAAI,cAAc,QAAQ;AACxC,QAAO;;AAKT,SAAgB,IACd,MACA,OACA,KACO;CACP,MAAM,EAAE,UAAU,GAAG,SAAS;CAC9B,MAAM,eAAgB,OAAO,OAAO;EAAE,GAAG;EAAM;EAAK,GAAG;AAEvD,KAAI,OAAO,SAAS,WAIlB,QAAO,EAFS,oBAAoB,KAAK,EAClB,aAAa,SAAY;EAAE,GAAG;EAAc;EAAU,GAAG,aAC/C;AAInC,KAAI,OAAO,SAAS,YAAY,aAAa,OAAO,MAAM;EACxD,MAAM,IAAI,aAAa;AACvB,MACE,OAAO,MAAM,YACb,MAAM,QACL,EAA8B,OAAO,IAAI,YAAY,MAAM,MAC5D;GACA,MAAM,SAAS;AACf,gBAAa,OAAO,OAAuB;AACzC,WAAO,QAAQ;;;;AAQrB,QAAO,EAAE,MAAM,cAAc,GAFV,aAAa,SAAY,EAAE,GAAG,MAAM,QAAQ,SAAS,GAAG,WAAW,CAAC,SAAS,CAEnC;;AAG/D,MAAa,OAAO"}
|
package/lib/types/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/index.ts"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsx-runtime2.d.ts","names":[],"sources":["../../../src/jsx-runtime.ts"],"mappings":";;;iBAwJgB,GAAA,CACd,IAAA,WAAe,WAAA,WACf,KAAA,EAAO,KAAA;EAAU,QAAA,GAAW,UAAA,GAAa,UAAA;AAAA,GACzC,GAAA,4BACC,KAAA;AAAA,cAgCU,IAAA,SAAI,GAAA"}
|