@arcanejs/react-toolkit 0.6.0 → 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/dist/data.d.mts CHANGED
@@ -24,6 +24,20 @@ type ProviderProps = DataFileUsage & {
24
24
  type DataFileUpdater<T> = (update: (current: T) => T) => void;
25
25
  type DataFileContext<T> = {
26
26
  data: T;
27
+ /**
28
+ * Last timestamp where {@link DataFileContext.data data} was updated
29
+ * in-memory.
30
+ *
31
+ * **Note: This is not the last time the data was saved to disk.**
32
+ * More specifically:
33
+ * - If the data has been loaded from disk and not changed,
34
+ * then this will be the timestamp that it was loaded from disk.
35
+ * - If the data has been updated since first loaded into memory,
36
+ * then this will be the timestamp of the last update.
37
+ *
38
+ * Uses the local timestamp in milliseconds, i.e. `Date.now()`.
39
+ */
40
+ lastUpdatedMillis: number;
27
41
  updateData: DataFileUpdater<T>;
28
42
  /**
29
43
  * Can be called to force an attempt to re-save the data to disk
@@ -54,6 +68,8 @@ declare function useDataFileContext<T>(dataFile: DataFileDefinition<T>): DataFil
54
68
  */
55
69
  declare function useDataFile<T>(dataFile: DataFileDefinition<T>, usage: DataFileUsage): DataFileCore<T>;
56
70
  type DataState<T> = {
71
+ lastUpdatedMillis: number;
72
+ } & ({
57
73
  status: 'loading';
58
74
  /**
59
75
  * The data is not yet loaded, so this will be undefined,
@@ -72,7 +88,7 @@ type DataState<T> = {
72
88
  } | {
73
89
  status: 'ready';
74
90
  data: T;
75
- };
91
+ });
76
92
  type UseDataFileCoreProps<T> = WithPathChange & {
77
93
  schema: ZodType<T>;
78
94
  defaultValue: T;
package/dist/data.d.ts CHANGED
@@ -24,6 +24,20 @@ type ProviderProps = DataFileUsage & {
24
24
  type DataFileUpdater<T> = (update: (current: T) => T) => void;
25
25
  type DataFileContext<T> = {
26
26
  data: T;
27
+ /**
28
+ * Last timestamp where {@link DataFileContext.data data} was updated
29
+ * in-memory.
30
+ *
31
+ * **Note: This is not the last time the data was saved to disk.**
32
+ * More specifically:
33
+ * - If the data has been loaded from disk and not changed,
34
+ * then this will be the timestamp that it was loaded from disk.
35
+ * - If the data has been updated since first loaded into memory,
36
+ * then this will be the timestamp of the last update.
37
+ *
38
+ * Uses the local timestamp in milliseconds, i.e. `Date.now()`.
39
+ */
40
+ lastUpdatedMillis: number;
27
41
  updateData: DataFileUpdater<T>;
28
42
  /**
29
43
  * Can be called to force an attempt to re-save the data to disk
@@ -54,6 +68,8 @@ declare function useDataFileContext<T>(dataFile: DataFileDefinition<T>): DataFil
54
68
  */
55
69
  declare function useDataFile<T>(dataFile: DataFileDefinition<T>, usage: DataFileUsage): DataFileCore<T>;
56
70
  type DataState<T> = {
71
+ lastUpdatedMillis: number;
72
+ } & ({
57
73
  status: 'loading';
58
74
  /**
59
75
  * The data is not yet loaded, so this will be undefined,
@@ -72,7 +88,7 @@ type DataState<T> = {
72
88
  } | {
73
89
  status: 'ready';
74
90
  data: T;
75
- };
91
+ });
76
92
  type UseDataFileCoreProps<T> = WithPathChange & {
77
93
  schema: ZodType<T>;
78
94
  defaultValue: T;
package/dist/data.js CHANGED
@@ -39,6 +39,7 @@ function useDataFileCore({
39
39
  path: null,
40
40
  data: void 0,
41
41
  previousData: void 0,
42
+ lastUpdatedMillis: Date.now(),
42
43
  state: {
43
44
  state: "saved"
44
45
  }
@@ -53,6 +54,7 @@ function useDataFileCore({
53
54
  }
54
55
  }, [schema, defaultValue]);
55
56
  const [data, setData] = _react.useState.call(void 0, {
57
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
56
58
  status: "loading",
57
59
  data: void 0
58
60
  });
@@ -61,6 +63,7 @@ function useDataFileCore({
61
63
  const data2 = state.current.data;
62
64
  if (state.current.state.state === "error") {
63
65
  setData({
66
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
64
67
  status: "error",
65
68
  error: state.current.state.error,
66
69
  data: data2
@@ -69,12 +72,14 @@ function useDataFileCore({
69
72
  }
70
73
  if (data2 === void 0) {
71
74
  setData({
75
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
72
76
  status: "loading",
73
77
  data: void 0
74
78
  });
75
79
  return;
76
80
  }
77
81
  setData({
82
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
78
83
  status: "ready",
79
84
  data: data2
80
85
  });
@@ -131,6 +136,7 @@ function useDataFileCore({
131
136
  const parsedData = schema.parse(JSON.parse(data2));
132
137
  if (state.current.path === path) {
133
138
  state.current.data = parsedData;
139
+ state.current.lastUpdatedMillis = Date.now();
134
140
  state.current.state = { state: "saved" };
135
141
  updateDataFromState();
136
142
  }
@@ -141,6 +147,7 @@ function useDataFileCore({
141
147
  if (error.code === "ENOENT") {
142
148
  const initialData = onPathChange === "transfer" && state.current.previousData !== void 0 ? state.current.previousData : defaultValue;
143
149
  state.current.data = initialData;
150
+ state.current.lastUpdatedMillis = Date.now();
144
151
  state.current.state = { state: "dirty" };
145
152
  _optionalChain([log, 'optionalAccess', _ => _.info, 'call', _2 => _2(
146
153
  "Creating a new file at %s with initial data %o",
@@ -164,6 +171,7 @@ function useDataFileCore({
164
171
  throw new Error("Attempt to update data before it has been loaded");
165
172
  }
166
173
  state.current.data = update(state.current.data);
174
+ state.current.lastUpdatedMillis = Date.now();
167
175
  state.current.state = { state: "dirty" };
168
176
  saveData();
169
177
  updateDataFromState();
@@ -182,6 +190,7 @@ function createDataFileDefinition({
182
190
  }) {
183
191
  const context = _react.createContext.call(void 0, {
184
192
  data: defaultValue,
193
+ lastUpdatedMillis: Date.now(),
185
194
  updateData: () => {
186
195
  throw new Error("Data file provider not used");
187
196
  },
@@ -207,6 +216,7 @@ function createDataFileDefinition({
207
216
  const providedContext = _react.useMemo.call(void 0,
208
217
  () => ({
209
218
  data: data.status !== "loading" && data.data !== void 0 ? data.data : defaultValue,
219
+ lastUpdatedMillis: data.lastUpdatedMillis,
210
220
  updateData,
211
221
  saveData,
212
222
  error: data.status === "error" ? data.error : void 0
package/dist/data.mjs CHANGED
@@ -39,6 +39,7 @@ function useDataFileCore({
39
39
  path: null,
40
40
  data: void 0,
41
41
  previousData: void 0,
42
+ lastUpdatedMillis: Date.now(),
42
43
  state: {
43
44
  state: "saved"
44
45
  }
@@ -53,6 +54,7 @@ function useDataFileCore({
53
54
  }
54
55
  }, [schema, defaultValue]);
55
56
  const [data, setData] = useState({
57
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
56
58
  status: "loading",
57
59
  data: void 0
58
60
  });
@@ -61,6 +63,7 @@ function useDataFileCore({
61
63
  const data2 = state.current.data;
62
64
  if (state.current.state.state === "error") {
63
65
  setData({
66
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
64
67
  status: "error",
65
68
  error: state.current.state.error,
66
69
  data: data2
@@ -69,12 +72,14 @@ function useDataFileCore({
69
72
  }
70
73
  if (data2 === void 0) {
71
74
  setData({
75
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
72
76
  status: "loading",
73
77
  data: void 0
74
78
  });
75
79
  return;
76
80
  }
77
81
  setData({
82
+ lastUpdatedMillis: state.current.lastUpdatedMillis,
78
83
  status: "ready",
79
84
  data: data2
80
85
  });
@@ -131,6 +136,7 @@ function useDataFileCore({
131
136
  const parsedData = schema.parse(JSON.parse(data2));
132
137
  if (state.current.path === path) {
133
138
  state.current.data = parsedData;
139
+ state.current.lastUpdatedMillis = Date.now();
134
140
  state.current.state = { state: "saved" };
135
141
  updateDataFromState();
136
142
  }
@@ -141,6 +147,7 @@ function useDataFileCore({
141
147
  if (error.code === "ENOENT") {
142
148
  const initialData = onPathChange === "transfer" && state.current.previousData !== void 0 ? state.current.previousData : defaultValue;
143
149
  state.current.data = initialData;
150
+ state.current.lastUpdatedMillis = Date.now();
144
151
  state.current.state = { state: "dirty" };
145
152
  log?.info(
146
153
  "Creating a new file at %s with initial data %o",
@@ -164,6 +171,7 @@ function useDataFileCore({
164
171
  throw new Error("Attempt to update data before it has been loaded");
165
172
  }
166
173
  state.current.data = update(state.current.data);
174
+ state.current.lastUpdatedMillis = Date.now();
167
175
  state.current.state = { state: "dirty" };
168
176
  saveData();
169
177
  updateDataFromState();
@@ -182,6 +190,7 @@ function createDataFileDefinition({
182
190
  }) {
183
191
  const context = createContext({
184
192
  data: defaultValue,
193
+ lastUpdatedMillis: Date.now(),
185
194
  updateData: () => {
186
195
  throw new Error("Data file provider not used");
187
196
  },
@@ -207,6 +216,7 @@ function createDataFileDefinition({
207
216
  const providedContext = useMemo(
208
217
  () => ({
209
218
  data: data.status !== "loading" && data.data !== void 0 ? data.data : defaultValue,
219
+ lastUpdatedMillis: data.lastUpdatedMillis,
210
220
  updateData,
211
221
  saveData,
212
222
  error: data.status === "error" ? data.error : void 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcanejs/react-toolkit",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "description": "Build web-accessible control interfaces for your long-running Node.js processes",
6
6
  "keywords": [
@@ -56,15 +56,15 @@
56
56
  "tsup": "^8.1.0",
57
57
  "typescript": "^5.3.3",
58
58
  "zod": "^3.23.8",
59
- "@arcanejs/eslint-config": "^0.0.0",
60
- "@arcanejs/typescript-config": "^0.0.0"
59
+ "@arcanejs/typescript-config": "^0.0.0",
60
+ "@arcanejs/eslint-config": "^0.0.0"
61
61
  },
62
62
  "dependencies": {
63
63
  "lodash": "^4.17.21",
64
64
  "react": "^18",
65
65
  "react-reconciler": "0.28.0",
66
66
  "@arcanejs/protocol": "^0.3.0",
67
- "@arcanejs/toolkit": "^0.5.0"
67
+ "@arcanejs/toolkit": "^0.5.1"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "zod": "^3.23.8"