rask-ui 0.1.1 → 0.2.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/dist/component.d.ts +17 -0
- package/dist/component.d.ts.map +1 -1
- package/dist/createAsync.d.ts +23 -0
- package/dist/createAsync.d.ts.map +1 -1
- package/dist/createAsync.js +23 -0
- package/dist/createContext.d.ts +26 -2
- package/dist/createContext.d.ts.map +1 -1
- package/dist/createContext.js +31 -5
- package/dist/createContext.test.d.ts +2 -0
- package/dist/createContext.test.d.ts.map +1 -0
- package/dist/createContext.test.js +136 -0
- package/dist/createMutation.d.ts +23 -0
- package/dist/createMutation.d.ts.map +1 -1
- package/dist/createMutation.js +23 -0
- package/dist/createQuery.d.ts +23 -0
- package/dist/createQuery.d.ts.map +1 -1
- package/dist/createQuery.js +23 -0
- package/dist/createRef.test.d.ts +2 -0
- package/dist/createRef.test.d.ts.map +1 -0
- package/dist/createRef.test.js +80 -0
- package/dist/createState.d.ts +24 -0
- package/dist/createState.d.ts.map +1 -1
- package/dist/createState.js +24 -0
- package/dist/createView.d.ts +54 -0
- package/dist/createView.d.ts.map +1 -0
- package/dist/createView.js +68 -0
- package/dist/createView.test.d.ts +2 -0
- package/dist/createView.test.d.ts.map +1 -0
- package/dist/createView.test.js +203 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +4 -5
- package/dist/error.test.d.ts +2 -0
- package/dist/error.test.d.ts.map +1 -0
- package/dist/error.test.js +144 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/integration.test.d.ts +2 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +155 -0
- package/dist/jsx-dev-runtime.d.ts +3 -3
- package/dist/jsx-dev-runtime.d.ts.map +1 -1
- package/dist/jsx-dev-runtime.js +2 -2
- package/dist/jsx-runtime.d.ts +1 -4
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx-runtime.js +3 -14
- package/dist/observation.d.ts +1 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +5 -0
- package/dist/test-setup.d.ts +3 -3
- package/dist/test-setup.d.ts.map +1 -1
- package/dist/test-setup.js +7 -8
- package/dist/tests/class.test.d.ts +2 -0
- package/dist/tests/class.test.d.ts.map +1 -0
- package/dist/tests/class.test.js +143 -0
- package/dist/tests/complex-rendering.test.d.ts +2 -0
- package/dist/tests/complex-rendering.test.d.ts.map +1 -0
- package/dist/tests/complex-rendering.test.js +400 -0
- package/dist/tests/component.cleanup.test.d.ts +2 -0
- package/dist/tests/component.cleanup.test.d.ts.map +1 -0
- package/dist/tests/component.cleanup.test.js +325 -0
- package/dist/tests/component.counter.test.d.ts +2 -0
- package/dist/tests/component.counter.test.d.ts.map +1 -0
- package/dist/tests/component.counter.test.js +124 -0
- package/dist/tests/component.interaction.test.d.ts +2 -0
- package/dist/tests/component.interaction.test.d.ts.map +1 -0
- package/dist/tests/component.interaction.test.js +73 -0
- package/dist/tests/component.props.test.d.ts +2 -0
- package/dist/tests/component.props.test.d.ts.map +1 -0
- package/dist/tests/component.props.test.js +88 -0
- package/dist/tests/component.return-types.test.d.ts +2 -0
- package/dist/tests/component.return-types.test.d.ts.map +1 -0
- package/dist/tests/component.return-types.test.js +357 -0
- package/dist/tests/component.state.test.d.ts +2 -0
- package/dist/tests/component.state.test.d.ts.map +1 -0
- package/dist/tests/component.state.test.js +129 -0
- package/dist/tests/component.test.d.ts +2 -0
- package/dist/tests/component.test.d.ts.map +1 -0
- package/dist/tests/component.test.js +63 -0
- package/dist/tests/createAsync.test.d.ts +2 -0
- package/dist/tests/createAsync.test.d.ts.map +1 -0
- package/dist/tests/createAsync.test.js +110 -0
- package/dist/tests/createContext.test.d.ts +2 -0
- package/dist/tests/createContext.test.d.ts.map +1 -0
- package/dist/tests/createContext.test.js +141 -0
- package/dist/tests/createMutation.test.d.ts +2 -0
- package/dist/tests/createMutation.test.d.ts.map +1 -0
- package/dist/tests/createMutation.test.js +168 -0
- package/dist/tests/createQuery.test.d.ts +2 -0
- package/dist/tests/createQuery.test.d.ts.map +1 -0
- package/dist/tests/createQuery.test.js +156 -0
- package/dist/tests/createRef.test.d.ts +2 -0
- package/dist/tests/createRef.test.d.ts.map +1 -0
- package/dist/tests/createRef.test.js +84 -0
- package/dist/tests/createState.test.d.ts +2 -0
- package/dist/tests/createState.test.d.ts.map +1 -0
- package/dist/tests/createState.test.js +111 -0
- package/dist/tests/createView.test.d.ts +2 -0
- package/dist/tests/createView.test.d.ts.map +1 -0
- package/dist/tests/createView.test.js +203 -0
- package/dist/tests/edge-cases.test.d.ts +2 -0
- package/dist/tests/edge-cases.test.d.ts.map +1 -0
- package/dist/tests/edge-cases.test.js +637 -0
- package/dist/tests/error-no-boundary.test.d.ts +2 -0
- package/dist/tests/error-no-boundary.test.d.ts.map +1 -0
- package/dist/tests/error-no-boundary.test.js +174 -0
- package/dist/tests/error.test.d.ts +2 -0
- package/dist/tests/error.test.d.ts.map +1 -0
- package/dist/tests/error.test.js +199 -0
- package/dist/tests/fragment.test.d.ts +2 -0
- package/dist/tests/fragment.test.d.ts.map +1 -0
- package/dist/tests/fragment.test.js +618 -0
- package/dist/tests/integration.test.d.ts +2 -0
- package/dist/tests/integration.test.d.ts.map +1 -0
- package/dist/tests/integration.test.js +192 -0
- package/dist/tests/keys.test.d.ts +2 -0
- package/dist/tests/keys.test.d.ts.map +1 -0
- package/dist/tests/keys.test.js +293 -0
- package/dist/tests/mount.test.d.ts +2 -0
- package/dist/tests/mount.test.d.ts.map +1 -0
- package/dist/tests/mount.test.js +91 -0
- package/dist/tests/observation.test.d.ts +2 -0
- package/dist/tests/observation.test.d.ts.map +1 -0
- package/dist/tests/observation.test.js +150 -0
- package/dist/tests/patch.test.d.ts +2 -0
- package/dist/tests/patch.test.d.ts.map +1 -0
- package/dist/tests/patch.test.js +498 -0
- package/dist/tests/patchChildren.test.d.ts +2 -0
- package/dist/tests/patchChildren.test.d.ts.map +1 -0
- package/dist/tests/patchChildren.test.js +387 -0
- package/dist/tests/primitives.test.d.ts +2 -0
- package/dist/tests/primitives.test.d.ts.map +1 -0
- package/dist/tests/primitives.test.js +132 -0
- package/dist/vdom/AbstractVNode.d.ts +22 -0
- package/dist/vdom/AbstractVNode.d.ts.map +1 -0
- package/dist/vdom/AbstractVNode.js +106 -0
- package/dist/vdom/ComponentVNode.d.ts +48 -0
- package/dist/vdom/ComponentVNode.d.ts.map +1 -0
- package/dist/vdom/ComponentVNode.js +209 -0
- package/dist/vdom/ElementVNode.d.ts +24 -0
- package/dist/vdom/ElementVNode.d.ts.map +1 -0
- package/dist/vdom/ElementVNode.js +126 -0
- package/dist/vdom/FragmentVNode.d.ts +13 -0
- package/dist/vdom/FragmentVNode.d.ts.map +1 -0
- package/dist/vdom/FragmentVNode.js +34 -0
- package/dist/vdom/RootVNode.d.ts +22 -0
- package/dist/vdom/RootVNode.d.ts.map +1 -0
- package/dist/vdom/RootVNode.js +55 -0
- package/dist/vdom/TextVNode.d.ts +11 -0
- package/dist/vdom/TextVNode.d.ts.map +1 -0
- package/dist/vdom/TextVNode.js +32 -0
- package/dist/vdom/class.test.d.ts +2 -0
- package/dist/vdom/class.test.d.ts.map +1 -0
- package/dist/vdom/class.test.js +143 -0
- package/dist/vdom/complex-rendering.test.d.ts +2 -0
- package/dist/vdom/complex-rendering.test.d.ts.map +1 -0
- package/dist/vdom/complex-rendering.test.js +400 -0
- package/dist/vdom/component.cleanup.test.d.ts +2 -0
- package/dist/vdom/component.cleanup.test.d.ts.map +1 -0
- package/dist/vdom/component.cleanup.test.js +323 -0
- package/dist/vdom/component.counter.test.d.ts +2 -0
- package/dist/vdom/component.counter.test.d.ts.map +1 -0
- package/dist/vdom/component.counter.test.js +124 -0
- package/dist/vdom/component.interaction.test.d.ts +2 -0
- package/dist/vdom/component.interaction.test.d.ts.map +1 -0
- package/dist/vdom/component.interaction.test.js +73 -0
- package/dist/vdom/component.props.test.d.ts +2 -0
- package/dist/vdom/component.props.test.d.ts.map +1 -0
- package/dist/vdom/component.props.test.js +88 -0
- package/dist/vdom/component.return-types.test.d.ts +2 -0
- package/dist/vdom/component.return-types.test.d.ts.map +1 -0
- package/dist/vdom/component.return-types.test.js +357 -0
- package/dist/vdom/component.state.test.d.ts +2 -0
- package/dist/vdom/component.state.test.d.ts.map +1 -0
- package/dist/vdom/component.state.test.js +129 -0
- package/dist/vdom/component.test.d.ts +2 -0
- package/dist/vdom/component.test.d.ts.map +1 -0
- package/dist/vdom/component.test.js +63 -0
- package/dist/vdom/dom-utils.d.ts +9 -0
- package/dist/vdom/dom-utils.d.ts.map +1 -0
- package/dist/vdom/dom-utils.js +74 -0
- package/dist/vdom/edge-cases.test.d.ts +2 -0
- package/dist/vdom/edge-cases.test.d.ts.map +1 -0
- package/dist/vdom/edge-cases.test.js +637 -0
- package/dist/vdom/fragment.test.d.ts +2 -0
- package/dist/vdom/fragment.test.d.ts.map +1 -0
- package/dist/vdom/fragment.test.js +618 -0
- package/dist/vdom/index.d.ts +10 -0
- package/dist/vdom/index.d.ts.map +1 -0
- package/dist/vdom/index.js +26 -0
- package/dist/vdom/keys.test.d.ts +2 -0
- package/dist/vdom/keys.test.d.ts.map +1 -0
- package/dist/vdom/keys.test.js +293 -0
- package/dist/vdom/mount.test.d.ts +2 -0
- package/dist/vdom/mount.test.d.ts.map +1 -0
- package/dist/vdom/mount.test.js +91 -0
- package/dist/vdom/patch.test.d.ts +2 -0
- package/dist/vdom/patch.test.d.ts.map +1 -0
- package/dist/vdom/patch.test.js +498 -0
- package/dist/vdom/patchChildren.test.d.ts +2 -0
- package/dist/vdom/patchChildren.test.d.ts.map +1 -0
- package/dist/vdom/patchChildren.test.js +392 -0
- package/dist/vdom/primitives.test.d.ts +2 -0
- package/dist/vdom/primitives.test.d.ts.map +1 -0
- package/dist/vdom/primitives.test.js +132 -0
- package/dist/vdom/types.d.ts +8 -0
- package/dist/vdom/types.d.ts.map +1 -0
- package/dist/vdom/types.js +1 -0
- package/dist/vdom/utils.d.ts +6 -0
- package/dist/vdom/utils.d.ts.map +1 -0
- package/dist/vdom/utils.js +63 -0
- package/package.json +1 -4
package/dist/component.d.ts
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { type VNode } from "snabbdom";
|
|
2
2
|
import { Observer } from "./observation";
|
|
3
3
|
import { ChildNode } from "./render";
|
|
4
|
+
/**
|
|
5
|
+
* Component function type. Components receive reactive props that should not be destructured.
|
|
6
|
+
*
|
|
7
|
+
* @warning **Do not destructure props!** Props are wrapped in a reactive proxy, and destructuring
|
|
8
|
+
* breaks reactivity. This is the same rule as Solid.js.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // ❌ Bad - destructuring props loses reactivity
|
|
12
|
+
* function MyComponent({ count, name }) {
|
|
13
|
+
* return () => <div>{count} {name}</div>; // Won't update!
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* // ✅ Good - access props directly in render
|
|
17
|
+
* function MyComponent(props) {
|
|
18
|
+
* return () => <div>{props.count} {props.name}</div>; // Reactive!
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
4
21
|
export type Component<P> = ((props: P) => () => VNode) | (() => () => VNode);
|
|
5
22
|
export type ComponentInstance = {
|
|
6
23
|
parent: ComponentInstance | null;
|
package/dist/component.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,KAAK,EAAkB,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAsB,QAAQ,EAAU,MAAM,eAAe,CAAC;AACrE,OAAO,EAAc,SAAS,EAAE,MAAM,UAAU,CAAC;AAGjD,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5B,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC,CAAC;AAIF,wBAAgB,mBAAmB,sBAElC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,QAQrC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,QAQvC;AAuGD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,4BAWlC"}
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,KAAK,EAAkB,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAsB,QAAQ,EAAU,MAAM,eAAe,CAAC;AACrE,OAAO,EAAc,SAAS,EAAE,MAAM,UAAU,CAAC;AAGjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5B,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC,CAAC;AAIF,wBAAgB,mBAAmB,sBAElC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,QAQrC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,QAQvC;AAuGD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,4BAWlC"}
|
package/dist/createAsync.d.ts
CHANGED
|
@@ -11,6 +11,29 @@ type AsyncState<T> = {
|
|
|
11
11
|
value: null;
|
|
12
12
|
error: string;
|
|
13
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Creates a reactive async state that tracks the lifecycle of a promise.
|
|
16
|
+
*
|
|
17
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity.
|
|
18
|
+
* Access properties directly in your render function instead.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
22
|
+
* function Component() {
|
|
23
|
+
* const async = createAsync(fetchData());
|
|
24
|
+
* const { isPending, value, error } = async; // Don't do this!
|
|
25
|
+
* return () => <div>{isPending ? "Loading..." : value}</div>; // Won't update!
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* // ✅ Good - access properties directly
|
|
29
|
+
* function Component() {
|
|
30
|
+
* const async = createAsync(fetchData());
|
|
31
|
+
* return () => <div>{async.isPending ? "Loading..." : async.value}</div>;
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* @param promise - The promise to track
|
|
35
|
+
* @returns Reactive state with isPending, value, and error properties
|
|
36
|
+
*/
|
|
14
37
|
export declare function createAsync<T>(promise: Promise<T>): AsyncState<T>;
|
|
15
38
|
export {};
|
|
16
39
|
//# sourceMappingURL=createAsync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createAsync.d.ts","sourceRoot":"","sources":["../src/createAsync.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,CAAC,CAAC,IACb;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,iBAwBjD"}
|
|
1
|
+
{"version":3,"file":"createAsync.d.ts","sourceRoot":"","sources":["../src/createAsync.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,CAAC,CAAC,IACb;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,iBAwBjD"}
|
package/dist/createAsync.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import { createState } from "./createState";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive async state that tracks the lifecycle of a promise.
|
|
4
|
+
*
|
|
5
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity.
|
|
6
|
+
* Access properties directly in your render function instead.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
10
|
+
* function Component() {
|
|
11
|
+
* const async = createAsync(fetchData());
|
|
12
|
+
* const { isPending, value, error } = async; // Don't do this!
|
|
13
|
+
* return () => <div>{isPending ? "Loading..." : value}</div>; // Won't update!
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* // ✅ Good - access properties directly
|
|
17
|
+
* function Component() {
|
|
18
|
+
* const async = createAsync(fetchData());
|
|
19
|
+
* return () => <div>{async.isPending ? "Loading..." : async.value}</div>;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* @param promise - The promise to track
|
|
23
|
+
* @returns Reactive state with isPending, value, and error properties
|
|
24
|
+
*/
|
|
2
25
|
export function createAsync(promise) {
|
|
3
26
|
const state = createState({
|
|
4
27
|
isPending: true,
|
package/dist/createContext.d.ts
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Creates a context object for providing and consuming values across component trees.
|
|
3
|
+
*
|
|
4
|
+
* @warning **Do not destructure context values returned by context.get()!** The returned
|
|
5
|
+
* value may be a reactive object, and destructuring breaks reactivity.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // ❌ Bad - destructuring context value
|
|
9
|
+
* const ThemeContext = createContext<{ color: string }>();
|
|
10
|
+
*
|
|
11
|
+
* function Consumer() {
|
|
12
|
+
* const theme = ThemeContext.get();
|
|
13
|
+
* const { color } = theme; // Don't do this!
|
|
14
|
+
* return () => <div style={{ color }}>Text</div>; // Won't update!
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* // ✅ Good - access properties directly
|
|
18
|
+
* function Consumer() {
|
|
19
|
+
* const theme = ThemeContext.get();
|
|
20
|
+
* return () => <div style={{ color: theme.color }}>Text</div>;
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* @returns Context object with inject() and get() methods
|
|
24
|
+
*/
|
|
25
|
+
export declare function createContext<T>(): {
|
|
26
|
+
inject(value: T): void;
|
|
3
27
|
get(): T;
|
|
4
28
|
};
|
|
5
29
|
//# sourceMappingURL=createContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createContext.d.ts","sourceRoot":"","sources":["../src/createContext.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createContext.d.ts","sourceRoot":"","sources":["../src/createContext.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,CAAC;kBAEb,CAAC;WAaR,CAAC;EAoBX"}
|
package/dist/createContext.js
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
|
-
import { getCurrentComponent } from "./
|
|
1
|
+
import { getCurrentComponent, } from "./vdom/ComponentVNode";
|
|
2
|
+
import { findComponentVNode } from "./vdom/utils";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a context object for providing and consuming values across component trees.
|
|
5
|
+
*
|
|
6
|
+
* @warning **Do not destructure context values returned by context.get()!** The returned
|
|
7
|
+
* value may be a reactive object, and destructuring breaks reactivity.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // ❌ Bad - destructuring context value
|
|
11
|
+
* const ThemeContext = createContext<{ color: string }>();
|
|
12
|
+
*
|
|
13
|
+
* function Consumer() {
|
|
14
|
+
* const theme = ThemeContext.get();
|
|
15
|
+
* const { color } = theme; // Don't do this!
|
|
16
|
+
* return () => <div style={{ color }}>Text</div>; // Won't update!
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* // ✅ Good - access properties directly
|
|
20
|
+
* function Consumer() {
|
|
21
|
+
* const theme = ThemeContext.get();
|
|
22
|
+
* return () => <div style={{ color: theme.color }}>Text</div>;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* @returns Context object with inject() and get() methods
|
|
26
|
+
*/
|
|
2
27
|
export function createContext() {
|
|
3
28
|
const context = {
|
|
4
|
-
|
|
29
|
+
inject(value) {
|
|
5
30
|
const currentComponent = getCurrentComponent();
|
|
6
31
|
if (!currentComponent) {
|
|
7
|
-
throw new Error("You can not
|
|
32
|
+
throw new Error("You can not inject context outside component setup");
|
|
8
33
|
}
|
|
9
34
|
if (!currentComponent.contexts) {
|
|
10
35
|
currentComponent.contexts = new Map();
|
|
@@ -14,13 +39,14 @@ export function createContext() {
|
|
|
14
39
|
get() {
|
|
15
40
|
let currentComponent = getCurrentComponent();
|
|
16
41
|
if (!currentComponent) {
|
|
17
|
-
throw new Error("You can not
|
|
42
|
+
throw new Error("You can not get context outside component setup");
|
|
18
43
|
}
|
|
19
44
|
while (currentComponent) {
|
|
20
45
|
if (currentComponent.contexts?.has(context)) {
|
|
21
46
|
return currentComponent.contexts.get(context);
|
|
22
47
|
}
|
|
23
|
-
|
|
48
|
+
const componentNode = findComponentVNode(currentComponent.parent);
|
|
49
|
+
currentComponent = componentNode?.instance ?? null;
|
|
24
50
|
}
|
|
25
51
|
throw new Error("Could not find context in parent components");
|
|
26
52
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createContext.test.d.ts","sourceRoot":"","sources":["../src/createContext.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "./jsx-runtime";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
import { createContext } from "./createContext";
|
|
4
|
+
import { render } from "./vdom";
|
|
5
|
+
describe("createContext", () => {
|
|
6
|
+
it("should create a context object", () => {
|
|
7
|
+
const context = createContext();
|
|
8
|
+
expect(context).toHaveProperty("inject");
|
|
9
|
+
expect(context).toHaveProperty("get");
|
|
10
|
+
});
|
|
11
|
+
it("should allow setting and getting context values", () => {
|
|
12
|
+
const ThemeContext = createContext();
|
|
13
|
+
function Parent() {
|
|
14
|
+
ThemeContext.inject({ theme: "dark" });
|
|
15
|
+
return () => _jsx(Child, {});
|
|
16
|
+
}
|
|
17
|
+
function Child() {
|
|
18
|
+
const theme = ThemeContext.get();
|
|
19
|
+
return () => _jsx("div", { children: theme.theme });
|
|
20
|
+
}
|
|
21
|
+
const container = document.createElement("div");
|
|
22
|
+
document.body.appendChild(container);
|
|
23
|
+
const vnode = render(_jsx(Parent, {}), container);
|
|
24
|
+
expect(vnode.elm.textContent).toContain("dark");
|
|
25
|
+
document.body.removeChild(vnode.elm);
|
|
26
|
+
});
|
|
27
|
+
it("should traverse parent components to find context", () => {
|
|
28
|
+
const ThemeContext = createContext();
|
|
29
|
+
function GrandParent() {
|
|
30
|
+
ThemeContext.inject({ theme: "light" });
|
|
31
|
+
return () => _jsx(Parent, {});
|
|
32
|
+
}
|
|
33
|
+
function Parent() {
|
|
34
|
+
return () => _jsx(Child, {});
|
|
35
|
+
}
|
|
36
|
+
function Child() {
|
|
37
|
+
const theme = ThemeContext.get();
|
|
38
|
+
return () => _jsx("div", { children: theme.theme });
|
|
39
|
+
}
|
|
40
|
+
const container = document.createElement("div");
|
|
41
|
+
document.body.appendChild(container);
|
|
42
|
+
const vnode = render(_jsx(GrandParent, {}), container);
|
|
43
|
+
expect(vnode.elm.textContent).toContain("light");
|
|
44
|
+
document.body.removeChild(vnode.elm);
|
|
45
|
+
});
|
|
46
|
+
it("should throw error when context is not found", () => {
|
|
47
|
+
const ThemeContext = createContext();
|
|
48
|
+
function Child() {
|
|
49
|
+
expect(() => {
|
|
50
|
+
ThemeContext.get();
|
|
51
|
+
}).toThrow("Could not find context in parent components");
|
|
52
|
+
return () => _jsx("div", { children: "Child" });
|
|
53
|
+
}
|
|
54
|
+
const container = document.createElement("div");
|
|
55
|
+
document.body.appendChild(container);
|
|
56
|
+
const vnode = render(_jsx(Child, {}), container);
|
|
57
|
+
document.body.removeChild(vnode.elm);
|
|
58
|
+
});
|
|
59
|
+
it("should throw error when setting context outside component", () => {
|
|
60
|
+
const ThemeContext = createContext();
|
|
61
|
+
expect(() => {
|
|
62
|
+
ThemeContext.inject({ theme: "dark" });
|
|
63
|
+
}).toThrow("No current root");
|
|
64
|
+
});
|
|
65
|
+
it("should throw error when getting context outside component", () => {
|
|
66
|
+
const ThemeContext = createContext();
|
|
67
|
+
expect(() => {
|
|
68
|
+
ThemeContext.get();
|
|
69
|
+
}).toThrow("No current root");
|
|
70
|
+
});
|
|
71
|
+
it("should allow overriding context in nested components", () => {
|
|
72
|
+
const ThemeContext = createContext();
|
|
73
|
+
function GrandParent() {
|
|
74
|
+
ThemeContext.inject({ theme: "light" });
|
|
75
|
+
return () => (_jsxs("div", { children: [_jsx(Parent, {}), _jsx(ChildOfGrandParent, {})] }));
|
|
76
|
+
}
|
|
77
|
+
function Parent() {
|
|
78
|
+
ThemeContext.inject({ theme: "dark" });
|
|
79
|
+
return () => _jsx(ChildOfParent, {});
|
|
80
|
+
}
|
|
81
|
+
function ChildOfParent() {
|
|
82
|
+
const theme = ThemeContext.get();
|
|
83
|
+
return () => _jsx("div", { class: "child-of-parent", children: theme.theme });
|
|
84
|
+
}
|
|
85
|
+
function ChildOfGrandParent() {
|
|
86
|
+
const theme = ThemeContext.get();
|
|
87
|
+
return () => _jsx("div", { class: "child-of-grandparent", children: theme.theme });
|
|
88
|
+
}
|
|
89
|
+
const container = document.createElement("div");
|
|
90
|
+
document.body.appendChild(container);
|
|
91
|
+
const vnode = render(_jsx(GrandParent, {}), container);
|
|
92
|
+
const childOfParent = document.querySelector(".child-of-parent");
|
|
93
|
+
const childOfGrandParent = document.querySelector(".child-of-grandparent");
|
|
94
|
+
expect(childOfParent?.textContent).toBe("dark");
|
|
95
|
+
expect(childOfGrandParent?.textContent).toBe("light");
|
|
96
|
+
document.body.removeChild(vnode.elm);
|
|
97
|
+
});
|
|
98
|
+
it("should support multiple different contexts", () => {
|
|
99
|
+
const ThemeContext = createContext();
|
|
100
|
+
const UserContext = createContext();
|
|
101
|
+
function Parent() {
|
|
102
|
+
ThemeContext.inject({ theme: "dark" });
|
|
103
|
+
UserContext.inject({ name: "Alice" });
|
|
104
|
+
return () => _jsx(Child, {});
|
|
105
|
+
}
|
|
106
|
+
function Child() {
|
|
107
|
+
const theme = ThemeContext.get();
|
|
108
|
+
const user = UserContext.get();
|
|
109
|
+
return () => (_jsxs("div", { children: [theme.theme, " - ", user.name] }));
|
|
110
|
+
}
|
|
111
|
+
const container = document.createElement("div");
|
|
112
|
+
document.body.appendChild(container);
|
|
113
|
+
const vnode = render(_jsx(Parent, {}), container);
|
|
114
|
+
expect(vnode.elm.textContent).toContain("dark - Alice");
|
|
115
|
+
document.body.removeChild(vnode.elm);
|
|
116
|
+
});
|
|
117
|
+
it("should handle context values of different types", () => {
|
|
118
|
+
const NumberContext = createContext();
|
|
119
|
+
const ArrayContext = createContext();
|
|
120
|
+
function Parent() {
|
|
121
|
+
NumberContext.inject(42);
|
|
122
|
+
ArrayContext.inject(["a", "b", "c"]);
|
|
123
|
+
return () => _jsx(Child, {});
|
|
124
|
+
}
|
|
125
|
+
function Child() {
|
|
126
|
+
const num = NumberContext.get();
|
|
127
|
+
const arr = ArrayContext.get();
|
|
128
|
+
return () => (_jsxs("div", { children: [num, " - ", arr.join(",")] }));
|
|
129
|
+
}
|
|
130
|
+
const container = document.createElement("div");
|
|
131
|
+
document.body.appendChild(container);
|
|
132
|
+
const vnode = render(_jsx(Parent, {}), container);
|
|
133
|
+
expect(vnode.elm.textContent).toContain("42 - a,b,c");
|
|
134
|
+
document.body.removeChild(vnode.elm);
|
|
135
|
+
});
|
|
136
|
+
});
|
package/dist/createMutation.d.ts
CHANGED
|
@@ -15,6 +15,29 @@ export type Mutation<T> = MutationState<T> & {
|
|
|
15
15
|
mutate(): void;
|
|
16
16
|
mutate(params: T): void;
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Creates a reactive mutation that manages async mutations with loading and error states.
|
|
20
|
+
*
|
|
21
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity.
|
|
22
|
+
* Access properties directly in your render function instead.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
26
|
+
* function Component() {
|
|
27
|
+
* const mutation = createMutation((params) => updateUser(params));
|
|
28
|
+
* const { isPending, error } = mutation; // Don't do this!
|
|
29
|
+
* return () => <button disabled={isPending}>Save</button>; // Won't update!
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* // ✅ Good - access properties directly
|
|
33
|
+
* function Component() {
|
|
34
|
+
* const mutation = createMutation((params) => updateUser(params));
|
|
35
|
+
* return () => <button disabled={mutation.isPending}>Save</button>;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* @param mutator - Function that performs the mutation and returns a promise
|
|
39
|
+
* @returns Reactive mutation object with isPending, params, error properties and mutate method
|
|
40
|
+
*/
|
|
18
41
|
export declare function createMutation<T>(mutator: (params: T) => Promise<T>): Mutation<T>;
|
|
19
42
|
export {};
|
|
20
43
|
//# sourceMappingURL=createMutation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createMutation.d.ts","sourceRoot":"","sources":["../src/createMutation.ts"],"names":[],"mappings":"AAEA,KAAK,aAAa,CAAC,CAAC,IAChB;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG;IAC3C,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACjC,QAAQ,CAAC,CAAC,CAAC,CA0Db"}
|
|
1
|
+
{"version":3,"file":"createMutation.d.ts","sourceRoot":"","sources":["../src/createMutation.ts"],"names":[],"mappings":"AAEA,KAAK,aAAa,CAAC,CAAC,IAChB;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG;IAC3C,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACjC,QAAQ,CAAC,CAAC,CAAC,CA0Db"}
|
package/dist/createMutation.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import { createState } from "./createState";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive mutation that manages async mutations with loading and error states.
|
|
4
|
+
*
|
|
5
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity.
|
|
6
|
+
* Access properties directly in your render function instead.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
10
|
+
* function Component() {
|
|
11
|
+
* const mutation = createMutation((params) => updateUser(params));
|
|
12
|
+
* const { isPending, error } = mutation; // Don't do this!
|
|
13
|
+
* return () => <button disabled={isPending}>Save</button>; // Won't update!
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* // ✅ Good - access properties directly
|
|
17
|
+
* function Component() {
|
|
18
|
+
* const mutation = createMutation((params) => updateUser(params));
|
|
19
|
+
* return () => <button disabled={mutation.isPending}>Save</button>;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* @param mutator - Function that performs the mutation and returns a promise
|
|
23
|
+
* @returns Reactive mutation object with isPending, params, error properties and mutate method
|
|
24
|
+
*/
|
|
2
25
|
export function createMutation(mutator) {
|
|
3
26
|
const state = createState({
|
|
4
27
|
isPending: false,
|
package/dist/createQuery.d.ts
CHANGED
|
@@ -14,6 +14,29 @@ type QueryState<T> = {
|
|
|
14
14
|
export type Query<T> = QueryState<T> & {
|
|
15
15
|
fetch(force?: boolean): void;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Creates a reactive query that manages data fetching with loading and error states.
|
|
19
|
+
*
|
|
20
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity.
|
|
21
|
+
* Access properties directly in your render function instead.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
25
|
+
* function Component() {
|
|
26
|
+
* const query = createQuery(() => fetchUsers());
|
|
27
|
+
* const { isPending, data, error } = query; // Don't do this!
|
|
28
|
+
* return () => <div>{isPending ? "Loading..." : data.length}</div>; // Won't update!
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* // ✅ Good - access properties directly
|
|
32
|
+
* function Component() {
|
|
33
|
+
* const query = createQuery(() => fetchUsers());
|
|
34
|
+
* return () => <div>{query.isPending ? "Loading..." : query.data.length}</div>;
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* @param fetcher - Function that returns a promise with the data to fetch
|
|
38
|
+
* @returns Reactive query object with isPending, data, error properties and fetch method
|
|
39
|
+
*/
|
|
17
40
|
export declare function createQuery<T>(fetcher: () => Promise<T>): Query<T>;
|
|
18
41
|
export {};
|
|
19
42
|
//# sourceMappingURL=createQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createQuery.d.ts","sourceRoot":"","sources":["../src/createQuery.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,CAAC,CAAC,IACb;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG;IACrC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CA+DlE"}
|
|
1
|
+
{"version":3,"file":"createQuery.d.ts","sourceRoot":"","sources":["../src/createQuery.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,CAAC,CAAC,IACb;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACf,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG;IACrC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CA+DlE"}
|
package/dist/createQuery.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
import { createState } from "./createState";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive query that manages data fetching with loading and error states.
|
|
4
|
+
*
|
|
5
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity.
|
|
6
|
+
* Access properties directly in your render function instead.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
10
|
+
* function Component() {
|
|
11
|
+
* const query = createQuery(() => fetchUsers());
|
|
12
|
+
* const { isPending, data, error } = query; // Don't do this!
|
|
13
|
+
* return () => <div>{isPending ? "Loading..." : data.length}</div>; // Won't update!
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* // ✅ Good - access properties directly
|
|
17
|
+
* function Component() {
|
|
18
|
+
* const query = createQuery(() => fetchUsers());
|
|
19
|
+
* return () => <div>{query.isPending ? "Loading..." : query.data.length}</div>;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* @param fetcher - Function that returns a promise with the data to fetch
|
|
23
|
+
* @returns Reactive query object with isPending, data, error properties and fetch method
|
|
24
|
+
*/
|
|
2
25
|
export function createQuery(fetcher) {
|
|
3
26
|
const state = createState({
|
|
4
27
|
isPending: true,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRef.test.d.ts","sourceRoot":"","sources":["../src/createRef.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "./jsx-runtime";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
import { createRef } from "./createRef";
|
|
4
|
+
import { render } from "./vdom";
|
|
5
|
+
describe("createRef", () => {
|
|
6
|
+
it("should create a ref with null initial value", () => {
|
|
7
|
+
const ref = createRef();
|
|
8
|
+
expect(ref.current).toBeNull();
|
|
9
|
+
});
|
|
10
|
+
it("should be callable as a function", () => {
|
|
11
|
+
const ref = createRef();
|
|
12
|
+
expect(typeof ref).toBe("function");
|
|
13
|
+
});
|
|
14
|
+
it("should update current when called with a node", () => {
|
|
15
|
+
const ref = createRef();
|
|
16
|
+
const element = document.createElement("div");
|
|
17
|
+
ref(element);
|
|
18
|
+
expect(ref.current).toBe(element);
|
|
19
|
+
});
|
|
20
|
+
it("should update current when called with null", () => {
|
|
21
|
+
const ref = createRef();
|
|
22
|
+
const element = document.createElement("div");
|
|
23
|
+
ref(element);
|
|
24
|
+
expect(ref.current).toBe(element);
|
|
25
|
+
ref(null);
|
|
26
|
+
expect(ref.current).toBeNull();
|
|
27
|
+
});
|
|
28
|
+
it("should work with JSX ref attribute", async () => {
|
|
29
|
+
const ref = createRef();
|
|
30
|
+
function TestComponent() {
|
|
31
|
+
return () => _jsx("div", { ref: ref, children: "Hello" });
|
|
32
|
+
}
|
|
33
|
+
const container = document.createElement("div");
|
|
34
|
+
document.body.appendChild(container);
|
|
35
|
+
const vnode = render(_jsx(TestComponent, {}), container);
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
37
|
+
expect(ref.current).not.toBeNull();
|
|
38
|
+
expect(ref.current?.tagName).toBe("DIV");
|
|
39
|
+
expect(ref.current?.textContent).toBe("Hello");
|
|
40
|
+
document.body.removeChild(vnode.elm);
|
|
41
|
+
});
|
|
42
|
+
it("should handle multiple ref updates", () => {
|
|
43
|
+
const ref = createRef();
|
|
44
|
+
const div = document.createElement("div");
|
|
45
|
+
const span = document.createElement("span");
|
|
46
|
+
ref(div);
|
|
47
|
+
expect(ref.current).toBe(div);
|
|
48
|
+
ref(span);
|
|
49
|
+
expect(ref.current).toBe(span);
|
|
50
|
+
ref(null);
|
|
51
|
+
expect(ref.current).toBeNull();
|
|
52
|
+
});
|
|
53
|
+
it("should work with different element types", async () => {
|
|
54
|
+
const inputRef = createRef();
|
|
55
|
+
const buttonRef = createRef();
|
|
56
|
+
function TestComponent() {
|
|
57
|
+
return () => (_jsxs("div", { children: [_jsx("input", { ref: inputRef, type: "text" }), _jsx("button", { ref: buttonRef, children: "Click" })] }));
|
|
58
|
+
}
|
|
59
|
+
const container = document.createElement("div");
|
|
60
|
+
document.body.appendChild(container);
|
|
61
|
+
const vnode = render(_jsx(TestComponent, {}), container);
|
|
62
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
63
|
+
expect(inputRef.current?.tagName).toBe("INPUT");
|
|
64
|
+
expect(buttonRef.current?.tagName).toBe("BUTTON");
|
|
65
|
+
document.body.removeChild(vnode.elm);
|
|
66
|
+
});
|
|
67
|
+
it("should allow accessing DOM properties", async () => {
|
|
68
|
+
const ref = createRef();
|
|
69
|
+
function TestComponent() {
|
|
70
|
+
return () => _jsx("input", { ref: ref, type: "text", value: "test" });
|
|
71
|
+
}
|
|
72
|
+
const container = document.createElement("div");
|
|
73
|
+
document.body.appendChild(container);
|
|
74
|
+
const vnode = render(_jsx(TestComponent, {}), container);
|
|
75
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
76
|
+
expect(ref.current?.value).toBe("test");
|
|
77
|
+
expect(ref.current?.type).toBe("text");
|
|
78
|
+
document.body.removeChild(vnode.elm);
|
|
79
|
+
});
|
|
80
|
+
});
|
package/dist/createState.d.ts
CHANGED
|
@@ -1,2 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a reactive state object that tracks property access and notifies observers on changes.
|
|
3
|
+
*
|
|
4
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity
|
|
5
|
+
* because it extracts plain values instead of maintaining proxy access. This is the same rule
|
|
6
|
+
* as Solid.js signals.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
10
|
+
* function Component(props) {
|
|
11
|
+
* const state = createState({ count: 0, name: "foo" });
|
|
12
|
+
* const { count, name } = state; // Don't do this!
|
|
13
|
+
* return () => <div>{count} {name}</div>; // Won't update!
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* // ✅ Good - access properties directly in render
|
|
17
|
+
* function Component(props) {
|
|
18
|
+
* const state = createState({ count: 0, name: "foo" });
|
|
19
|
+
* return () => <div>{state.count} {state.name}</div>; // Reactive!
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* @param state - The initial state object to make reactive
|
|
23
|
+
* @returns A reactive proxy of the state object
|
|
24
|
+
*/
|
|
1
25
|
export declare function createState<T extends object>(state: T): T;
|
|
2
26
|
//# sourceMappingURL=createState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createState.d.ts","sourceRoot":"","sources":["../src/createState.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEzD"}
|
|
1
|
+
{"version":3,"file":"createState.d.ts","sourceRoot":"","sources":["../src/createState.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAEzD"}
|
package/dist/createState.js
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import { getCurrentObserver, Signal } from "./observation";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a reactive state object that tracks property access and notifies observers on changes.
|
|
4
|
+
*
|
|
5
|
+
* @warning **Do not destructure the returned reactive object!** Destructuring breaks reactivity
|
|
6
|
+
* because it extracts plain values instead of maintaining proxy access. This is the same rule
|
|
7
|
+
* as Solid.js signals.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // ❌ Bad - destructuring loses reactivity
|
|
11
|
+
* function Component(props) {
|
|
12
|
+
* const state = createState({ count: 0, name: "foo" });
|
|
13
|
+
* const { count, name } = state; // Don't do this!
|
|
14
|
+
* return () => <div>{count} {name}</div>; // Won't update!
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* // ✅ Good - access properties directly in render
|
|
18
|
+
* function Component(props) {
|
|
19
|
+
* const state = createState({ count: 0, name: "foo" });
|
|
20
|
+
* return () => <div>{state.count} {state.name}</div>; // Reactive!
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* @param state - The initial state object to make reactive
|
|
24
|
+
* @returns A reactive proxy of the state object
|
|
25
|
+
*/
|
|
2
26
|
export function createState(state) {
|
|
3
27
|
return getProxy(state);
|
|
4
28
|
}
|