@aics/vole-app 2.15.0 → 3.1.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/es/aics-image-viewer/components/App/ChannelUpdater.js +21 -3
- package/es/aics-image-viewer/components/App/index.js +156 -199
- package/es/aics-image-viewer/components/CellViewerCanvasWrapper/index.js +10 -9
- package/es/aics-image-viewer/components/ChannelsWidget.js +35 -22
- package/es/aics-image-viewer/components/ChannelsWidgetRow/index.js +27 -71
- package/es/aics-image-viewer/components/ChannelsWidgetRow/styles.css +0 -6
- package/es/aics-image-viewer/components/ColorPicker.js +1 -1
- package/es/aics-image-viewer/components/ControlPanel/index.js +5 -4
- package/es/aics-image-viewer/components/CustomizeWidget.js +12 -8
- package/es/aics-image-viewer/components/ErrorAlert/index.js +4 -4
- package/es/aics-image-viewer/components/GlobalVolumeControls.js +12 -10
- package/es/aics-image-viewer/components/StyleProvider/index.js +4 -2
- package/es/aics-image-viewer/components/TfEditor/index.js +304 -154
- package/es/aics-image-viewer/components/TfEditor/styles.css +53 -31
- package/es/aics-image-viewer/components/Toolbar/DownloadButton.js +1 -1
- package/es/aics-image-viewer/components/Toolbar/index.js +18 -16
- package/es/aics-image-viewer/components/shared/SharedCheckBox.js +1 -1
- package/es/aics-image-viewer/components/shared/SliderRow/styles.css +1 -0
- package/es/aics-image-viewer/components/shared/SmarterSlider.js +1 -1
- package/es/aics-image-viewer/components/shared/ViewerIcon.js +1 -1
- package/es/aics-image-viewer/components/useVolume.js +68 -59
- package/es/aics-image-viewer/shared/constants.js +2 -2
- package/es/aics-image-viewer/shared/utils/controlPointsToLut.js +57 -24
- package/es/aics-image-viewer/shared/utils/sceneStore.js +14 -4
- package/es/aics-image-viewer/shared/utils/storage.js +238 -0
- package/es/aics-image-viewer/shared/utils/test/storage.test.js +264 -0
- package/es/aics-image-viewer/shared/utils/test/urlParsing.test.js +249 -109
- package/es/aics-image-viewer/shared/utils/test/viewerChannelSettings.test.js +1 -1
- package/es/aics-image-viewer/shared/utils/urlParsing.js +287 -154
- package/es/aics-image-viewer/shared/utils/viewerState.js +4 -24
- package/es/aics-image-viewer/state/reset.js +111 -0
- package/es/aics-image-viewer/state/store.js +90 -0
- package/es/aics-image-viewer/state/subscribers.js +153 -0
- package/es/aics-image-viewer/state/test/reset.test.js +247 -0
- package/es/aics-image-viewer/state/util.js +71 -0
- package/es/index.js +3 -3
- package/package.json +18 -11
- package/type-declarations/aics-image-viewer/components/App/ChannelUpdater.d.ts +2 -4
- package/type-declarations/aics-image-viewer/components/App/types.d.ts +3 -3
- package/type-declarations/aics-image-viewer/components/AxisClipSliders/index.d.ts +6 -6
- package/type-declarations/aics-image-viewer/components/CellViewerCanvasWrapper/index.d.ts +5 -14
- package/type-declarations/aics-image-viewer/components/ChannelsWidget.d.ts +3 -6
- package/type-declarations/aics-image-viewer/components/ChannelsWidgetRow/index.d.ts +3 -6
- package/type-declarations/aics-image-viewer/components/ColorPicker.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/ControlPanel/index.d.ts +6 -7
- package/type-declarations/aics-image-viewer/components/CustomizeWidget.d.ts +2 -8
- package/type-declarations/aics-image-viewer/components/ErrorAlert/index.d.ts +4 -0
- package/type-declarations/aics-image-viewer/components/GlobalVolumeControls.d.ts +2 -9
- package/type-declarations/aics-image-viewer/components/MetadataViewer/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/StyleProvider/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/TfEditor/index.d.ts +10 -3
- package/type-declarations/aics-image-viewer/components/Toolbar/index.d.ts +3 -12
- package/type-declarations/aics-image-viewer/components/shared/SliderRow/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/shared/SmarterSlider.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/shared/ViewerIcon.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/useVolume.d.ts +7 -4
- package/type-declarations/aics-image-viewer/shared/constants.d.ts +5 -5
- package/type-declarations/aics-image-viewer/shared/types.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/controlPointsToLut.d.ts +9 -5
- package/type-declarations/aics-image-viewer/shared/utils/firebase/index.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/hooks.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/playControls.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/sceneStore.d.ts +8 -4
- package/type-declarations/aics-image-viewer/shared/utils/storage.d.ts +15 -0
- package/type-declarations/aics-image-viewer/shared/utils/urlParsing.d.ts +94 -31
- package/type-declarations/aics-image-viewer/shared/utils/viewerChannelSettings.d.ts +39 -1
- package/type-declarations/aics-image-viewer/shared/utils/viewerState.d.ts +3 -6
- package/type-declarations/aics-image-viewer/state/reset.d.ts +29 -0
- package/type-declarations/aics-image-viewer/state/store.d.ts +30 -0
- package/type-declarations/aics-image-viewer/state/subscribers.d.ts +4 -0
- package/type-declarations/aics-image-viewer/state/types.d.ts +46 -0
- package/type-declarations/aics-image-viewer/state/util.d.ts +8 -0
- package/type-declarations/index.d.ts +4 -4
- package/es/aics-image-viewer/components/ViewerStateProvider/ResetStateProvider.js +0 -163
- package/es/aics-image-viewer/components/ViewerStateProvider/index.js +0 -259
- package/type-declarations/aics-image-viewer/components/ViewerStateProvider/ResetStateProvider.d.ts +0 -34
- package/type-declarations/aics-image-viewer/components/ViewerStateProvider/index.d.ts +0 -33
- package/type-declarations/aics-image-viewer/components/ViewerStateProvider/types.d.ts +0 -107
- /package/es/aics-image-viewer/{components/ViewerStateProvider → state}/types.js +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { describe, expect, it } from "@jest/globals";
|
|
2
|
+
import { readStoredMetadata, readStoredScenes, writeMetadata, writeScenes } from "../storage";
|
|
3
|
+
var LONG_STRING = "This is a very long string, long enough that it dwarfs the size of other example data used in this test. Its purpose is to test how the functions in the \"storage\" module evict data from local storage when the quota for local storage size is exceeded. The local storage quota is set to five thousand in this test environment, which is much smaller than most browsers will provide. At one thousand two hundred and thirty-four characters, this string represents a little less than a quarter of the total size of local storage in this test environment. Therefore, the tests below can reliably predict that up to three objects containing this string in one of its properties will fit in local storage, and that inserting a fourth one will trigger an eviction. They can also predict that a single object containing four or more copies of this string will not be allowed in local storage at all. This is slightly imprecise because adding items to local storage using the functions tested in this module incurs some additional storage penalties for the storage key, the stringified JSON surrounding the value, and the key and value of the least-recently-used queue. The size of local storage in this test environment is set in jest.config.js.";
|
|
4
|
+
var LARGE_ENTRY = {
|
|
5
|
+
data: LONG_STRING
|
|
6
|
+
};
|
|
7
|
+
describe("writeMetadata/readStoredMetadata", function () {
|
|
8
|
+
it("writes metadata records to local storage", function () {
|
|
9
|
+
writeMetadata({
|
|
10
|
+
foo: {
|
|
11
|
+
foo: "bar"
|
|
12
|
+
},
|
|
13
|
+
bar: {
|
|
14
|
+
bar: "foo"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
expect(readStoredMetadata(["bar", "foo"])).toEqual([{
|
|
18
|
+
bar: "foo"
|
|
19
|
+
}, {
|
|
20
|
+
foo: "bar"
|
|
21
|
+
}]);
|
|
22
|
+
});
|
|
23
|
+
it("handles metadata keys that contain commas", function () {
|
|
24
|
+
writeMetadata({
|
|
25
|
+
"foo,bar": {
|
|
26
|
+
a: 1,
|
|
27
|
+
b: 2
|
|
28
|
+
},
|
|
29
|
+
baz: {
|
|
30
|
+
three: "eight"
|
|
31
|
+
},
|
|
32
|
+
"bar,foo": {
|
|
33
|
+
c: 3,
|
|
34
|
+
d: 4
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
expect(readStoredMetadata(["baz", "foo,bar"])).toEqual([{
|
|
38
|
+
three: "eight"
|
|
39
|
+
}, {
|
|
40
|
+
a: 1,
|
|
41
|
+
b: 2
|
|
42
|
+
}]);
|
|
43
|
+
});
|
|
44
|
+
it("overwrites duplicate entries", function () {
|
|
45
|
+
writeMetadata({
|
|
46
|
+
foo: {
|
|
47
|
+
numbers: [1, 2, 3]
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
writeMetadata({
|
|
51
|
+
foo: {
|
|
52
|
+
numbers: [4, 5, 6]
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
expect(readStoredMetadata(["foo"])).toEqual([{
|
|
56
|
+
numbers: [4, 5, 6]
|
|
57
|
+
}]);
|
|
58
|
+
});
|
|
59
|
+
it("evicts least-recently used entries when storage runs out", function () {
|
|
60
|
+
writeMetadata({
|
|
61
|
+
one: LARGE_ENTRY
|
|
62
|
+
});
|
|
63
|
+
writeMetadata({
|
|
64
|
+
two: LARGE_ENTRY,
|
|
65
|
+
three: LARGE_ENTRY
|
|
66
|
+
});
|
|
67
|
+
expect(readStoredMetadata(["one", "two", "three"])).toEqual([LARGE_ENTRY, LARGE_ENTRY, LARGE_ENTRY]);
|
|
68
|
+
writeMetadata({
|
|
69
|
+
four: LARGE_ENTRY
|
|
70
|
+
});
|
|
71
|
+
expect(readStoredMetadata(["one", "two", "three", "four"])).toEqual([undefined, LARGE_ENTRY, LARGE_ENTRY, LARGE_ENTRY]);
|
|
72
|
+
});
|
|
73
|
+
it("leaves storage unchanged when a single entry is too large to fit in storage", function () {
|
|
74
|
+
writeMetadata({
|
|
75
|
+
one: {
|
|
76
|
+
entrySize: "small"
|
|
77
|
+
},
|
|
78
|
+
two: {
|
|
79
|
+
bigness: "not_too_large"
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
writeMetadata({
|
|
83
|
+
three: {
|
|
84
|
+
favoriteNumber: 8
|
|
85
|
+
},
|
|
86
|
+
big: {
|
|
87
|
+
one: LONG_STRING,
|
|
88
|
+
two: LONG_STRING,
|
|
89
|
+
three: LONG_STRING,
|
|
90
|
+
four: LONG_STRING
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
expect(readStoredMetadata(["one", "two", "three", "big"])).toEqual([{
|
|
94
|
+
entrySize: "small"
|
|
95
|
+
}, {
|
|
96
|
+
bigness: "not_too_large"
|
|
97
|
+
}, {
|
|
98
|
+
favoriteNumber: 8
|
|
99
|
+
}, undefined]);
|
|
100
|
+
});
|
|
101
|
+
it("moves entries to the front of the queue when read", function () {
|
|
102
|
+
writeMetadata({
|
|
103
|
+
one: LARGE_ENTRY
|
|
104
|
+
});
|
|
105
|
+
writeMetadata({
|
|
106
|
+
two: LARGE_ENTRY,
|
|
107
|
+
three: LARGE_ENTRY
|
|
108
|
+
});
|
|
109
|
+
readStoredMetadata(["one"]);
|
|
110
|
+
writeMetadata({
|
|
111
|
+
four: LARGE_ENTRY,
|
|
112
|
+
five: LARGE_ENTRY
|
|
113
|
+
});
|
|
114
|
+
expect(readStoredMetadata(["one", "two", "three", "four", "five"])).toEqual([LARGE_ENTRY, undefined, undefined, LARGE_ENTRY, LARGE_ENTRY]);
|
|
115
|
+
});
|
|
116
|
+
it("moves entries to the front of the queue when overwritten", function () {
|
|
117
|
+
writeMetadata({
|
|
118
|
+
one: LARGE_ENTRY,
|
|
119
|
+
two: LARGE_ENTRY
|
|
120
|
+
});
|
|
121
|
+
writeMetadata({
|
|
122
|
+
three: LARGE_ENTRY,
|
|
123
|
+
one: LARGE_ENTRY
|
|
124
|
+
});
|
|
125
|
+
writeMetadata({
|
|
126
|
+
four: LARGE_ENTRY
|
|
127
|
+
});
|
|
128
|
+
expect(readStoredMetadata(["one", "two", "three", "four"])).toEqual([LARGE_ENTRY, undefined, LARGE_ENTRY, LARGE_ENTRY]);
|
|
129
|
+
});
|
|
130
|
+
it("returns `false` on an attempt to write more data than local storage can hold", function () {
|
|
131
|
+
var fits = writeMetadata({
|
|
132
|
+
one: LARGE_ENTRY,
|
|
133
|
+
two: LARGE_ENTRY,
|
|
134
|
+
three: LARGE_ENTRY
|
|
135
|
+
});
|
|
136
|
+
expect(fits).toBe(true);
|
|
137
|
+
var tooBig = writeMetadata({
|
|
138
|
+
big: {
|
|
139
|
+
one: LONG_STRING,
|
|
140
|
+
two: LONG_STRING,
|
|
141
|
+
four: LONG_STRING,
|
|
142
|
+
six: LONG_STRING
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
expect(tooBig).toBe(false);
|
|
146
|
+
var tooMany = writeMetadata({
|
|
147
|
+
one: LARGE_ENTRY,
|
|
148
|
+
two: LARGE_ENTRY,
|
|
149
|
+
three: LARGE_ENTRY,
|
|
150
|
+
four: LARGE_ENTRY
|
|
151
|
+
});
|
|
152
|
+
expect(tooMany).toBe(false);
|
|
153
|
+
});
|
|
154
|
+
it("returns `undefined` on an attempt to get an array key", function () {
|
|
155
|
+
writeMetadata({
|
|
156
|
+
one: {
|
|
157
|
+
digits: 1
|
|
158
|
+
},
|
|
159
|
+
"one,two": {
|
|
160
|
+
digits: 12
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
expect(readStoredMetadata(["one", "one,two", ["one", "two"]])).toEqual([{
|
|
164
|
+
digits: 1
|
|
165
|
+
}, {
|
|
166
|
+
digits: 12
|
|
167
|
+
}, undefined]);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe("writeScenes/readStoredScenes", function () {
|
|
171
|
+
var EXAMPLE_URL = "https://example.com/image.zarr";
|
|
172
|
+
var EXAMPLE_URL_2 = "https://example.com/image2.zarr";
|
|
173
|
+
it("writes keyed URLs to local storage", function () {
|
|
174
|
+
writeScenes("foo", EXAMPLE_URL);
|
|
175
|
+
expect(readStoredScenes("foo")).toBe(EXAMPLE_URL);
|
|
176
|
+
});
|
|
177
|
+
it("handles keys that contain commas", function () {
|
|
178
|
+
writeScenes("foo,bar", EXAMPLE_URL);
|
|
179
|
+
expect(readStoredScenes("foo,bar")).toBe(EXAMPLE_URL);
|
|
180
|
+
});
|
|
181
|
+
it("overwrites duplicate entries", function () {
|
|
182
|
+
writeScenes("foo", EXAMPLE_URL);
|
|
183
|
+
writeScenes("foo", EXAMPLE_URL_2);
|
|
184
|
+
expect(readStoredScenes("foo")).toBe(EXAMPLE_URL_2);
|
|
185
|
+
});
|
|
186
|
+
it("evicts least-recently used entries when storage runs out", function () {
|
|
187
|
+
writeScenes("one", LONG_STRING);
|
|
188
|
+
writeScenes("two", LONG_STRING);
|
|
189
|
+
writeScenes("three", LONG_STRING);
|
|
190
|
+
writeScenes("four", LONG_STRING);
|
|
191
|
+
expect(readStoredScenes("one")).toBe(undefined);
|
|
192
|
+
expect(readStoredScenes("two")).toBe(LONG_STRING);
|
|
193
|
+
expect(readStoredScenes("three")).toBe(LONG_STRING);
|
|
194
|
+
expect(readStoredScenes("four")).toBe(LONG_STRING);
|
|
195
|
+
});
|
|
196
|
+
it("shares an eviction queue with metadata", function () {
|
|
197
|
+
writeMetadata({
|
|
198
|
+
one: LARGE_ENTRY
|
|
199
|
+
});
|
|
200
|
+
writeScenes("one", LONG_STRING);
|
|
201
|
+
writeMetadata({
|
|
202
|
+
two: LARGE_ENTRY
|
|
203
|
+
});
|
|
204
|
+
writeScenes("two", LONG_STRING);
|
|
205
|
+
expect(readStoredScenes("one")).toBe(LONG_STRING);
|
|
206
|
+
expect(readStoredMetadata(["one", "two"])).toEqual([undefined, LARGE_ENTRY]);
|
|
207
|
+
expect(readStoredScenes("two")).toBe(LONG_STRING);
|
|
208
|
+
writeMetadata({
|
|
209
|
+
three: LARGE_ENTRY
|
|
210
|
+
});
|
|
211
|
+
expect(readStoredMetadata(["one", "two", "three"])).toEqual([undefined, LARGE_ENTRY, LARGE_ENTRY]);
|
|
212
|
+
expect(readStoredScenes("one")).toBe(undefined);
|
|
213
|
+
expect(readStoredScenes("two")).toBe(LONG_STRING);
|
|
214
|
+
});
|
|
215
|
+
it("moves entries to the front of the queue when read", function () {
|
|
216
|
+
var LARGE_ENTRY = {
|
|
217
|
+
data: LONG_STRING
|
|
218
|
+
};
|
|
219
|
+
writeScenes("one", LONG_STRING);
|
|
220
|
+
writeMetadata({
|
|
221
|
+
one: LARGE_ENTRY
|
|
222
|
+
});
|
|
223
|
+
readStoredScenes("one");
|
|
224
|
+
writeMetadata({
|
|
225
|
+
two: LARGE_ENTRY,
|
|
226
|
+
three: LARGE_ENTRY
|
|
227
|
+
});
|
|
228
|
+
expect(readStoredScenes("one")).toBe(LONG_STRING);
|
|
229
|
+
expect(readStoredMetadata(["one", "two", "three"])).toEqual([undefined, LARGE_ENTRY, LARGE_ENTRY]);
|
|
230
|
+
});
|
|
231
|
+
it("moves entries to the front of the queue when overwritten", function () {
|
|
232
|
+
writeScenes("one", LONG_STRING);
|
|
233
|
+
writeMetadata({
|
|
234
|
+
two: LARGE_ENTRY
|
|
235
|
+
});
|
|
236
|
+
writeMetadata({
|
|
237
|
+
three: LARGE_ENTRY
|
|
238
|
+
});
|
|
239
|
+
writeScenes("one", LONG_STRING);
|
|
240
|
+
writeMetadata({
|
|
241
|
+
four: LARGE_ENTRY
|
|
242
|
+
});
|
|
243
|
+
expect(readStoredScenes("one")).toBe(LONG_STRING);
|
|
244
|
+
expect(readStoredMetadata(["two", "three", "four"])).toEqual([undefined, LARGE_ENTRY, LARGE_ENTRY]);
|
|
245
|
+
});
|
|
246
|
+
it("returns `false` on an attempt to write a longer scene url than local storage can hold", function () {
|
|
247
|
+
expect(writeScenes("fits", LONG_STRING)).toBe(true);
|
|
248
|
+
expect(writeScenes("does_not_fit", LONG_STRING + LONG_STRING + LONG_STRING + LONG_STRING)).toBe(false);
|
|
249
|
+
});
|
|
250
|
+
it("enforces a maximum number of scene entries", function () {
|
|
251
|
+
var MAX_ENTRIES = 25;
|
|
252
|
+
var EXTRA_ENTRIES = 5;
|
|
253
|
+
var entriesToInsert = MAX_ENTRIES + EXTRA_ENTRIES;
|
|
254
|
+
for (var i = 0; i < entriesToInsert; i++) {
|
|
255
|
+
writeScenes("scene".concat(i), EXAMPLE_URL);
|
|
256
|
+
}
|
|
257
|
+
for (var _i = 0; _i < EXTRA_ENTRIES; _i++) {
|
|
258
|
+
expect(readStoredScenes("scene".concat(_i))).toBe(undefined);
|
|
259
|
+
}
|
|
260
|
+
for (var _i2 = EXTRA_ENTRIES; _i2 < entriesToInsert; _i2++) {
|
|
261
|
+
expect(readStoredScenes("scene".concat(_i2))).toBe(EXAMPLE_URL);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
});
|