react-smart-crud 0.1.5 → 0.1.7

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/actions.js +31 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-smart-crud",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Minimal optimistic CRUD helper for React without useState, useEffect, or prop drilling",
5
5
  "type": "./src/index.d.ts",
6
6
  "main": "./src/index.js",
package/src/actions.js CHANGED
@@ -3,7 +3,6 @@ import { request } from "./http";
3
3
  import { notify } from "./notify";
4
4
 
5
5
  /* ================= CREATE ================= */
6
-
7
6
  export function createItem(url, data, options = {}) {
8
7
  const entry = getEntry(url);
9
8
 
@@ -30,19 +29,22 @@ export function createItem(url, data, options = {}) {
30
29
  entry.data = entry.data.map((item) =>
31
30
  item._temp ? { ...item, ...serverData, _temp: false } : item
32
31
  );
33
-
32
+ notify("success", "Created", { url, data: serverData });
34
33
  options.onSuccess?.(serverData);
35
34
  })
36
35
  .catch((error) => {
37
36
  // 🔴 rollback
38
37
  entry.data = entry.data.filter((i) => !i._temp);
38
+ notify("error", error.message || "Create failed", {
39
+ url,
40
+ error,
41
+ });
39
42
  options.onError?.(error);
40
43
  })
41
44
  .finally(() => {
42
45
  entry.subscribers.forEach((fn) => fn());
43
46
  });
44
47
  }
45
-
46
48
  /* ================= UPDATE ================= */
47
49
  export function updateItem(url, id, data, options = {}) {
48
50
  const entry = getEntry(url);
@@ -72,32 +74,53 @@ export function updateItem(url, id, data, options = {}) {
72
74
  entry.data = entry.data.map((item) =>
73
75
  item.id === id ? { ...item, ...serverData, _updating: false } : item
74
76
  );
75
-
77
+ notify("success", "Updated", { url, id, data: serverData });
76
78
  options.onSuccess?.(serverData);
77
79
  })
78
80
  .catch((error) => {
79
81
  entry.data = backup;
82
+
83
+ notify("error", error.message || "Update failed", {
84
+ url,
85
+ id,
86
+ error,
87
+ });
88
+
80
89
  options.onError?.(error);
81
90
  })
82
91
  .finally(() => entry.subscribers.forEach((fn) => fn()));
83
92
  }
84
-
85
93
  /* ================= DELETE ================= */
86
94
  export function deleteItem(url, id, options = {}) {
87
95
  const entry = getEntry(url);
88
96
  const backup = [...entry.data];
89
97
 
98
+ // 🟢 Optimistic delete
90
99
  entry.data = entry.data.filter((i) => i.id !== id);
91
100
  entry.subscribers.forEach((fn) => fn());
92
101
 
93
102
  request(`${url}/${id}`, { method: "DELETE" })
94
103
  .then(() => {
95
- options.onSuccess?.();
96
- notify("success", "Deleted");
104
+ if (options.onSuccess) {
105
+ options.onSuccess();
106
+ } else {
107
+ notify("success", "Deleted", { action: "delete", url, id });
108
+ }
97
109
  })
98
110
  .catch((error) => {
111
+ // 🔴 rollback
99
112
  entry.data = backup;
100
113
  entry.subscribers.forEach((fn) => fn());
101
- options.onError?.(error);
114
+
115
+ if (options.onError) {
116
+ options.onError(error);
117
+ } else {
118
+ notify("error", error.message || "Delete failed", {
119
+ action: "delete",
120
+ url,
121
+ id,
122
+ error,
123
+ });
124
+ }
102
125
  });
103
126
  }