rask-ui 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,29 @@ A lightweight reactive component library that combines the simplicity of observa
10
10
  npm install rask-ui
11
11
  ```
12
12
 
13
+ ---
14
+
15
+ ## 📢 Open For Feedback
16
+
17
+ **RASK is feature-complete and ready for community feedback!**
18
+
19
+ The core implementation is finished, including:
20
+ - ✅ Inferno-based reconciler for powerful UI expression
21
+ - ✅ JSX transformation plugin (Inferno JSX + stateful components)
22
+ - ✅ Reactive primitives for simple state management
23
+
24
+ **Before the official release, we need your input:**
25
+ - Would a library like this be valuable for your projects?
26
+ - Is the API clear and intuitive?
27
+ - Is the documentation helpful and complete?
28
+ - Does the approach resonate with you?
29
+
30
+ **[Share your feedback by creating an issue →](https://github.com/christianalfoni/rask/issues/new)**
31
+
32
+ Your feedback will directly shape the final release. All perspectives welcome!
33
+
34
+ ---
35
+
13
36
  ## The Itch with Modern UI Frameworks
14
37
 
15
38
  Modern UI frameworks present developers with a fundamental tradeoff between state management and UI expression:
@@ -68,79 +91,24 @@ RASK gives you:
68
91
 
69
92
  ## Getting Started
70
93
 
71
- ### Installation
94
+ The fastest way to get started is using `create-rask-ui`:
72
95
 
73
96
  ```bash
74
- npm install rask-ui
97
+ npm create rask-ui my-app
98
+ cd my-app
99
+ npm run dev
75
100
  ```
76
101
 
77
- ### Vite Setup
78
-
79
- RASK uses a custom Vite plugin powered by SWC for optimal JSX transformation. This plugin transforms JSX to Inferno's highly optimized `createVNode` calls and automatically converts function components to RASK's reactive component pattern.
102
+ This will scaffold a new Vite project with RASK UI pre-configured and ready to go. You'll be prompted to choose between TypeScript or JavaScript.
80
103
 
81
- #### 1. Configure Vite
82
-
83
- Create or update your `vite.config.ts`:
84
-
85
- ```ts
86
- import { defineConfig } from 'vite';
87
- import { raskPlugin } from 'rask-ui/plugin';
88
-
89
- export default defineConfig({
90
- plugins: [raskPlugin()],
91
- });
92
- ```
93
-
94
- **Plugin Options:**
95
-
96
- ```ts
97
- raskPlugin({
98
- // Enable/disable function component transformation
99
- // Default: true
100
- transformComponents: true,
101
-
102
- // Add imports for Inferno utilities (usually not needed)
103
- // Default: false
104
- imports: false,
105
-
106
- // Package to import from when transformComponents is enabled
107
- // Default: "rask-ui"
108
- importSource: "rask-ui",
109
-
110
- // Define all arguments for createVNode (for debugging)
111
- // Default: false
112
- defineAllArguments: false,
113
- })
114
- ```
104
+ ### What's Included
115
105
 
116
- #### 2. Configure TypeScript
106
+ The scaffolded project includes:
117
107
 
118
- Update your `tsconfig.json`:
119
-
120
- ```json
121
- {
122
- "compilerOptions": {
123
- "jsx": "react-jsx",
124
- "jsxImportSource": "rask-ui",
125
- "moduleResolution": "bundler",
126
- "target": "ES2022",
127
- "module": "ESNext",
128
- "lib": ["ES2022", "DOM", "DOM.Iterable"]
129
- }
130
- }
131
- ```
132
-
133
- **Key settings:**
134
-
135
- - `"jsx": "react-jsx"` - Tells TypeScript to use the new JSX transform for type checking
136
- - `"jsxImportSource": "rask-ui"` - Points to RASK's JSX runtime for type definitions
137
- - `"moduleResolution": "bundler"` - Required for Vite
138
-
139
- **How it works:**
140
-
141
- - **TypeScript**: Type-checks JSX using RASK's type definitions (imported from Inferno)
142
- - **SWC Plugin**: Transforms JSX to Inferno's `createVNode` calls at build time
143
- - The result: You get full type safety with zero runtime overhead
108
+ - Vite configured with the RASK plugin
109
+ - ✅ TypeScript or JavaScript with proper JSX configuration
110
+ - ✅ Hot Module Replacement (HMR) working out of the box
111
+ - ✅ Sample counter component to get you started
144
112
 
145
113
  ### Basic Example
146
114
 
@@ -173,7 +141,7 @@ function MyComponent(props) {
173
141
  // SETUP PHASE - Runs once when component is created
174
142
  const state = createState({ value: props.initial });
175
143
 
176
- onMount(() => {
144
+ createMountEffect(() => {
177
145
  console.log("Component mounted!");
178
146
  });
179
147
 
@@ -250,7 +218,7 @@ When `state.count` changes in Parent, only Child re-renders because it accesses
250
218
 
251
219
  ### One Rule To Accept
252
220
 
253
- **RASK has observable primitives**: Never destructure reactive objects (state, props, context values, async, query, mutation). Destructuring extracts plain values and breaks reactivity.
221
+ **RASK has observable primitives**: Never destructure reactive objects (state, props, context values, tasks). Destructuring extracts plain values and breaks reactivity.
254
222
 
255
223
  ```tsx
256
224
  // ❌ BAD - Destructuring breaks reactivity
@@ -296,9 +264,7 @@ Reactive objects are implemented using JavaScript Proxies. When you access a pro
296
264
  - `createState()` - Never destructure state objects
297
265
  - Props - Never destructure component props
298
266
  - `createContext().get()` - Never destructure context values
299
- - `createAsync()` - Never destructure async state
300
- - `createQuery()` - Never destructure query objects
301
- - `createMutation()` - Never destructure mutation objects
267
+ - `createTask()` - Never destructure task objects
302
268
  - `createView()` - Never destructure view objects
303
269
  - `createComputed()` - Never destructure computed objects
304
270
 
@@ -614,15 +580,15 @@ function BatchingExample() {
614
580
 
615
581
  ### Lifecycle Hooks
616
582
 
617
- #### `onMount(callback)`
583
+ #### `createMountEffect(callback)`
618
584
 
619
585
  Registers a callback to run after the component is mounted to the DOM.
620
586
 
621
587
  ```tsx
622
- import { onMount } from "rask-ui";
588
+ import { createMountEffect } from "rask-ui";
623
589
 
624
590
  function Example() {
625
- onMount(() => {
591
+ createMountEffect(() => {
626
592
  console.log("Component mounted!");
627
593
  });
628
594
 
@@ -641,12 +607,12 @@ function Example() {
641
607
 
642
608
  ---
643
609
 
644
- #### `onCleanup(callback)`
610
+ #### `createCleanup(callback)`
645
611
 
646
612
  Registers a callback to run when the component is unmounted.
647
613
 
648
614
  ```tsx
649
- import { onCleanup } from "rask-ui";
615
+ import { createCleanup } from "rask-ui";
650
616
 
651
617
  function Example() {
652
618
  const state = createState({ time: Date.now() });
@@ -655,7 +621,7 @@ function Example() {
655
621
  state.time = Date.now();
656
622
  }, 1000);
657
623
 
658
- onCleanup(() => {
624
+ createCleanup(() => {
659
625
  clearInterval(interval);
660
626
  });
661
627
 
@@ -716,58 +682,38 @@ function Child() {
716
682
 
717
683
  ### Async Data Management
718
684
 
719
- #### `createAsync<T>(promise)`
685
+ #### `createTask<T, P>(task)`
720
686
 
721
- Creates reactive state for async operations with loading and error states.
687
+ Creates a low-level reactive primitive for managing async operations with loading, error, and result states. This is a generic primitive that gives you full control over async state management without prescribing patterns.
722
688
 
723
689
  ```tsx
724
- import { createAsync } from "rask-ui";
690
+ import { createTask } from "rask-ui";
725
691
 
692
+ // Simple task without parameters - auto-runs on creation
726
693
  function UserProfile() {
727
- const user = createAsync(fetch("/api/user").then((r) => r.json()));
694
+ const user = createTask(() => fetch("/api/user").then((r) => r.json()));
728
695
 
729
- return () => }
730
- if (user.isPending) {
731
- return <p>Loading...</p>
696
+ return () => {
697
+ if (user.isRunning) {
698
+ return <p>Loading...</p>;
732
699
  }
733
700
 
734
701
  if (user.error) {
735
- return <p>Error: {user.error}</p>
702
+ return <p>Error: {user.error}</p>;
736
703
  }
737
704
 
738
- return <p>Hello, {user.value.name}!</p>
705
+ return <p>Hello, {user.result.name}!</p>;
706
+ };
739
707
  }
740
- ```
741
-
742
- **Parameters:**
743
-
744
- - `promise: Promise<T>` - The promise to track
745
-
746
- **Returns:** Reactive object with:
747
-
748
- - `isPending: boolean` - True while promise is pending
749
- - `value: T | null` - Resolved value (null while pending or on error)
750
- - `error: string | null` - Error message (null while pending or on success)
751
-
752
- **States:**
753
-
754
- - `{ isPending: true, value: null, error: null }` - Loading
755
- - `{ isPending: false, value: T, error: null }` - Success
756
- - `{ isPending: false, value: null, error: string }` - Error
757
-
758
- ---
759
-
760
- #### `createQuery<T>(fetcher)`
761
-
762
- Creates a query with refetch capability and request cancellation.
763
-
764
- ```tsx
765
- import { createQuery } from "rask-ui";
766
708
 
709
+ // Task with parameters - control when to run
767
710
  function Posts() {
768
- const posts = createQuery(() => fetch("/api/posts").then((r) => r.json()));
711
+ const posts = createTask((page: number) =>
712
+ fetch(`/api/posts?page=${page}`).then((r) => r.json())
713
+ );
714
+
769
715
  const renderPosts = () => {
770
- if (posts.isPending) {
716
+ if (posts.isRunning) {
771
717
  return <p>Loading...</p>;
772
718
  }
773
719
 
@@ -775,61 +721,37 @@ function Posts() {
775
721
  return <p>Error: {posts.error}</p>;
776
722
  }
777
723
 
778
- return posts.data.map((post) => (
724
+ if (!posts.result) {
725
+ return <p>No posts loaded</p>;
726
+ }
727
+
728
+ return posts.result.map((post) => (
779
729
  <article key={post.id}>{post.title}</article>
780
730
  ));
781
731
  };
782
732
 
783
733
  return () => (
784
734
  <div>
785
- <button onClick={() => posts.fetch()}>Refresh</button>
786
- <button onClick={() => posts.fetch(true)}>Force Refresh</button>
735
+ <button onClick={() => posts.run(1)}>Load Page 1</button>
736
+ <button onClick={() => posts.rerun(1)}>Reload Page 1</button>
787
737
  {renderPosts()}
788
738
  </div>
789
739
  );
790
740
  }
791
- ```
792
-
793
- **Parameters:**
794
-
795
- - `fetcher: () => Promise<T>` - Function that returns a promise
796
-
797
- **Returns:** Query object with:
798
-
799
- - `isPending: boolean` - True while fetching
800
- - `data: T | null` - Fetched data
801
- - `error: string | null` - Error message
802
- - `fetch(force?: boolean)` - Refetch data
803
- - `force: false` (default) - Keep existing data while refetching
804
- - `force: true` - Clear data before refetching
805
-
806
- **Features:**
807
-
808
- - Automatic request cancellation on refetch
809
- - Keeps old data by default during refetch
810
- - Automatically fetches on creation
811
-
812
- ---
813
-
814
- #### `createMutation<T>(mutator)`
815
-
816
- Creates a mutation for data updates with pending and error states.
817
-
818
- ```tsx
819
- import { createMutation } from "rask-ui";
820
741
 
742
+ // Mutation-style usage
821
743
  function CreatePost() {
822
744
  const state = createState({ title: "", body: "" });
823
745
 
824
- const create = createMutation((data) =>
746
+ const create = createTask((data: { title: string; body: string }) =>
825
747
  fetch("/api/posts", {
826
748
  method: "POST",
827
749
  body: JSON.stringify(data),
828
- }))
750
+ }).then((r) => r.json())
829
751
  );
830
752
 
831
753
  const handleSubmit = () => {
832
- create.mutate({ title: state.title, body: state.body });
754
+ create.run({ title: state.title, body: state.body });
833
755
  };
834
756
 
835
757
  return () => (
@@ -842,8 +764,8 @@ function CreatePost() {
842
764
  value={state.body}
843
765
  onInput={(e) => (state.body = e.target.value)}
844
766
  />
845
- <button disabled={create.isPending}>
846
- {create.isPending ? "Creating..." : "Create"}
767
+ <button disabled={create.isRunning}>
768
+ {create.isRunning ? "Creating..." : "Create"}
847
769
  </button>
848
770
  {create.error && <p>Error: {create.error}</p>}
849
771
  </form>
@@ -851,22 +773,72 @@ function CreatePost() {
851
773
  }
852
774
  ```
853
775
 
854
- **Parameters:**
776
+ **Type Signatures:**
855
777
 
856
- - `mutator: (params: T) => Promise<T>` - Function that performs the mutation
778
+ ```tsx
779
+ // Task without parameters - auto-runs on creation
780
+ createTask<T>(task: () => Promise<T>): Task<T, never> & {
781
+ run(): Promise<T>;
782
+ rerun(): Promise<T>;
783
+ }
784
+
785
+ // Task with parameters - manual control
786
+ createTask<T, P>(task: (params: P) => Promise<T>): Task<T, P> & {
787
+ run(params: P): Promise<T>;
788
+ rerun(params: P): Promise<T>;
789
+ }
790
+ ```
791
+
792
+ **Returns:** Task object with reactive state and methods:
793
+
794
+ **State Properties:**
795
+ - `isRunning: boolean` - True while task is executing
796
+ - `result: T | null` - Result of successful execution (null if not yet run, running, or error)
797
+ - `error: string | null` - Error message from failed execution (null if successful or running)
798
+ - `params: P | null` - Current parameters while running (null when idle)
799
+
800
+ **Methods:**
801
+ - `run(params?: P): Promise<T>` - Execute the task, clearing previous result
802
+ - `rerun(params?: P): Promise<T>` - Re-execute the task, keeping previous result until new one arrives
803
+
804
+ **State Transitions:**
805
+
806
+ Initial state (no params):
807
+ ```tsx
808
+ { isRunning: false, params: null, result: null, error: null }
809
+ ```
857
810
 
858
- **Returns:** Mutation object with:
811
+ While running:
812
+ ```tsx
813
+ { isRunning: true, result: T | null, params: P, error: null }
814
+ ```
859
815
 
860
- - `isPending: boolean` - True while mutation is in progress
861
- - `params: T | null` - Current mutation parameters
862
- - `error: string | null` - Error message
863
- - `mutate(params: T)` - Execute the mutation
816
+ Success:
817
+ ```tsx
818
+ { isRunning: false, params: null, result: T, error: null }
819
+ ```
820
+
821
+ Error:
822
+ ```tsx
823
+ { isRunning: false, params: null, result: null, error: string }
824
+ ```
864
825
 
865
826
  **Features:**
866
827
 
867
- - Automatic request cancellation if mutation called again
868
- - Tracks mutation parameters
869
- - Resets state after successful completion
828
+ - **Automatic cancellation** - Previous executions are cancelled when a new one starts
829
+ - **Flexible control** - Use `run()` to clear old data or `rerun()` to keep it during loading
830
+ - **Type-safe** - Full TypeScript inference for parameters and results
831
+ - **Auto-run support** - Tasks without parameters run automatically on creation
832
+ - **Generic primitive** - Build your own patterns on top (queries, mutations, etc.)
833
+
834
+ **Usage Patterns:**
835
+
836
+ Use `createTask` as a building block for various async patterns:
837
+ - **Queries**: Tasks that fetch data and can be refetched
838
+ - **Mutations**: Tasks that modify server state
839
+ - **Polling**: Tasks that run periodically
840
+ - **Debounced searches**: Tasks that run based on user input
841
+ - **File uploads**: Tasks that track upload progress
870
842
 
871
843
  ---
872
844
 
@@ -1223,4 +1195,4 @@ MIT
1223
1195
 
1224
1196
  ## Why "RASK"?
1225
1197
 
1226
- The name comes from Norwegian/Swedish meaning "fast" - which captures the essence of this library: fast to write, fast to understand, and fast to run.
1198
+ The name comes from Norwegian meaning "fast" - which captures the essence of this library: fast to write, fast to understand, and fast to run.
@@ -1,7 +1,7 @@
1
1
  import { VNode, Component, Props } from "inferno";
2
2
  export declare function getCurrentComponent(): RaskComponent<any>;
3
- export declare function onMount(cb: () => void): void;
4
- export declare function onCleanup(cb: () => void): void;
3
+ export declare function createMountEffect(cb: () => void): void;
4
+ export declare function createCleanup(cb: () => void): void;
5
5
  export type RaskFunctionComponent<P extends Props<any>> = (() => () => VNode) | ((props: P) => () => VNode);
6
6
  export declare class RaskComponent<P extends Props<any>> extends Component<P> {
7
7
  setup: RaskFunctionComponent<P>;
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACL,SAAS,EACT,KAAK,EAEN,MAAM,SAAS,CAAC;AAQjB,wBAAgB,mBAAmB,uBAMlC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,QAMrC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,QAMvC;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAClD,CAAC,MAAM,MAAM,KAAK,CAAC,GACnB,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,CAAC;AAEhC,qBAAa,aAAa,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,QAAQ,CAEb;IACH,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAM;IAC3D,QAAQ,gBAAa;IACrB,eAAe;IAUf,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACjC,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACnC,OAAO,CAAC,mBAAmB;IA2D3B,iBAAiB,IAAI,IAAI;IAGzB,oBAAoB,IAAI,IAAI;IAG5B;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,GAAG;IAYlC,yBAAyB,IAAI,IAAI;IACjC,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO;IAerD,MAAM;CAyCP;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,SAO9D"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,EACL,SAAS,EACT,KAAK,EAEN,MAAM,SAAS,CAAC;AAQjB,wBAAgB,mBAAmB,uBAMlC;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,QAM/C;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,IAAI,QAM3C;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAClD,CAAC,MAAM,MAAM,KAAK,CAAC,GACnB,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,CAAC;AAEhC,qBAAa,aAAa,CAAC,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,CAAc;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,QAAQ,CAEb;IACH,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAM;IAC3D,QAAQ,gBAAa;IACrB,eAAe;IAUf,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACjC,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAM;IACnC,OAAO,CAAC,mBAAmB;IA2D3B,iBAAiB,IAAI,IAAI;IAGzB,oBAAoB,IAAI,IAAI;IAG5B;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,GAAG;IAYlC,yBAAyB,IAAI,IAAI;IACjC,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO;IAerD,MAAM;CAyCP;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,SAO9D"}
package/dist/component.js CHANGED
@@ -8,15 +8,15 @@ export function getCurrentComponent() {
8
8
  }
9
9
  return currentComponent;
10
10
  }
11
- export function onMount(cb) {
11
+ export function createMountEffect(cb) {
12
12
  if (!currentComponent) {
13
- throw new Error("Only use onCleanup in component setup");
13
+ throw new Error("Only use createMountEffect in component setup");
14
14
  }
15
15
  currentComponent.onMounts.push(cb);
16
16
  }
17
- export function onCleanup(cb) {
17
+ export function createCleanup(cb) {
18
18
  if (!currentComponent) {
19
- throw new Error("Only use onCleanup in component setup");
19
+ throw new Error("Only use createCleanup in component setup");
20
20
  }
21
21
  currentComponent.onCleanups.push(cb);
22
22
  }
@@ -1,4 +1,4 @@
1
- import { getCurrentComponent, onCleanup } from "./component";
1
+ import { getCurrentComponent, createCleanup } from "./component";
2
2
  import { getCurrentObserver, Observer, Signal } from "./observation";
3
3
  export function createComputed(computed) {
4
4
  let currentComponent;
@@ -18,7 +18,7 @@ export function createComputed(computed) {
18
18
  signal.notify();
19
19
  });
20
20
  if (currentComponent) {
21
- onCleanup(() => computedObserver.dispose());
21
+ createCleanup(() => computedObserver.dispose());
22
22
  }
23
23
  Object.defineProperty(proxy, prop, {
24
24
  get() {
@@ -1,4 +1,4 @@
1
- import { getCurrentComponent, onCleanup } from "./component";
1
+ import { getCurrentComponent, createCleanup } from "./component";
2
2
  import { Observer } from "./observation";
3
3
  export function createEffect(cb) {
4
4
  let currentComponent;
@@ -19,7 +19,7 @@ export function createEffect(cb) {
19
19
  stopObserving();
20
20
  };
21
21
  if (currentComponent) {
22
- onCleanup(() => observer.dispose());
22
+ createCleanup(() => observer.dispose());
23
23
  }
24
24
  runEffect();
25
25
  }
@@ -0,0 +1,30 @@
1
+ export type Task<T, P> = {
2
+ isRunning: false;
3
+ params: null;
4
+ result: null;
5
+ error: null;
6
+ } | {
7
+ isRunning: true;
8
+ result: T | null;
9
+ params: P;
10
+ error: null;
11
+ } | {
12
+ isRunning: false;
13
+ params: null;
14
+ result: T;
15
+ error: null;
16
+ } | {
17
+ isRunning: false;
18
+ params: null;
19
+ result: null;
20
+ error: string;
21
+ };
22
+ export declare function createTask<T>(task: () => Promise<T>): Task<T, never> & {
23
+ run(): Promise<T>;
24
+ rerun(): Promise<T>;
25
+ };
26
+ export declare function createTask<T, P>(task: (params: P) => Promise<T>): Task<T, P> & {
27
+ run(params: P): Promise<T>;
28
+ rerun(params: P): Promise<T>;
29
+ };
30
+ //# sourceMappingURL=createTask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTask.d.ts","sourceRoot":"","sources":["../src/createTask.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,IACjB;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,IAAI,CAAC;CACb,GACD;IACE,SAAS,EAAE,KAAK,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG;IACtE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACrB,CAAC;AACF,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAC9B,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IACd,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3B,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9B,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { createState } from "./createState";
2
+ export function createTask(task) {
3
+ const state = createState({
4
+ isRunning: false,
5
+ result: null,
6
+ error: null,
7
+ params: null,
8
+ });
9
+ const assign = (newState) => {
10
+ Object.assign(state, newState);
11
+ };
12
+ let currentAbortController;
13
+ const fetch = (params) => {
14
+ currentAbortController?.abort();
15
+ const abortController = (currentAbortController = new AbortController());
16
+ const promise = task(params);
17
+ promise
18
+ .then((result) => {
19
+ if (abortController.signal.aborted) {
20
+ return;
21
+ }
22
+ assign({
23
+ isRunning: false,
24
+ result,
25
+ error: null,
26
+ params: null,
27
+ });
28
+ })
29
+ .catch((error) => {
30
+ if (abortController.signal.aborted) {
31
+ return;
32
+ }
33
+ assign({
34
+ isRunning: false,
35
+ result: null,
36
+ error: String(error),
37
+ params: null,
38
+ });
39
+ });
40
+ return promise;
41
+ };
42
+ fetch();
43
+ return {
44
+ get isRunning() {
45
+ return state.isRunning;
46
+ },
47
+ get result() {
48
+ return state.result;
49
+ },
50
+ get error() {
51
+ return state.error;
52
+ },
53
+ get params() {
54
+ return state.params;
55
+ },
56
+ run(params) {
57
+ const promise = fetch(params);
58
+ assign({
59
+ isRunning: true,
60
+ result: null,
61
+ error: null,
62
+ params: (params || null),
63
+ });
64
+ return promise;
65
+ },
66
+ rerun(params) {
67
+ const promise = fetch(params);
68
+ assign({
69
+ isRunning: true,
70
+ result: state.result,
71
+ error: null,
72
+ params: (params || null),
73
+ });
74
+ return promise;
75
+ },
76
+ };
77
+ }
package/dist/index.d.ts CHANGED
@@ -1,14 +1,13 @@
1
1
  export { render } from "./render";
2
- export { onCleanup, onMount, RaskComponent } from "./component";
2
+ export { createCleanup, createMountEffect, RaskComponent } from "./component";
3
3
  export { createContext } from "./createContext";
4
4
  export { createState } from "./createState";
5
- export { createAsync } from "./createAsync";
5
+ export { createTask } from "./createTask";
6
6
  export { ErrorBoundary } from "./error";
7
- export { createQuery } from "./createQuery";
8
- export { createMutation } from "./createMutation";
9
7
  export { createRef } from "inferno";
10
8
  export { createView } from "./createView";
11
9
  export { createEffect } from "./createEffect";
12
10
  export { createComputed } from "./createComputed";
13
11
  export { syncBatch } from "./batch";
12
+ export { createVNode, createComponentVNode, createFragment, createTextVNode, normalizeProps, } from "inferno";
14
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  export { render } from "./render";
2
- export { onCleanup, onMount, RaskComponent } from "./component";
2
+ export { createCleanup, createMountEffect, RaskComponent } from "./component";
3
3
  export { createContext } from "./createContext";
4
4
  export { createState } from "./createState";
5
- export { createAsync } from "./createAsync";
5
+ export { createTask } from "./createTask";
6
6
  export { ErrorBoundary } from "./error";
7
- export { createQuery } from "./createQuery";
8
- export { createMutation } from "./createMutation";
9
7
  export { createRef } from "inferno";
10
8
  export { createView } from "./createView";
11
9
  export { createEffect } from "./createEffect";
12
10
  export { createComputed } from "./createComputed";
13
11
  export { syncBatch } from "./batch";
12
+ // Re-export Inferno JSX runtime functions so users don't need to install Inferno directly
13
+ export { createVNode, createComponentVNode, createFragment, createTextVNode, normalizeProps, } from "inferno";
package/dist/plugin.d.ts CHANGED
@@ -7,7 +7,7 @@ export interface RaskPluginOptions {
7
7
  transformComponents?: boolean;
8
8
  /**
9
9
  * Import source for Inferno imports
10
- * @default false (no imports added)
10
+ * @default true (imports from rask-ui)
11
11
  */
12
12
  imports?: boolean;
13
13
  /**
package/dist/plugin.js CHANGED
@@ -8,7 +8,7 @@ const require = createRequire(import.meta.url);
8
8
  * Vite plugin for transforming JSX to Inferno and function components to RaskComponent classes
9
9
  */
10
10
  export function raskPlugin(options = {}) {
11
- const { transformComponents = true, imports = false, importSource = 'rask-ui', defineAllArguments = false, } = options;
11
+ const { transformComponents = true, imports = true, importSource = 'rask-ui', defineAllArguments = false, } = options;
12
12
  // Resolve the path to swc-plugin-inferno WASM file
13
13
  const infernoPluginPath = require.resolve('swc-plugin-inferno/swc_plugin_inferno.wasm');
14
14
  // Resolve the path to our RaskComponent plugin
package/logo.png ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rask-ui",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -25,10 +25,11 @@
25
25
  "files": [
26
26
  "dist",
27
27
  "swc-plugin",
28
+ "logo.png",
28
29
  "README.md"
29
30
  ],
30
31
  "scripts": {
31
- "build": "npm run build:plugin && tsc && cp ../../README.md .",
32
+ "build": "npm run build:plugin && tsc && cp ../../README.md . && cp ../../logo.png .",
32
33
  "build:plugin": "cd swc-plugin && cargo build --release --target wasm32-wasip1",
33
34
  "dev": "tsc --watch",
34
35
  "test": "vitest",
@@ -1 +1 @@
1
- /Users/christianalfoni/Development/snabbdom-components/packages/core/swc-plugin/target/wasm32-wasip1/release/libswc_plugin_rask_component.rlib: /Users/christianalfoni/Development/snabbdom-components/packages/core/swc-plugin/src/lib.rs
1
+ /Users/christianalfoni/Development/rask-ui/packages/core/swc-plugin/target/wasm32-wasip1/release/libswc_plugin_rask_component.rlib: /Users/christianalfoni/Development/rask-ui/packages/core/swc-plugin/src/lib.rs
@@ -1 +1 @@
1
- /Users/christianalfoni/Development/snabbdom-components/packages/core/swc-plugin/target/wasm32-wasip1/release/swc_plugin_rask_component.wasm: /Users/christianalfoni/Development/snabbdom-components/packages/core/swc-plugin/src/lib.rs
1
+ /Users/christianalfoni/Development/rask-ui/packages/core/swc-plugin/target/wasm32-wasip1/release/swc_plugin_rask_component.wasm: /Users/christianalfoni/Development/rask-ui/packages/core/swc-plugin/src/lib.rs