@pyreon/solid-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.
- 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 +459 -20
- package/lib/jsx-runtime.js +5 -1
- package/lib/types/index.d.ts +194 -6
- package/package.json +8 -4
- package/src/env.d.ts +6 -0
- package/src/index.ts +738 -25
- package/src/jsx-runtime.ts +14 -0
- package/src/solid-compat.browser.test.ts +32 -0
- package/src/tests/native-marker-bypass.test.tsx +70 -0
- package/src/tests/new-apis.test.ts +1539 -0
- package/src/tests/solid-compat.test.ts +366 -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/lib/types/index.d.ts
CHANGED
|
@@ -1,19 +1,43 @@
|
|
|
1
|
-
import { ComponentFn, ErrorBoundary, For, LazyComponent, Match, Props, Show, Suspense, Switch, VNodeChild
|
|
1
|
+
import { ComponentFn, Context, ErrorBoundary, For, LazyComponent, Match, Props, Show, Suspense, Switch, VNodeChild } from "@pyreon/core";
|
|
2
2
|
import { EffectScope, batch as pyreonBatch, runUntracked } from "@pyreon/reactivity";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
|
+
/** Solid-compatible read accessor type */
|
|
6
|
+
type Accessor<T> = () => T;
|
|
7
|
+
/** Solid-compatible setter type */
|
|
8
|
+
type Setter<T> = (v: T | ((prev: T) => T)) => void;
|
|
9
|
+
/** Solid-compatible signal tuple type */
|
|
10
|
+
type Signal<T> = [Accessor<T>, Setter<T>];
|
|
11
|
+
/** Solid-compatible owner type */
|
|
12
|
+
type Owner = EffectScope;
|
|
13
|
+
/** Solid-compatible component type */
|
|
14
|
+
type Component<P = object> = (props: P) => VNodeChild;
|
|
15
|
+
/** Solid-compatible parent component type (includes children) */
|
|
16
|
+
type ParentComponent<P = object> = (props: P & {
|
|
17
|
+
children?: VNodeChild;
|
|
18
|
+
}) => VNodeChild;
|
|
19
|
+
/** Solid-compatible flow component type */
|
|
20
|
+
type FlowComponent<P = object> = Component<P>;
|
|
21
|
+
/** Solid-compatible void component type (no children) */
|
|
22
|
+
type VoidComponent<P = object> = Component<P>;
|
|
5
23
|
type SignalGetter<T> = () => T;
|
|
6
24
|
type SignalSetter<T> = (v: T | ((prev: T) => T)) => void;
|
|
7
|
-
|
|
25
|
+
interface CreateSignalOptions<T> {
|
|
26
|
+
equals?: false | ((prev: T, next: T) => boolean);
|
|
27
|
+
}
|
|
28
|
+
declare function createSignal<T>(initialValue: T, options?: CreateSignalOptions<T>): [SignalGetter<T>, SignalSetter<T>];
|
|
8
29
|
/**
|
|
9
30
|
* Solid-compatible `createEffect` — creates a reactive side effect.
|
|
10
31
|
*
|
|
32
|
+
* Supports the `(prev) => next` signature with an optional initial value,
|
|
33
|
+
* matching Solid's `createEffect<T>(fn: (prev: T) => T, initialValue: T)`.
|
|
34
|
+
*
|
|
11
35
|
* In component context: hook-indexed, only created on first render. The effect
|
|
12
36
|
* uses Pyreon's native tracking so signal reads are automatically tracked.
|
|
13
37
|
* A re-entrance guard prevents infinite loops from signal writes inside
|
|
14
38
|
* the effect.
|
|
15
39
|
*/
|
|
16
|
-
declare function createEffect(fn: () => void): void;
|
|
40
|
+
declare function createEffect<T>(fn: ((prev?: T) => T) | (() => void), initialValue?: T): void;
|
|
17
41
|
/**
|
|
18
42
|
* Solid-compatible `createRenderEffect` — same as createEffect.
|
|
19
43
|
* In Solid, this runs during the render phase; here it runs as a Pyreon effect.
|
|
@@ -22,14 +46,19 @@ declare function createRenderEffect(fn: () => void): void;
|
|
|
22
46
|
/**
|
|
23
47
|
* Solid-compatible `createMemo` — derives a value from reactive sources.
|
|
24
48
|
*
|
|
49
|
+
* Supports the `(prev) => next` signature with an optional initial value,
|
|
50
|
+
* matching Solid's `createMemo<T>(fn: (prev: T) => T, initialValue: T)`.
|
|
51
|
+
*
|
|
25
52
|
* In component context: hook-indexed, only created on first render.
|
|
26
53
|
* Uses Pyreon's native computed for auto-tracking.
|
|
27
54
|
*/
|
|
28
|
-
declare function createMemo<T>(fn: () => T): () => T;
|
|
55
|
+
declare function createMemo<T>(fn: ((prev?: T) => T) | (() => T), initialValue?: T): () => T;
|
|
29
56
|
declare function createRoot<T>(fn: (dispose: () => void) => T): T;
|
|
30
57
|
type AccessorArray = readonly (() => unknown)[];
|
|
31
58
|
type OnEffectFunction<D, V> = (input: D, prevInput: D | undefined, prev: V | undefined) => V;
|
|
32
|
-
declare function on<S extends (() => unknown) | AccessorArray, V>(deps: S, fn: OnEffectFunction<S extends (() => infer R) ? R : S extends readonly (() => infer R)[] ? R[] : never, V
|
|
59
|
+
declare function on<S extends (() => unknown) | AccessorArray, V>(deps: S, fn: OnEffectFunction<S extends (() => infer R) ? R : S extends readonly (() => infer R)[] ? R[] : never, V>, options?: {
|
|
60
|
+
defer?: boolean;
|
|
61
|
+
}): () => V | undefined;
|
|
33
62
|
/**
|
|
34
63
|
* Solid-compatible `onMount` — runs once after the component's first render.
|
|
35
64
|
*/
|
|
@@ -52,8 +81,167 @@ declare function lazy<P extends Props>(loader: () => Promise<{
|
|
|
52
81
|
default: ComponentFn<P>;
|
|
53
82
|
}>;
|
|
54
83
|
};
|
|
84
|
+
declare const SOLID_CTX: unique symbol;
|
|
85
|
+
/**
|
|
86
|
+
* Solid-compatible context with a Provider component that uses Pyreon's
|
|
87
|
+
* native tree-scoped context stack for proper nesting (inner Provider
|
|
88
|
+
* overrides outer for its subtree).
|
|
89
|
+
*/
|
|
90
|
+
interface SolidContext<T> {
|
|
91
|
+
readonly [SOLID_CTX_BRAND]: true;
|
|
92
|
+
readonly id: symbol;
|
|
93
|
+
readonly defaultValue: T | undefined;
|
|
94
|
+
Provider: (props: Record<string, unknown>) => unknown;
|
|
95
|
+
}
|
|
96
|
+
declare const SOLID_CTX_BRAND: typeof SOLID_CTX;
|
|
97
|
+
/**
|
|
98
|
+
* Solid-compatible `createContext` — creates a context with a `.Provider`
|
|
99
|
+
* component. Uses Pyreon's native context stack for tree-scoped nesting.
|
|
100
|
+
*/
|
|
101
|
+
declare function createContext<T>(defaultValue?: T): SolidContext<T>;
|
|
102
|
+
/**
|
|
103
|
+
* Solid-compatible `useContext` — reads the nearest provided value for a context.
|
|
104
|
+
* Works with both compat contexts (from this module's `createContext`) and
|
|
105
|
+
* Pyreon native contexts (from `@pyreon/core`).
|
|
106
|
+
*/
|
|
107
|
+
declare function useContext<T>(context: SolidContext<T> | Context<T>): T;
|
|
55
108
|
declare function getOwner(): EffectScope | null;
|
|
56
109
|
declare function runWithOwner<T>(owner: EffectScope | null, fn: () => T): T;
|
|
110
|
+
/**
|
|
111
|
+
* Solid-compatible resource — async data fetching with reactive source tracking.
|
|
112
|
+
* Returns `[resource, { mutate, refetch }]` where `resource()` is the data accessor
|
|
113
|
+
* with `.loading`, `.error`, and `.latest` reactive properties.
|
|
114
|
+
*
|
|
115
|
+
* When the resource is loading and read inside a Suspense boundary, the accessor
|
|
116
|
+
* throws the fetch promise so Suspense can catch it. It also integrates with
|
|
117
|
+
* Pyreon's `__loading` protocol so `<Suspense>` can detect it.
|
|
118
|
+
*/
|
|
119
|
+
interface Resource<T> {
|
|
120
|
+
(): T | undefined;
|
|
121
|
+
loading: boolean;
|
|
122
|
+
error: Error | undefined;
|
|
123
|
+
latest: T | undefined;
|
|
124
|
+
}
|
|
125
|
+
type ResourceReturn<T> = [Resource<T>, {
|
|
126
|
+
mutate: (v: T | ((prev: T | undefined) => T)) => void;
|
|
127
|
+
refetch: () => void;
|
|
128
|
+
}];
|
|
129
|
+
declare function createResource<T>(fetcher: (info: {
|
|
130
|
+
value: T | undefined;
|
|
131
|
+
}) => Promise<T> | T, options?: {
|
|
132
|
+
initialValue?: T;
|
|
133
|
+
}): ResourceReturn<T>;
|
|
134
|
+
declare function createResource<T, S = true>(source: (() => S) | true, fetcher: (source: S, info: {
|
|
135
|
+
value: T | undefined;
|
|
136
|
+
}) => Promise<T> | T, options?: {
|
|
137
|
+
initialValue?: T;
|
|
138
|
+
}): ResourceReturn<T>;
|
|
139
|
+
/**
|
|
140
|
+
* Solid-compatible `createStore` — creates a deeply reactive proxy-based store.
|
|
141
|
+
*
|
|
142
|
+
* Returns `[store, setStore]` where:
|
|
143
|
+
* - `store` is a recursive proxy that lazily creates per-path signals for fine-grained tracking
|
|
144
|
+
* - `setStore` supports Solid's path-based setter API:
|
|
145
|
+
* - `setStore('key', value)` — set a top-level key
|
|
146
|
+
* - `setStore('nested', 'key', value)` — set a nested path
|
|
147
|
+
* - `setStore('key', prev => next)` — functional update at a path
|
|
148
|
+
* - `setStore('todos', 0, 'done', true)` — numeric index into arrays
|
|
149
|
+
* - `setStore('todos', t => t.done, 'text', 'x')` — filter predicate on arrays
|
|
150
|
+
* - `setStore(fn)` — mutator function (receives a draft clone)
|
|
151
|
+
*/
|
|
152
|
+
type SetStoreFunction<_T> = {
|
|
153
|
+
(...args: unknown[]): void;
|
|
154
|
+
};
|
|
155
|
+
declare function createStore<T extends object>(initialValue: T): [T, SetStoreFunction<T>];
|
|
156
|
+
/**
|
|
157
|
+
* Solid-compatible `reconcile` — replaces the entire store state with the given value.
|
|
158
|
+
* Used with setStore: `setStore(reconcile(newData))`
|
|
159
|
+
*/
|
|
160
|
+
declare function reconcile<T extends object>(value: T): (state: T) => T;
|
|
161
|
+
/**
|
|
162
|
+
* Solid-compatible `unwrap` — returns a deep clone of the store's raw data,
|
|
163
|
+
* stripping the reactive proxy.
|
|
164
|
+
*/
|
|
165
|
+
declare function unwrap<T>(value: T): T;
|
|
166
|
+
/**
|
|
167
|
+
* Solid-compatible `produce` — creates an Immer-like updater function for stores.
|
|
168
|
+
* Returns a function that clones the state, applies mutations, and returns the result.
|
|
169
|
+
*/
|
|
170
|
+
declare function produce<T extends object>(fn: (state: T) => void): (state: T) => T;
|
|
171
|
+
/**
|
|
172
|
+
* Solid-compatible `startTransition` — runs a function as a transition.
|
|
173
|
+
* In Pyreon, this is a no-op wrapper that calls the function synchronously.
|
|
174
|
+
*/
|
|
175
|
+
declare function startTransition(fn: () => void): void;
|
|
176
|
+
/**
|
|
177
|
+
* Solid-compatible `useTransition` — returns `[isPending, startTransition]`.
|
|
178
|
+
* In Pyreon, transitions are not deferred — isPending is always false.
|
|
179
|
+
*/
|
|
180
|
+
declare function useTransition(): [() => boolean, (fn: () => void) => void];
|
|
181
|
+
interface Observer<T> {
|
|
182
|
+
next: (v: T) => void;
|
|
183
|
+
}
|
|
184
|
+
interface Subscription {
|
|
185
|
+
unsubscribe: () => void;
|
|
186
|
+
}
|
|
187
|
+
interface Observable<T> {
|
|
188
|
+
subscribe: (observer: Observer<T>) => Subscription;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Solid-compatible `observable` — converts a signal accessor to an observable.
|
|
192
|
+
* Returns an object with a `subscribe` method that tracks signal changes.
|
|
193
|
+
*/
|
|
194
|
+
declare function observable<T>(input: () => T): Observable<T>;
|
|
195
|
+
/**
|
|
196
|
+
* Solid-compatible `from` — converts an observable or producer into a signal accessor.
|
|
197
|
+
* Accepts either a producer function `(setter) => cleanup` or an observable with `.subscribe()`.
|
|
198
|
+
*/
|
|
199
|
+
declare function from<T>(producer: ((setter: (v: T) => void) => () => void) | Observable<T>): () => T | undefined;
|
|
200
|
+
/**
|
|
201
|
+
* Solid-compatible `mapArray` — maps a reactive list by item identity.
|
|
202
|
+
* Each item is a static value, while the index is a reactive accessor.
|
|
203
|
+
*/
|
|
204
|
+
declare function mapArray<T, U>(list: () => readonly T[], mapFn: (item: T, index: () => number) => U): () => U[];
|
|
205
|
+
/**
|
|
206
|
+
* Solid-compatible `indexArray` — maps a reactive list by index position.
|
|
207
|
+
* Each item is a reactive accessor, while the index is a static number.
|
|
208
|
+
*/
|
|
209
|
+
declare function indexArray<T, U>(list: () => readonly T[], mapFn: (item: () => T, index: number) => U): () => U[];
|
|
210
|
+
/**
|
|
211
|
+
* Solid-compatible `Index` — like `For` but keyed by index.
|
|
212
|
+
* Items are reactive accessors, indices are static numbers.
|
|
213
|
+
*
|
|
214
|
+
* In Solid, `<Index>` keeps DOM nodes stable per index position.
|
|
215
|
+
* Here we use a computed that maps items to `(item: () => T, index: number)`.
|
|
216
|
+
*/
|
|
217
|
+
declare function Index<T>(props: {
|
|
218
|
+
each: readonly T[] | (() => readonly T[]);
|
|
219
|
+
children: (item: () => T, index: number) => VNodeChild;
|
|
220
|
+
}): VNodeChild;
|
|
221
|
+
/**
|
|
222
|
+
* Solid-compatible `createUniqueId` — returns a unique string identifier.
|
|
223
|
+
*/
|
|
224
|
+
declare function createUniqueId(): string;
|
|
225
|
+
/**
|
|
226
|
+
* Solid-compatible `DEV` — an object in dev mode, `undefined` in production.
|
|
227
|
+
* Used for conditional dev-only code: `if (DEV) { ... }`
|
|
228
|
+
*/
|
|
229
|
+
declare const DEV: {} | undefined;
|
|
230
|
+
/**
|
|
231
|
+
* Solid-compatible `catchError` — wraps a function and catches synchronous errors.
|
|
232
|
+
*/
|
|
233
|
+
declare function catchError<T>(tryFn: () => T, onError: (err: Error) => void): T | undefined;
|
|
234
|
+
/**
|
|
235
|
+
* Solid-compatible `createDeferred` — creates a memo that updates on next idle frame.
|
|
236
|
+
* In Pyreon there is no concurrent scheduling, so this behaves the same as `createMemo`.
|
|
237
|
+
*/
|
|
238
|
+
declare function createDeferred<T>(fn: () => T): () => T;
|
|
239
|
+
/**
|
|
240
|
+
* Solid-compatible `createReaction` — manual tracking primitive.
|
|
241
|
+
* Returns a function that accepts a tracking function. When any tracked
|
|
242
|
+
* dependency changes, `onInvalidate` fires (but only after the first run).
|
|
243
|
+
*/
|
|
244
|
+
declare function createReaction(onInvalidate: () => void): (tracking: () => void) => void;
|
|
57
245
|
//#endregion
|
|
58
|
-
export { ErrorBoundary, For, Match, Show, SignalGetter, SignalSetter, Suspense, Switch, pyreonBatch as batch, children, createEffect as createComputed, createEffect,
|
|
246
|
+
export { Accessor, Component, CreateSignalOptions, DEV, ErrorBoundary, FlowComponent, For, Index, Match, Owner, ParentComponent, Resource, ResourceReturn, SetStoreFunction, Setter, Show, Signal, SignalGetter, SignalSetter, SolidContext, Suspense, Switch, VoidComponent, pyreonBatch as batch, catchError, children, createEffect as createComputed, createEffect, createContext, createDeferred, createMemo, createReaction, createRenderEffect, createResource, createRoot, createSelector, createSignal, createStore, createUniqueId, from, getOwner, indexArray, lazy, mapArray, mergeProps, observable, on, onCleanup, onMount, produce, reconcile, runWithOwner, splitProps, startTransition, runUntracked as untrack, unwrap, useContext, useTransition };
|
|
59
247
|
//# sourceMappingURL=index2.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/solid-compat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "SolidJS-compatible API shim for Pyreon — write Solid-style code that runs on Pyreon's reactive engine",
|
|
5
5
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/solid-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.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
|
}
|
package/src/env.d.ts
ADDED