@pyreon/vue-compat 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { ComponentFn, Fragment, Props, VNodeChild, h as pyreonH } from "@pyreon/core";
1
+ import { ComponentFn, ComponentFn as Component, Fragment, Props, VNodeChild, VNodeChild as VNode, h as pyreonH } from "@pyreon/core";
2
2
  import { batch } from "@pyreon/reactivity";
3
3
 
4
4
  //#region src/index.d.ts
@@ -31,6 +31,11 @@ declare function isRef(val: unknown): val is Ref;
31
31
  * Unwraps a ref: if it has `.value`, return `.value`; otherwise return as-is.
32
32
  */
33
33
  declare function unref<T>(r: T | Ref<T>): T;
34
+ /**
35
+ * Unwraps a ref, calls a getter, or returns the value as-is.
36
+ * Vue 3.3+ API for normalizing ref/getter/value inputs.
37
+ */
38
+ declare function toValue<T>(source: Ref<T> | (() => T) | T): T;
34
39
  interface ComputedRef<T = unknown> extends Ref<T> {
35
40
  readonly value: T;
36
41
  }
@@ -65,6 +70,11 @@ declare function shallowReactive<T extends object>(obj: T): T;
65
70
  * Inside a component: hook-indexed.
66
71
  */
67
72
  declare function readonly<T extends object>(obj: T): Readonly<T>;
73
+ /**
74
+ * Returns a shallow readonly proxy — only top-level properties throw on set.
75
+ * Nested objects are NOT wrapped in readonly (unlike `readonly()`).
76
+ */
77
+ declare function shallowReadonly<T extends object>(obj: T): Readonly<T>;
68
78
  /**
69
79
  * Returns the raw (unwrapped) object behind a reactive or readonly proxy.
70
80
  */
@@ -88,21 +98,25 @@ interface WatchOptions {
88
98
  immediate?: boolean;
89
99
  /** Ignored in Pyreon — dependencies are tracked automatically. */
90
100
  deep?: boolean;
101
+ /** Accepted for compatibility but not meaningfully differentiated in Pyreon. */
102
+ flush?: 'pre' | 'post' | 'sync';
91
103
  }
92
104
  type WatchSource<T> = Ref<T> | (() => T);
93
105
  /**
94
- * Watches a reactive source and calls `cb` when it changes.
106
+ * Watches a reactive source (or array of sources) and calls `cb` when it changes.
95
107
  *
96
108
  * Inside a component: hook-indexed, created once. Disposed on unmount.
97
109
  */
98
- declare function watch<T>(source: WatchSource<T>, cb: (newValue: T, oldValue: T | undefined) => void, options?: WatchOptions): () => void;
110
+ declare function watch<T>(source: WatchSource<T>, cb: (newValue: T, oldValue: T | undefined, onCleanup: (fn: () => void) => void) => void, options?: WatchOptions): () => void;
111
+ declare function watch<T extends readonly WatchSource<any>[]>(sources: [...T], cb: (newValues: { [K in keyof T]: T[K] extends WatchSource<infer V> ? V : never }, oldValues: { [K in keyof T]: T[K] extends WatchSource<infer V> ? V | undefined : never }, onCleanup: (fn: () => void) => void) => void, options?: WatchOptions): () => void;
99
112
  /**
100
113
  * Runs the given function reactively — re-executes whenever its tracked
101
- * dependencies change.
114
+ * dependencies change. Passes an `onCleanup` registration function to the
115
+ * callback, matching Vue 3's `watchEffect((onCleanup) => { ... })` API.
102
116
  *
103
117
  * Inside a component: hook-indexed, created once. Disposed on unmount.
104
118
  */
105
- declare function watchEffect(fn: () => void): () => void;
119
+ declare function watchEffect(fn: (onCleanup: (fn: () => void) => void) => void): () => void;
106
120
  /**
107
121
  * Registers a callback to run after the component is mounted.
108
122
  * Hook-indexed: only registered on first render.
@@ -140,27 +154,173 @@ declare function nextTick(): Promise<void>;
140
154
  declare function provide<T>(key: string | symbol, value: T): void;
141
155
  /**
142
156
  * Injects a value provided by an ancestor component.
157
+ * Supports Vue 3's factory default pattern: `inject(key, () => expensiveDefault, true)`.
143
158
  */
144
- declare function inject<T>(key: string | symbol, defaultValue?: T): T | undefined;
159
+ declare function inject<T>(key: string | symbol, defaultValue?: T | (() => T), treatDefaultAsFactory?: boolean): T | undefined;
145
160
  interface ComponentOptions<P extends Props = Props> {
146
161
  /** The setup function — called once during component initialization. */
147
- setup: (props: P) => (() => VNodeChild) | VNodeChild;
162
+ setup: (props: P, ctx?: SetupContext) => (() => VNodeChild) | VNodeChild;
148
163
  /** Optional name for debugging. */
149
164
  name?: string;
165
+ /** Prop definitions (not validated at runtime, used for type documentation). */
166
+ props?: Record<string, unknown>;
150
167
  }
151
168
  /**
152
169
  * Defines a component using Vue 3 Composition API style.
153
170
  * Only supports the `setup()` function — Options API is not supported.
154
171
  */
155
172
  declare function defineComponent<P extends Props = Props>(options: ComponentOptions<P> | ((props: P) => VNodeChild)): ComponentFn<P>;
173
+ /**
174
+ * Defines an async component that lazily loads on first use.
175
+ * Supports both a bare loader function and an options object with
176
+ * loadingComponent, errorComponent, delay, and timeout.
177
+ *
178
+ * Returns a ComponentFn with a `__loading` property for Suspense integration.
179
+ */
180
+ declare function defineAsyncComponent<P extends Props = Props>(loader: (() => Promise<{
181
+ default: ComponentFn<P>;
182
+ }>) | {
183
+ loader: () => Promise<{
184
+ default: ComponentFn<P>;
185
+ }>;
186
+ loadingComponent?: ComponentFn;
187
+ errorComponent?: ComponentFn;
188
+ delay?: number;
189
+ timeout?: number;
190
+ }): ComponentFn<P> & {
191
+ __loading: () => boolean;
192
+ };
156
193
  interface App {
157
194
  /** Mount the application into a DOM element. Returns an unmount function. */
158
195
  mount(el: string | Element): () => void;
196
+ /** Install a plugin. */
197
+ use(plugin: {
198
+ install: (app: App) => void;
199
+ }): App;
200
+ /** Provide a value to the entire app tree. */
201
+ provide<T>(key: string | symbol, value: T): App;
159
202
  }
160
203
  /**
161
204
  * Creates a Pyreon application instance — Vue 3 `createApp()` compatible.
162
205
  */
163
206
  declare function createApp(component: ComponentFn, props?: Props): App;
207
+ /**
208
+ * Returns `true` if the value was created by `reactive()`.
209
+ */
210
+ declare function isReactive(value: unknown): boolean;
211
+ /**
212
+ * Returns `true` if the value was created by `readonly()`.
213
+ */
214
+ declare function isReadonly(value: unknown): boolean;
215
+ /**
216
+ * Returns `true` if the value is either reactive or readonly.
217
+ */
218
+ declare function isProxy(value: unknown): boolean;
219
+ /**
220
+ * Marks an object so that `reactive()` will return it as-is (not wrapped).
221
+ */
222
+ declare function markRaw<T extends object>(obj: T): T;
223
+ interface EffectScopeCompat {
224
+ /** Run a function within this scope. Returns undefined if scope is stopped. */
225
+ run<T>(fn: () => T): T | undefined;
226
+ /** Stop the scope and dispose all collected effects/cleanups. */
227
+ stop(): void;
228
+ /** Whether the scope is still active. */
229
+ active: boolean;
230
+ }
231
+ /**
232
+ * Creates an effect scope that collects reactive effects for grouped disposal.
233
+ *
234
+ * @param detached - If true, the scope is not collected by a parent scope.
235
+ */
236
+ declare function effectScope(detached?: boolean): EffectScopeCompat;
237
+ /**
238
+ * Returns the current active effect scope, or undefined if none.
239
+ */
240
+ declare function getCurrentScope(): EffectScopeCompat | undefined;
241
+ /**
242
+ * Registers a cleanup function on the current effect scope.
243
+ */
244
+ declare function onScopeDispose(fn: () => void): void;
245
+ /**
246
+ * Registers an error capture handler.
247
+ * No direct equivalent in Pyreon — stored but not actively used.
248
+ */
249
+ declare function onErrorCaptured(fn: (err: Error) => boolean | void): void;
250
+ /**
251
+ * Dev-only lifecycle hook — no-op in Pyreon.
252
+ */
253
+ declare function onRenderTracked(_fn: (event: {
254
+ key: string;
255
+ type: string;
256
+ }) => void): void;
257
+ /**
258
+ * Dev-only lifecycle hook — no-op in Pyreon.
259
+ */
260
+ declare function onRenderTriggered(_fn: (event: {
261
+ key: string;
262
+ type: string;
263
+ }) => void): void;
264
+ /**
265
+ * Teleport — renders children into a different DOM element.
266
+ * Maps to Pyreon's Portal.
267
+ */
268
+ declare function Teleport(props: {
269
+ to: string | Element;
270
+ children?: VNodeChild;
271
+ }): VNodeChild;
272
+ /**
273
+ * KeepAlive — not supported in Pyreon. Renders children as-is.
274
+ */
275
+ declare function KeepAlive(props: {
276
+ children?: VNodeChild;
277
+ }): VNodeChild;
278
+ /**
279
+ * Runs a watchEffect that flushes after DOM updates.
280
+ * In Pyreon, same as `watchEffect()`.
281
+ */
282
+ declare function watchPostEffect(fn: (onCleanup: (fn: () => void) => void) => void): () => void;
283
+ /**
284
+ * Runs a watchEffect that flushes synchronously.
285
+ * In Pyreon, same as `watchEffect()`.
286
+ */
287
+ declare function watchSyncEffect(fn: (onCleanup: (fn: () => void) => void) => void): () => void;
288
+ /**
289
+ * Creates a customized ref with explicit control over dependency tracking
290
+ * and update triggering.
291
+ */
292
+ declare function customRef<T>(factory: (track: () => void, trigger: () => void) => {
293
+ get: () => T;
294
+ set: (v: T) => void;
295
+ }): Ref<T>;
296
+ /**
297
+ * Compatibility version string — indicates Vue 3 API compatibility.
298
+ */
299
+ declare const version = "3.5.0-pyreon";
300
+ /** Vue-compatible PropType — a callable that returns T. */
301
+ type PropType<T> = {
302
+ (): T;
303
+ };
304
+ /** Extract prop types from a component's props definition. */
305
+ type ExtractPropTypes<T> = { [K in keyof T]: T[K] extends PropType<infer V> ? V : T[K] };
306
+ /** Vue-compatible emits options type. */
307
+ type EmitsOptions = Record<string, (...args: unknown[]) => void>;
308
+ /** Vue-compatible setup context. */
309
+ type SetupContext = {
310
+ emit: (event: string, ...args: unknown[]) => void;
311
+ slots: Record<string, (() => VNodeChild) | undefined>;
312
+ attrs: Record<string, unknown>;
313
+ };
314
+ /** Vue-compatible plugin interface. */
315
+ type Plugin = {
316
+ install: (app: App) => void;
317
+ };
318
+ /** Vue-compatible directive type (stub). */
319
+ type Directive = Record<string, unknown>;
320
+ /** Vue-compatible injection key with type branding. */
321
+ type InjectionKey<T> = symbol & {
322
+ __type: T;
323
+ };
164
324
  //#endregion
165
- export { ComputedRef, Fragment, Ref, WatchOptions, WritableComputedRef, batch, computed, createApp, defineComponent, pyreonH as h, inject, isRef, nextTick, onBeforeMount, onBeforeUnmount, onMounted, onUnmounted, onUpdated, provide, reactive, readonly, ref, shallowReactive, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, watch, watchEffect };
325
+ export { type Component, ComputedRef, Directive, EffectScopeCompat, EmitsOptions, ExtractPropTypes, Fragment, InjectionKey, KeepAlive, Plugin, PropType, Ref, SetupContext, Teleport, type VNode, WatchOptions, WritableComputedRef, batch, computed, createApp, customRef, defineAsyncComponent, defineComponent, effectScope, getCurrentScope, pyreonH as h, inject, isProxy, isReactive, isReadonly, isRef, markRaw, nextTick, onBeforeMount, onBeforeUnmount, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onUnmounted, onUpdated, provide, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, toValue, triggerRef, unref, version, watch, watchEffect, watchPostEffect, watchSyncEffect };
166
326
  //# sourceMappingURL=index2.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/vue-compat",
3
- "version": "0.13.1",
3
+ "version": "0.15.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.13.1",
56
- "@pyreon/reactivity": "^0.13.1",
57
- "@pyreon/runtime-dom": "^0.13.1"
57
+ "@pyreon/core": "^0.15.0",
58
+ "@pyreon/reactivity": "^0.15.0",
59
+ "@pyreon/runtime-dom": "^0.15.0"
58
60
  },
59
61
  "devDependencies": {
60
62
  "@happy-dom/global-registrator": "^20.8.9",
63
+ "@pyreon/test-utils": "^0.13.2",
64
+ "@vitest/browser-playwright": "^4.1.4",
61
65
  "happy-dom": "^20.8.3"
62
66
  }
63
67
  }