use-abcd 0.0.1
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 +93 -0
- package/dist/useCrud.d.ts +139 -0
- package/dist/useCrud.js +2077 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# use-abcd (alpha)
|
|
2
|
+
|
|
3
|
+
[](https://github.com/smtrd3/common-state/actions)
|
|
4
|
+
|
|
5
|
+
A powerful React hook for managing ABCD (or CRUD) operations with optimistic updates, caching, and automatic state management.
|
|
6
|
+
|
|
7
|
+
> **Note on Package Name**: The package is published as `use-abcd` on npm due to naming availability, where ABCD stands for Add, Browse, Change, and Delete - which maps directly to the traditional CRUD (Create, Read, Update, Delete) operations. While the package name uses ABCD, all internal APIs and documentation use CRUD terminology for familiarity and consistency with common programming patterns.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🔄 Automatic state management
|
|
12
|
+
- ⚡ Optimistic updates
|
|
13
|
+
- 🗄️ Built-in caching
|
|
14
|
+
- 🎯 Type-safe
|
|
15
|
+
- 🚫 Automatic error handling
|
|
16
|
+
- ⏳ Debounce support
|
|
17
|
+
- 🔍 Request cancellation
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install use-abcd
|
|
23
|
+
# or
|
|
24
|
+
yarn add use-abcd
|
|
25
|
+
# or
|
|
26
|
+
bun add use-abcd
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Example
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { useCrud } from "use-crud";
|
|
33
|
+
|
|
34
|
+
type Todo = {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string;
|
|
37
|
+
completed: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function TodoList() {
|
|
41
|
+
const { items, isLoading, create, update, remove } = useCrud<Todo>({
|
|
42
|
+
id: "todos",
|
|
43
|
+
context: {},
|
|
44
|
+
// Configure caching (optional)
|
|
45
|
+
caching: {
|
|
46
|
+
capacity: 10,
|
|
47
|
+
age: 60000, // 1 minute
|
|
48
|
+
},
|
|
49
|
+
// Fetch todos from API
|
|
50
|
+
fetch: async ({ signal }) => {
|
|
51
|
+
const response = await fetch("https://api.example.com/todos", { signal });
|
|
52
|
+
const items = await response.json();
|
|
53
|
+
return { items, metadata: {} };
|
|
54
|
+
},
|
|
55
|
+
// Create new todo
|
|
56
|
+
create: async (todo) => {
|
|
57
|
+
const response = await fetch("https://api.example.com/todos", {
|
|
58
|
+
method: "POST",
|
|
59
|
+
body: JSON.stringify(todo),
|
|
60
|
+
});
|
|
61
|
+
const { id } = await response.json();
|
|
62
|
+
return { id };
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
if (isLoading) return <div>Loading...</div>;
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
<button onClick={() => create({ title: "New Todo", completed: false })}>Add Todo</button>
|
|
71
|
+
{items.map((item) => (
|
|
72
|
+
<div key={item.data.id}>
|
|
73
|
+
<span>{item.data.title}</span>
|
|
74
|
+
<button
|
|
75
|
+
onClick={() =>
|
|
76
|
+
update(item.data, (draft) => {
|
|
77
|
+
draft.completed = !draft.completed;
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
>
|
|
81
|
+
Toggle
|
|
82
|
+
</button>
|
|
83
|
+
<button onClick={() => remove(item.data)}>Delete</button>
|
|
84
|
+
</div>
|
|
85
|
+
))}
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
MIT
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
declare type CachedItem = {
|
|
2
|
+
data: unknown;
|
|
3
|
+
ts: number;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export declare type CreateStoreConfig<T extends Item = Item> = {
|
|
7
|
+
id: string;
|
|
8
|
+
initialData?: T[];
|
|
9
|
+
debounce?: number;
|
|
10
|
+
caching?: {
|
|
11
|
+
capacity: number;
|
|
12
|
+
age: number;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export declare type CrudConfig<T extends Item = Item, C = any> = {
|
|
17
|
+
id: string;
|
|
18
|
+
context: C;
|
|
19
|
+
debounce?: number;
|
|
20
|
+
caching?: {
|
|
21
|
+
capacity: number;
|
|
22
|
+
age: number;
|
|
23
|
+
};
|
|
24
|
+
fetch?: FetchFn<T>;
|
|
25
|
+
create?: TransitionFn<T>;
|
|
26
|
+
update?: TransitionFn<T>;
|
|
27
|
+
remove?: TransitionFn<T>;
|
|
28
|
+
getServerSnapshot?: () => StoreState<T>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export declare function customLog(title?: string, ...messages: any[]): void;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Cache implementation for storing and managing fetch results
|
|
35
|
+
* with configurable age and capacity limits.
|
|
36
|
+
*/
|
|
37
|
+
export declare class FetchCache {
|
|
38
|
+
age: number;
|
|
39
|
+
capacity: number;
|
|
40
|
+
storage: Map<string, CachedItem>;
|
|
41
|
+
constructor(age?: number, capacity?: number);
|
|
42
|
+
invalidate(): void;
|
|
43
|
+
reset(age: number, capacity: number): void;
|
|
44
|
+
get(id: string): unknown;
|
|
45
|
+
put(id: string, item: unknown): void;
|
|
46
|
+
remove(id: string): void;
|
|
47
|
+
withCache: (id: string, callback: () => Promise<unknown>) => Promise<unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export declare type FetchFn<T extends Item = Item> = (option: QueryOption) => Promise<{
|
|
51
|
+
items: T[];
|
|
52
|
+
metadata: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
|
|
55
|
+
export declare type Item = {
|
|
56
|
+
id: string;
|
|
57
|
+
} & Record<string, unknown>;
|
|
58
|
+
|
|
59
|
+
export declare type ItemWithState<T extends Item = Item> = {
|
|
60
|
+
data: T;
|
|
61
|
+
state: "create" | "update" | "delete" | "idle" | "error";
|
|
62
|
+
optimistic: boolean;
|
|
63
|
+
errors: string[];
|
|
64
|
+
input?: T;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export declare type QueryOption = {
|
|
68
|
+
signal: AbortSignal;
|
|
69
|
+
context: unknown;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export declare type StoreOptions<T extends Item = Item> = {
|
|
73
|
+
initialData?: T[];
|
|
74
|
+
} & Pick<CrudConfig, "caching" | "debounce">;
|
|
75
|
+
|
|
76
|
+
export declare type StoreState<T extends Item = Item> = {
|
|
77
|
+
fetchState: {
|
|
78
|
+
isLoading: boolean;
|
|
79
|
+
errors: string[];
|
|
80
|
+
metadata?: unknown;
|
|
81
|
+
};
|
|
82
|
+
items: Map<string, ItemWithState<T>>;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export declare type TransitionFn<T extends Item = Item> = (item: Partial<T>, option: QueryOption) => Promise<{
|
|
86
|
+
id: string;
|
|
87
|
+
}>;
|
|
88
|
+
|
|
89
|
+
export declare type Updater<T> = (updatable: T) => void;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Main hook for managing CRUD operations with automatic state management.
|
|
93
|
+
* Provides access to items, metadata, loading states, and CRUD operations.
|
|
94
|
+
* @template T - Type of items to manage, must extend Item base type
|
|
95
|
+
* @template C - Type of context object used in operations
|
|
96
|
+
* @param config - Configuration object for CRUD operations
|
|
97
|
+
* @returns Object containing items, state information, and CRUD operation handlers
|
|
98
|
+
*/
|
|
99
|
+
export declare function useCrud<T extends Item = Item, C extends Record<string, any> = any>(config: CrudConfig<T, C>): {
|
|
100
|
+
itemsById: Map<string, ItemWithState<T>>;
|
|
101
|
+
items: {
|
|
102
|
+
id: string;
|
|
103
|
+
data: T;
|
|
104
|
+
state: "create" | "update" | "delete" | "idle" | "error";
|
|
105
|
+
optimistic: boolean;
|
|
106
|
+
errors: string[];
|
|
107
|
+
input?: T;
|
|
108
|
+
}[];
|
|
109
|
+
metadata: unknown;
|
|
110
|
+
isLoading: boolean;
|
|
111
|
+
hasError: boolean;
|
|
112
|
+
errors: string[];
|
|
113
|
+
create: (item: Omit<T, "id">) => void;
|
|
114
|
+
update: (item: T, updater: Updater<T>, isOptimistic?: boolean) => void;
|
|
115
|
+
remove: (item: T) => void;
|
|
116
|
+
cancelFetch: () => void;
|
|
117
|
+
cancelOperation: (id: string) => void;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Hook that provides CRUD operation handlers for managing items.
|
|
122
|
+
* @template T - Type of items to manage, must extend Item base type
|
|
123
|
+
* @template C - Type of context object used in operations
|
|
124
|
+
* @param config - Configuration object for CRUD operations
|
|
125
|
+
* @returns Object containing CRUD operation handlers and cancellation functions
|
|
126
|
+
*/
|
|
127
|
+
export declare function useCrudOperations<T extends Item = Item, C extends Record<string, any> = any>(config: CrudConfig<T, C>): {
|
|
128
|
+
fetch: () => void;
|
|
129
|
+
refetch: () => void;
|
|
130
|
+
create: (item: Omit<T, "id">) => void;
|
|
131
|
+
update: (item: T, updater: Updater<T>, isOptimistic?: boolean) => void;
|
|
132
|
+
remove: (item: T) => void;
|
|
133
|
+
cancelFetch: () => void;
|
|
134
|
+
cancelOperation: (id: string) => void;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export declare const useMemoDeepEquals: <T>(value: T) => T;
|
|
138
|
+
|
|
139
|
+
export { }
|