rask-ui 0.12.1 → 0.12.2

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
@@ -903,13 +903,13 @@ function TodoList() {
903
903
 
904
904
  ```tsx
905
905
  // Task without parameters - auto-runs on creation
906
- createTask<T>(task: () => Promise<T>): Task<T> & {
906
+ createTask<T>(task: (params: undefined, signal: AbortSignal) => Promise<T>): Task<T> & {
907
907
  run(): Promise<T>;
908
908
  rerun(): Promise<T>;
909
909
  }
910
910
 
911
911
  // Task with parameters - manual control
912
- createTask<P, T>(task: (params: P) => Promise<T>): Task<P, T> & {
912
+ createTask<P, T>(task: (params: P, signal: AbortSignal) => Promise<T>): Task<P, T> & {
913
913
  run(params: P): Promise<T>;
914
914
  rerun(params: P): Promise<T>;
915
915
  }
@@ -966,12 +966,82 @@ Error:
966
966
  { isRunning: false, params: null, result: null, error: string }
967
967
  ```
968
968
 
969
+ **Signal Parameter:**
970
+
971
+ The task callback receives an `AbortSignal` as the second parameter. This signal is useful for:
972
+
973
+ - **Passing to fetch requests** - Cancel network requests when the task is aborted
974
+ - **Detecting cancellation** - Check if the task was cancelled after async operations complete
975
+ - **Custom state management** - Detect if the task was rerun and implement your own cleanup logic
976
+
977
+ ```tsx
978
+ function SearchPosts() {
979
+ const state = createState({ query: "" });
980
+
981
+ const search = createTask((query: string, signal: AbortSignal) =>
982
+ fetch(`/api/search?q=${query}`, { signal }).then((r) => r.json())
983
+ );
984
+
985
+ createEffect(() => {
986
+ if (state.query) {
987
+ search.run(state.query);
988
+ }
989
+ });
990
+
991
+ return () => (
992
+ <div>
993
+ <input
994
+ value={state.query}
995
+ onInput={(e) => (state.query = e.target.value)}
996
+ />
997
+ {search.isRunning && <p>Searching...</p>}
998
+ {search.result && (
999
+ <ul>
1000
+ {search.result.map((post) => (
1001
+ <li key={post.id}>{post.title}</li>
1002
+ ))}
1003
+ </ul>
1004
+ )}
1005
+ </div>
1006
+ );
1007
+ }
1008
+
1009
+ // Detecting cancellation for custom state management
1010
+ function CustomStateExample() {
1011
+ const state = createState({ data: null, customLoading: false });
1012
+
1013
+ const task = createTask(async (id: number, signal: AbortSignal) => {
1014
+ state.customLoading = true;
1015
+ const result = await fetch(`/api/data/${id}`).then((r) => r.json());
1016
+
1017
+ // Check if task was cancelled/rerun after the async operation
1018
+ if (signal.aborted) {
1019
+ // Don't update state if the task was cancelled
1020
+ return result;
1021
+ }
1022
+
1023
+ state.data = result;
1024
+ state.customLoading = false;
1025
+ return result;
1026
+ });
1027
+
1028
+ return () => (
1029
+ <div>
1030
+ {state.customLoading && <p>Loading...</p>}
1031
+ {state.data && <p>Data: {JSON.stringify(state.data)}</p>}
1032
+ <button onClick={() => task.run(1)}>Load Data</button>
1033
+ </div>
1034
+ );
1035
+ }
1036
+ ```
1037
+
969
1038
  **Features:**
970
1039
 
971
1040
  - **Automatic cancellation** - Previous executions are cancelled when a new one starts
972
1041
  - **Flexible control** - Use `run()` to clear old data or `rerun()` to keep it during loading
973
1042
  - **Type-safe** - Full TypeScript inference for parameters and results
974
1043
  - **Auto-run support** - Tasks without parameters run automatically on creation
1044
+ - **Signal support** - AbortSignal provided for cancellation detection and request cancellation
975
1045
  - **Generic primitive** - Build your own patterns on top (queries, mutations, etc.)
976
1046
 
977
1047
  **Usage Patterns:**
@@ -26,6 +26,6 @@ export type Task<A, B = never> = [B] extends [never] ? TaskState<null, A> & {
26
26
  run(params: A): Promise<B>;
27
27
  rerun(params: A): Promise<B>;
28
28
  };
29
- export declare function createTask<T>(task: () => Promise<T>): Task<T>;
30
- export declare function createTask<P, T>(task: (params: P) => Promise<T>): Task<P, T>;
29
+ export declare function createTask<T>(task: (params: undefined, signal: AbortSignal) => Promise<T>): Task<T>;
30
+ export declare function createTask<P, T>(task: (params: P, signal: AbortSignal) => Promise<T>): Task<P, T>;
31
31
  //# sourceMappingURL=createTask.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createTask.d.ts","sourceRoot":"","sources":["../src/createTask.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IACtB;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,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAChD,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG;IACnB,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACrB,GACD,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAChB,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;AAEN,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC/D,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"createTask.d.ts","sourceRoot":"","sources":["../src/createTask.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IACtB;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,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAChD,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG;IACnB,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;CACrB,GACD,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAChB,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;AAEN,wBAAgB,UAAU,CAAC,CAAC,EAC1B,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3D,IAAI,CAAC,CAAC,CAAC,CAAC;AACX,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAC7B,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GACnD,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
@@ -10,7 +10,7 @@ export function createTask(task) {
10
10
  const fetch = (params) => {
11
11
  currentAbortController?.abort();
12
12
  const abortController = (currentAbortController = new AbortController());
13
- const promise = task(params);
13
+ const promise = task(params, abortController.signal);
14
14
  promise
15
15
  .then((result) => {
16
16
  if (abortController.signal.aborted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rask-ui",
3
- "version": "0.12.1",
3
+ "version": "0.12.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",