@isograph/react-disposable-state 0.0.4 → 0.1.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/CacheItem.d.ts +18 -14
- package/dist/CacheItem.js +65 -61
- package/dist/ParentCache.d.ts +2 -2
- package/dist/ParentCache.js +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/useCachedPrecommitValue.d.ts +2 -2
- package/dist/useCachedPrecommitValue.js +1 -1
- package/dist/useDisposableState.d.ts +3 -3
- package/dist/useDisposableState.js +6 -4
- package/dist/useHasCommittedRef.d.ts +1 -1
- package/dist/useLazyDisposableState.d.ts +1 -1
- package/dist/useLazyDisposableState.js +3 -3
- package/dist/useUpdatableDisposableState.d.ts +1 -1
- package/dist/useUpdatableDisposableState.js +3 -3
- package/docs/managing-complex-state.md +4 -4
- package/package.json +7 -2
- package/src/CacheItem.test.ts +94 -94
- package/src/CacheItem.ts +80 -76
- package/src/ParentCache.test.ts +31 -27
- package/src/ParentCache.ts +3 -3
- package/src/index.ts +8 -8
- package/src/useCachedPrecommitValue.test.tsx +57 -73
- package/src/useCachedPrecommitValue.ts +7 -7
- package/src/useDisposableState.ts +13 -11
- package/src/useHasCommittedRef.ts +1 -1
- package/src/useLazyDisposableState.ts +7 -7
- package/src/useUpdatableDisposableState.test.tsx +334 -327
- package/src/useUpdatableDisposableState.ts +9 -9
package/dist/CacheItem.d.ts
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
import { CleanupFn, Factory, ItemCleanupPair } from
|
1
|
+
import { CleanupFn, Factory, ItemCleanupPair } from '@isograph/disposable-types';
|
2
2
|
export type NotInParentCacheAndDisposed = {
|
3
|
-
kind:
|
3
|
+
kind: 'NotInParentCacheAndDisposed';
|
4
4
|
};
|
5
5
|
export type NotInParentCacheAndNotDisposed<T> = {
|
6
|
-
kind:
|
6
|
+
kind: 'NotInParentCacheAndNotDisposed';
|
7
7
|
value: T;
|
8
8
|
disposeValue: () => void;
|
9
9
|
permanentRetainCount: number;
|
10
10
|
};
|
11
11
|
export type InParentCacheAndNotDisposed<T> = {
|
12
|
-
kind:
|
12
|
+
kind: 'InParentCacheAndNotDisposed';
|
13
13
|
value: T;
|
14
14
|
disposeValue: () => void;
|
15
15
|
removeFromParentCache: () => void;
|
@@ -21,21 +21,25 @@ export type CacheItemOptions = {
|
|
21
21
|
temporaryRetainTime: number;
|
22
22
|
};
|
23
23
|
/**
|
24
|
+
* CacheItem:
|
25
|
+
*
|
26
|
+
* Terminology:
|
24
27
|
* - TRC = Temporary Retain Count
|
25
28
|
* - PRC = Permanent Retain Count
|
26
29
|
*
|
27
|
-
* Rules:
|
28
|
-
* - In parent cache <=> TRC > 0
|
29
|
-
* - Removed from parent cache <=> TRC === 0
|
30
|
-
* - In parent cache => not disposed
|
31
|
-
* - Disposed => removed from parent cache + PRC === 0
|
32
|
-
*
|
33
30
|
* A CacheItem<T> can be in three states:
|
34
|
-
*
|
35
|
-
*
|
36
|
-
*
|
31
|
+
* In parent cache? | Item disposed? | TRC | PRC | Name
|
32
|
+
* -----------------+----------------+-----+-----+-------------------------------
|
33
|
+
* In parent cache | Not disposed | >0 | >=0 | InParentCacheAndNotDisposed
|
34
|
+
* Removed | Not disposed | 0 | >0 | NotInParentCacheAndNotDisposed
|
35
|
+
* Removed | Disposed | 0 | 0 | NotInParentCacheAndNotDisposed
|
36
|
+
*
|
37
|
+
* A cache item can only move down rows. As in, if its in the parent cache,
|
38
|
+
* it can be removed. It can never be replaced in the parent cache. (If a
|
39
|
+
* parent cache becomes full again, it will contain a new CacheItem.) The
|
40
|
+
* contained item can be disposed, but never un-disposed.
|
37
41
|
*
|
38
|
-
*
|
42
|
+
* So, the valid transitions are:
|
39
43
|
* - InParentCacheAndNotDisposed => NotInParentCacheAndNotDisposed
|
40
44
|
* - InParentCacheAndNotDisposed => NotInParentCacheAndDisposed
|
41
45
|
* - NotInParentCacheAndNotDisposed => NotInParentCacheAndDisposed
|
package/dist/CacheItem.js
CHANGED
@@ -5,21 +5,25 @@ const DEFAULT_TEMPORARY_RETAIN_TIME = 5000;
|
|
5
5
|
// TODO don't export this class, only export type (interface) instead
|
6
6
|
// TODO convert cacheitem impl to a getter and setter and free functions
|
7
7
|
/**
|
8
|
+
* CacheItem:
|
9
|
+
*
|
10
|
+
* Terminology:
|
8
11
|
* - TRC = Temporary Retain Count
|
9
12
|
* - PRC = Permanent Retain Count
|
10
13
|
*
|
11
|
-
* Rules:
|
12
|
-
* - In parent cache <=> TRC > 0
|
13
|
-
* - Removed from parent cache <=> TRC === 0
|
14
|
-
* - In parent cache => not disposed
|
15
|
-
* - Disposed => removed from parent cache + PRC === 0
|
16
|
-
*
|
17
14
|
* A CacheItem<T> can be in three states:
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
15
|
+
* In parent cache? | Item disposed? | TRC | PRC | Name
|
16
|
+
* -----------------+----------------+-----+-----+-------------------------------
|
17
|
+
* In parent cache | Not disposed | >0 | >=0 | InParentCacheAndNotDisposed
|
18
|
+
* Removed | Not disposed | 0 | >0 | NotInParentCacheAndNotDisposed
|
19
|
+
* Removed | Disposed | 0 | 0 | NotInParentCacheAndNotDisposed
|
20
|
+
*
|
21
|
+
* A cache item can only move down rows. As in, if its in the parent cache,
|
22
|
+
* it can be removed. It can never be replaced in the parent cache. (If a
|
23
|
+
* parent cache becomes full again, it will contain a new CacheItem.) The
|
24
|
+
* contained item can be disposed, but never un-disposed.
|
21
25
|
*
|
22
|
-
*
|
26
|
+
* So, the valid transitions are:
|
23
27
|
* - InParentCacheAndNotDisposed => NotInParentCacheAndNotDisposed
|
24
28
|
* - InParentCacheAndNotDisposed => NotInParentCacheAndDisposed
|
25
29
|
* - NotInParentCacheAndNotDisposed => NotInParentCacheAndDisposed
|
@@ -34,7 +38,7 @@ class CacheItem {
|
|
34
38
|
this.__options = options !== null && options !== void 0 ? options : null;
|
35
39
|
const [value, disposeValue] = factory();
|
36
40
|
this.__state = {
|
37
|
-
kind:
|
41
|
+
kind: 'InParentCacheAndNotDisposed',
|
38
42
|
value,
|
39
43
|
disposeValue,
|
40
44
|
removeFromParentCache,
|
@@ -46,21 +50,21 @@ class CacheItem {
|
|
46
50
|
}
|
47
51
|
getValue() {
|
48
52
|
switch (this.__state.kind) {
|
49
|
-
case
|
53
|
+
case 'InParentCacheAndNotDisposed': {
|
50
54
|
return this.__state.value;
|
51
55
|
}
|
52
|
-
case
|
56
|
+
case 'NotInParentCacheAndNotDisposed': {
|
53
57
|
return this.__state.value;
|
54
58
|
}
|
55
59
|
default: {
|
56
|
-
throw new Error(
|
57
|
-
|
60
|
+
throw new Error('Attempted to access disposed value from CacheItem. ' +
|
61
|
+
'This indicates a bug in react-disposable-state.');
|
58
62
|
}
|
59
63
|
}
|
60
64
|
}
|
61
65
|
permanentRetainIfNotDisposed(disposeOfTemporaryRetain) {
|
62
66
|
switch (this.__state.kind) {
|
63
|
-
case
|
67
|
+
case 'InParentCacheAndNotDisposed': {
|
64
68
|
let cleared = false;
|
65
69
|
this.__state.permanentRetainCount++;
|
66
70
|
disposeOfTemporaryRetain();
|
@@ -68,30 +72,30 @@ class CacheItem {
|
|
68
72
|
this.__state.value,
|
69
73
|
() => {
|
70
74
|
if (cleared) {
|
71
|
-
throw new Error(
|
72
|
-
|
75
|
+
throw new Error('A permanent retain should only be cleared once. ' +
|
76
|
+
'This indicates a bug in react-disposable-state.');
|
73
77
|
}
|
74
78
|
cleared = true;
|
75
79
|
switch (this.__state.kind) {
|
76
|
-
case
|
80
|
+
case 'InParentCacheAndNotDisposed': {
|
77
81
|
this.__state.permanentRetainCount--;
|
78
82
|
this.__maybeExitInParentCacheAndNotDisposedState(this.__state);
|
79
83
|
return;
|
80
84
|
}
|
81
|
-
case
|
85
|
+
case 'NotInParentCacheAndNotDisposed': {
|
82
86
|
this.__state.permanentRetainCount--;
|
83
87
|
this.__maybeExitNotInParentCacheAndNotDisposedState(this.__state);
|
84
88
|
return;
|
85
89
|
}
|
86
90
|
default: {
|
87
|
-
throw new Error(
|
88
|
-
|
91
|
+
throw new Error('CacheItem was in a disposed state, but there existed a permanent retain. ' +
|
92
|
+
'This indicates a bug in react-disposable-state.');
|
89
93
|
}
|
90
94
|
}
|
91
95
|
},
|
92
96
|
];
|
93
97
|
}
|
94
|
-
case
|
98
|
+
case 'NotInParentCacheAndNotDisposed': {
|
95
99
|
let cleared = false;
|
96
100
|
this.__state.permanentRetainCount++;
|
97
101
|
disposeOfTemporaryRetain();
|
@@ -99,19 +103,19 @@ class CacheItem {
|
|
99
103
|
this.__state.value,
|
100
104
|
() => {
|
101
105
|
if (cleared) {
|
102
|
-
throw new Error(
|
103
|
-
|
106
|
+
throw new Error('A permanent retain should only be cleared once. ' +
|
107
|
+
'This indicates a bug in react-disposable-state.');
|
104
108
|
}
|
105
109
|
cleared = true;
|
106
110
|
switch (this.__state.kind) {
|
107
|
-
case
|
111
|
+
case 'NotInParentCacheAndNotDisposed': {
|
108
112
|
this.__state.permanentRetainCount--;
|
109
113
|
this.__maybeExitNotInParentCacheAndNotDisposedState(this.__state);
|
110
114
|
return;
|
111
115
|
}
|
112
116
|
default: {
|
113
|
-
throw new Error(
|
114
|
-
|
117
|
+
throw new Error('CacheItem was in an unexpected state. ' +
|
118
|
+
'This indicates a bug in react-disposable-state.');
|
115
119
|
}
|
116
120
|
}
|
117
121
|
},
|
@@ -126,40 +130,40 @@ class CacheItem {
|
|
126
130
|
temporaryRetain() {
|
127
131
|
var _a, _b;
|
128
132
|
switch (this.__state.kind) {
|
129
|
-
case
|
130
|
-
let status =
|
133
|
+
case 'InParentCacheAndNotDisposed': {
|
134
|
+
let status = 'Uncleared';
|
131
135
|
this.__state.temporaryRetainCount++;
|
132
136
|
const clearTemporaryRetainByCallack = () => {
|
133
|
-
if (status ===
|
134
|
-
throw new Error(
|
135
|
-
|
137
|
+
if (status === 'ClearedByCallback') {
|
138
|
+
throw new Error('A temporary retain should only be cleared once. ' +
|
139
|
+
'This indicates a bug in react-disposable-state.');
|
136
140
|
}
|
137
|
-
else if (status ===
|
141
|
+
else if (status === 'Uncleared') {
|
138
142
|
switch (this.__state.kind) {
|
139
|
-
case
|
143
|
+
case 'InParentCacheAndNotDisposed': {
|
140
144
|
this.__state.temporaryRetainCount--;
|
141
145
|
this.__maybeExitInParentCacheAndNotDisposedState(this.__state);
|
142
146
|
clearTimeout(timeoutId);
|
143
147
|
return;
|
144
148
|
}
|
145
149
|
default: {
|
146
|
-
throw new Error(
|
147
|
-
|
150
|
+
throw new Error('A temporary retain was cleared, for which the CacheItem is in an invalid state. ' +
|
151
|
+
'This indicates a bug in react-disposable-state.');
|
148
152
|
}
|
149
153
|
}
|
150
154
|
}
|
151
155
|
};
|
152
156
|
const clearTemporaryRetainByTimeout = () => {
|
153
|
-
status =
|
157
|
+
status = 'ClearedByTimeout';
|
154
158
|
switch (this.__state.kind) {
|
155
|
-
case
|
159
|
+
case 'InParentCacheAndNotDisposed': {
|
156
160
|
this.__state.temporaryRetainCount--;
|
157
161
|
this.__maybeExitInParentCacheAndNotDisposedState(this.__state);
|
158
162
|
return;
|
159
163
|
}
|
160
164
|
default: {
|
161
|
-
throw new Error(
|
162
|
-
|
165
|
+
throw new Error('A temporary retain was cleared, for which the CacheItem is in an invalid state. ' +
|
166
|
+
'This indicates a bug in react-disposable-state.');
|
163
167
|
}
|
164
168
|
}
|
165
169
|
};
|
@@ -167,65 +171,65 @@ class CacheItem {
|
|
167
171
|
return clearTemporaryRetainByCallack;
|
168
172
|
}
|
169
173
|
default: {
|
170
|
-
throw new Error(
|
171
|
-
|
174
|
+
throw new Error('temporaryRetain was called, for which the CacheItem is in an invalid state. ' +
|
175
|
+
'This indicates a bug in react-disposable-state.');
|
172
176
|
}
|
173
177
|
}
|
174
178
|
}
|
175
179
|
permanentRetain() {
|
176
180
|
switch (this.__state.kind) {
|
177
|
-
case
|
181
|
+
case 'InParentCacheAndNotDisposed': {
|
178
182
|
let cleared = false;
|
179
183
|
this.__state.permanentRetainCount++;
|
180
184
|
return () => {
|
181
185
|
if (cleared) {
|
182
|
-
throw new Error(
|
183
|
-
|
186
|
+
throw new Error('A permanent retain should only be cleared once. ' +
|
187
|
+
'This indicates a bug in react-disposable-state.');
|
184
188
|
}
|
185
189
|
cleared = true;
|
186
190
|
switch (this.__state.kind) {
|
187
|
-
case
|
191
|
+
case 'InParentCacheAndNotDisposed': {
|
188
192
|
this.__state.permanentRetainCount--;
|
189
193
|
this.__maybeExitInParentCacheAndNotDisposedState(this.__state);
|
190
194
|
return;
|
191
195
|
}
|
192
|
-
case
|
196
|
+
case 'NotInParentCacheAndNotDisposed': {
|
193
197
|
this.__state.permanentRetainCount--;
|
194
198
|
this.__maybeExitNotInParentCacheAndNotDisposedState(this.__state);
|
195
199
|
return;
|
196
200
|
}
|
197
201
|
default: {
|
198
|
-
throw new Error(
|
199
|
-
|
202
|
+
throw new Error('CacheItem was in a disposed state, but there existed a permanent retain. ' +
|
203
|
+
'This indicates a bug in react-disposable-state.');
|
200
204
|
}
|
201
205
|
}
|
202
206
|
};
|
203
207
|
}
|
204
|
-
case
|
208
|
+
case 'NotInParentCacheAndNotDisposed': {
|
205
209
|
let cleared = false;
|
206
210
|
this.__state.permanentRetainCount++;
|
207
211
|
return () => {
|
208
212
|
if (cleared) {
|
209
|
-
throw new Error(
|
210
|
-
|
213
|
+
throw new Error('A permanent retain should only be cleared once. ' +
|
214
|
+
'This indicates a bug in react-disposable-state.');
|
211
215
|
}
|
212
216
|
cleared = true;
|
213
217
|
switch (this.__state.kind) {
|
214
|
-
case
|
218
|
+
case 'NotInParentCacheAndNotDisposed': {
|
215
219
|
this.__state.permanentRetainCount--;
|
216
220
|
this.__maybeExitNotInParentCacheAndNotDisposedState(this.__state);
|
217
221
|
return;
|
218
222
|
}
|
219
223
|
default: {
|
220
|
-
throw new Error(
|
221
|
-
|
224
|
+
throw new Error('CacheItem was in an unexpected state. ' +
|
225
|
+
'This indicates a bug in react-disposable-state.');
|
222
226
|
}
|
223
227
|
}
|
224
228
|
};
|
225
229
|
}
|
226
230
|
default: {
|
227
|
-
throw new Error(
|
228
|
-
|
231
|
+
throw new Error('permanentRetain was called, but the CacheItem is in an invalid state. ' +
|
232
|
+
'This indicates a bug in react-disposable-state.');
|
229
233
|
}
|
230
234
|
}
|
231
235
|
}
|
@@ -234,13 +238,13 @@ class CacheItem {
|
|
234
238
|
state.removeFromParentCache();
|
235
239
|
state.disposeValue();
|
236
240
|
this.__state = {
|
237
|
-
kind:
|
241
|
+
kind: 'NotInParentCacheAndDisposed',
|
238
242
|
};
|
239
243
|
}
|
240
244
|
else if (state.temporaryRetainCount === 0) {
|
241
245
|
state.removeFromParentCache();
|
242
246
|
this.__state = {
|
243
|
-
kind:
|
247
|
+
kind: 'NotInParentCacheAndNotDisposed',
|
244
248
|
value: state.value,
|
245
249
|
disposeValue: state.disposeValue,
|
246
250
|
permanentRetainCount: state.permanentRetainCount,
|
@@ -251,7 +255,7 @@ class CacheItem {
|
|
251
255
|
if (state.permanentRetainCount === 0) {
|
252
256
|
state.disposeValue();
|
253
257
|
this.__state = {
|
254
|
-
kind:
|
258
|
+
kind: 'NotInParentCacheAndDisposed',
|
255
259
|
};
|
256
260
|
}
|
257
261
|
}
|
package/dist/ParentCache.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { CacheItem } from
|
2
|
-
import { CleanupFn, Factory, ItemCleanupPair } from
|
1
|
+
import { CacheItem } from './CacheItem';
|
2
|
+
import { CleanupFn, Factory, ItemCleanupPair } from '@isograph/disposable-types';
|
3
3
|
/**
|
4
4
|
* ParentCache
|
5
5
|
* - A ParentCache can be in two states: populated and unpopulated.
|
package/dist/ParentCache.js
CHANGED
@@ -68,7 +68,7 @@ class ParentCache {
|
|
68
68
|
// typescript thinks that cacheItem is any, because it's referenced in the closure.
|
69
69
|
const [cacheItem, disposeTemporaryRetain] = pair;
|
70
70
|
this.__cacheItem = cacheItem;
|
71
|
-
return [cacheItem,
|
71
|
+
return [cacheItem, cacheItem.getValue(), disposeTemporaryRetain];
|
72
72
|
}
|
73
73
|
empty() {
|
74
74
|
this.__cacheItem = null;
|
package/dist/index.d.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
export * from
|
2
|
-
export * from
|
3
|
-
export * from
|
4
|
-
export * from
|
5
|
-
export * from
|
6
|
-
export * from
|
7
|
-
export * from
|
8
|
-
export * from
|
1
|
+
export * from '@isograph/disposable-types';
|
2
|
+
export * from './CacheItem';
|
3
|
+
export * from './ParentCache';
|
4
|
+
export * from './useCachedPrecommitValue';
|
5
|
+
export * from './useDisposableState';
|
6
|
+
export * from './useHasCommittedRef';
|
7
|
+
export * from './useLazyDisposableState';
|
8
|
+
export * from './useUpdatableDisposableState';
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { ParentCache } from
|
2
|
-
import { ItemCleanupPair } from
|
1
|
+
import { ParentCache } from './ParentCache';
|
2
|
+
import { ItemCleanupPair } from '@isograph/isograph-disposable-types/dist';
|
3
3
|
/**
|
4
4
|
* usePrecommitValue<T>
|
5
5
|
* - Takes a mutable parent cache, a factory function, and an onCommit callback.
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import { ParentCache } from
|
2
|
-
import { ItemCleanupPair } from
|
3
|
-
import { UnassignedState } from
|
1
|
+
import { ParentCache } from './ParentCache';
|
2
|
+
import { ItemCleanupPair } from '@isograph/disposable-types';
|
3
|
+
import { UnassignedState } from './useUpdatableDisposableState';
|
4
4
|
type UseUpdatableDisposableStateReturnValue<T> = {
|
5
5
|
state: T;
|
6
6
|
setState: (pair: ItemCleanupPair<Exclude<T, UnassignedState>>) => void;
|
@@ -18,8 +18,8 @@ function useDisposableState(parentCache) {
|
|
18
18
|
itemCleanupPairRef.current = null;
|
19
19
|
}
|
20
20
|
else {
|
21
|
-
throw new Error(
|
22
|
-
|
21
|
+
throw new Error('itemCleanupPairRef.current is unexpectedly null. ' +
|
22
|
+
'This indicates a bug in react-disposable-state.');
|
23
23
|
}
|
24
24
|
}
|
25
25
|
}, [stateFromDisposableStateHook]);
|
@@ -57,12 +57,14 @@ exports.useDisposableState = useDisposableState;
|
|
57
57
|
function tsTests() {
|
58
58
|
let x;
|
59
59
|
const a = useDisposableState(x);
|
60
|
+
// This should be a compiler error, because the generic is inferred to be of
|
61
|
+
// type never. TODO determine why this doesn't break the build!
|
60
62
|
// @ts-expect-error
|
61
|
-
a.setState([
|
63
|
+
a.setState(['asdf', () => { }]);
|
62
64
|
// @ts-expect-error
|
63
65
|
a.setState([useUpdatableDisposableState_1.UNASSIGNED_STATE, () => { }]);
|
64
66
|
const b = useDisposableState(x);
|
65
67
|
// @ts-expect-error
|
66
68
|
b.setState([useUpdatableDisposableState_1.UNASSIGNED_STATE, () => { }]);
|
67
|
-
b.setState([
|
69
|
+
b.setState(['asdf', () => { }]);
|
68
70
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
'use strict';
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.useLazyDisposableState = void 0;
|
4
4
|
const react_1 = require("react");
|
@@ -23,7 +23,7 @@ function useLazyDisposableState(parentCache) {
|
|
23
23
|
const cleanupFn = (_a = itemCleanupPairRef.current) === null || _a === void 0 ? void 0 : _a[1];
|
24
24
|
// TODO confirm useEffect is called in order.
|
25
25
|
if (cleanupFn == null) {
|
26
|
-
throw new Error(
|
26
|
+
throw new Error('cleanupFn unexpectedly null. This indicates a bug in react-disposable-state.');
|
27
27
|
}
|
28
28
|
return cleanupFn;
|
29
29
|
}, []);
|
@@ -34,6 +34,6 @@ function useLazyDisposableState(parentCache) {
|
|
34
34
|
// Safety: This can't happen. For renders before the initial commit, preCommitItem
|
35
35
|
// is non-null. During the initial commit, we assign itemCleanupPairRef.current,
|
36
36
|
// so during subsequent renders, itemCleanupPairRef.current is non-null.
|
37
|
-
throw new Error(
|
37
|
+
throw new Error('returnedItem was unexpectedly null. This indicates a bug in react-disposable-state.');
|
38
38
|
}
|
39
39
|
exports.useLazyDisposableState = useLazyDisposableState;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ItemCleanupPair } from
|
1
|
+
import { ItemCleanupPair } from '@isograph/disposable-types';
|
2
2
|
export declare const UNASSIGNED_STATE: unique symbol;
|
3
3
|
export type UnassignedState = typeof UNASSIGNED_STATE;
|
4
4
|
type UseUpdatableDisposableStateReturnValue<T> = {
|
@@ -41,7 +41,7 @@ function useUpdatableDisposableState() {
|
|
41
41
|
const [stateICI, setStateICI] = (0, react_1.useState)(exports.UNASSIGNED_STATE);
|
42
42
|
const setStateAfterCommit = (0, react_1.useCallback)((itemCleanupPair) => {
|
43
43
|
if (!hasCommittedRef.current) {
|
44
|
-
throw new Error(
|
44
|
+
throw new Error('Calling setState before the component has committed is unsafe and disallowed.');
|
45
45
|
}
|
46
46
|
const ici = {
|
47
47
|
item: itemCleanupPair[0],
|
@@ -84,9 +84,9 @@ function tsTests() {
|
|
84
84
|
// @ts-expect-error
|
85
85
|
a.setState([exports.UNASSIGNED_STATE, () => { }]);
|
86
86
|
// @ts-expect-error
|
87
|
-
a.setState([
|
87
|
+
a.setState(['asdf', () => { }]);
|
88
88
|
const b = useUpdatableDisposableState();
|
89
89
|
// @ts-expect-error
|
90
90
|
b.setState([exports.UNASSIGNED_STATE, () => { }]);
|
91
|
-
b.setState([
|
91
|
+
b.setState(['asdf', () => { }]);
|
92
92
|
}
|
@@ -61,7 +61,7 @@ const addItem2ToState = () => {
|
|
61
61
|
|
62
62
|
// get a new active reference to the existing item1
|
63
63
|
const [item1ActiveReference, disposeItem1ActiveReference] = nullthrows(
|
64
|
-
state[0].cloneIfNotDisposed()
|
64
|
+
state[0].cloneIfNotDisposed(),
|
65
65
|
);
|
66
66
|
setState([item1ActiveReference, item2ActiveReference], () => {
|
67
67
|
disposeItem1ActiveReference();
|
@@ -94,7 +94,7 @@ const removeItem2FromState = () => {
|
|
94
94
|
|
95
95
|
// get a new active reference to the existing item1
|
96
96
|
const [item1ActiveReference, disposeItem1ActiveReference] = nullthrows(
|
97
|
-
state[0].cloneIfNotDisposed()
|
97
|
+
state[0].cloneIfNotDisposed(),
|
98
98
|
);
|
99
99
|
setState([item1ActiveReference], () => {
|
100
100
|
disposeItem1ActiveReference();
|
@@ -133,12 +133,12 @@ For example:
|
|
133
133
|
```ts
|
134
134
|
type MyState =
|
135
135
|
| {
|
136
|
-
kind:
|
136
|
+
kind: 'ConnectedToDatabase';
|
137
137
|
connectionToDatabase: ConnectionToDatabase;
|
138
138
|
currentUserId: number;
|
139
139
|
}
|
140
140
|
| {
|
141
|
-
kind:
|
141
|
+
kind: 'DisconnectedFromDatabase';
|
142
142
|
};
|
143
143
|
```
|
144
144
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@isograph/react-disposable-state",
|
3
|
-
"version": "0.0
|
3
|
+
"version": "0.1.0",
|
4
4
|
"description": "Primitives for managing disposable state in React",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -16,7 +16,7 @@
|
|
16
16
|
"prepack": "yarn run compile"
|
17
17
|
},
|
18
18
|
"dependencies": {
|
19
|
-
"@isograph/disposable-types": "0.0
|
19
|
+
"@isograph/disposable-types": "0.1.0",
|
20
20
|
"react": "^18.2.0"
|
21
21
|
},
|
22
22
|
"devDependencies": {
|
@@ -24,5 +24,10 @@
|
|
24
24
|
"react-test-renderer": "^18.2.0",
|
25
25
|
"vitest": "^0.29.8",
|
26
26
|
"typescript": "^5.0.3"
|
27
|
+
},
|
28
|
+
"repository": {
|
29
|
+
"type": "git",
|
30
|
+
"url": "git+https://github.com/isographlabs/isograph.git",
|
31
|
+
"directory": "libs/isograph-react-disposable-state"
|
27
32
|
}
|
28
33
|
}
|