Skip to content

Commit 582f452

Browse files
committed
Add docs, tooltip to idb-cache config
1 parent 1f66852 commit 582f452

File tree

6 files changed

+737
-20
lines changed

6 files changed

+737
-20
lines changed

packages/idb-cache-app/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@
1919
"@instructure/ui-buttons": "^9.9.0",
2020
"@instructure/ui-flex": "^9.9.0",
2121
"@instructure/ui-heading": "^9.9.0",
22+
"@instructure/ui-icons": "^9.10.0",
2223
"@instructure/ui-metric": "^9.9.0",
2324
"@instructure/ui-number-input": "^9.9.0",
25+
"@instructure/ui-radio-input": "^9.10.0",
2426
"@instructure/ui-responsive": "^9.9.0",
27+
"@instructure/ui-text": "^9.10.0",
2528
"@instructure/ui-text-input": "^9.9.0",
29+
"@instructure/ui-tooltip": "^9.10.0",
2630
"@instructure/ui-view": "^9.9.0",
2731
"@playwright/test": "^1.48.2",
2832
"@rsbuild/core": "^1.0.19",

packages/idb-cache-app/src/App.tsx

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ import {
1818
} from "./components/WrappedFlexItem";
1919
import { Test } from "./components/Test";
2020
import { generateTextOfSize } from "./fixtures";
21+
import { RadioInputGroup, RadioInput } from "@instructure/ui-radio-input";
22+
import { IconInfoLine } from "@instructure/ui-icons";
23+
import { Tooltip } from "@instructure/ui-tooltip";
24+
25+
const DEFAULT_NUM_ITEMS = 1;
26+
const DEFAULT_ITEM_SIZE = 1024 * 32; // 32KiB
27+
const DEFAULT_CHUNK_SIZE = 1024 * 25; // 25 KiB
28+
const DEFAULT_MAX_CHUNKS_STORED = 5000;
2129

2230
// For demonstration/testing purposes.
2331
// Do *not* store cacheKey to localStorage in production.
@@ -33,13 +41,6 @@ if (!initialCacheBuster) {
3341
localStorage.cacheBuster = initialCacheBuster;
3442
}
3543

36-
const DEFAULT_NUM_ITEMS = 1;
37-
38-
// Default item size set to 32KB
39-
const DEFAULT_ITEM_SIZE = 1024 * 32;
40-
const DEFAULT_CHUNK_SIZE = 1024 * 25; // 25 KiB
41-
const DEAFULT_MAX_CHUNKS_STORED = 5000;
42-
4344
const getInitialItemSize = () => {
4445
const params = new URLSearchParams(window.location.hash.slice(1));
4546
const sizeParam = params.get("size");
@@ -67,8 +68,8 @@ const App = () => {
6768
const [itemCount, setItemCount] = useState<number | null>(null);
6869
const [maxTotalChunksStored, setMaxTotalChunksStored] = useState<number>(
6970
() => {
70-
const stored = localStorage.getItem("maxTotalChunksStored");
71-
return stored ? Number.parseInt(stored, 10) : DEAFULT_MAX_CHUNKS_STORED;
71+
const stored = localStorage.maxTotalChunksStored;
72+
return stored ? Number.parseInt(stored, 10) : DEFAULT_MAX_CHUNKS_STORED;
7273
},
7374
);
7475

@@ -303,7 +304,22 @@ const App = () => {
303304

304305
<WrappedFlexItem>
305306
<NumberInput
306-
renderLabel="Item size (KiB):"
307+
renderLabel={
308+
<Flex alignItems="end" direction="row">
309+
<Flex.Item as="div">
310+
<View margin="0 xx-small 0 0">Item size (KiB)</View>
311+
</Flex.Item>
312+
<Tooltip
313+
color="primary-inverse"
314+
renderTip="When an item exceeds this size, it splits into multiple chunks."
315+
offsetY="5px"
316+
>
317+
<Flex.Item as="div">
318+
<IconInfoLine />
319+
</Flex.Item>
320+
</Tooltip>
321+
</Flex>
322+
}
307323
onChange={(e) => {
308324
const newValue = Math.max(
309325
Number.parseInt(e.target.value || "0", 10) * 1024,
@@ -317,7 +333,6 @@ const App = () => {
317333
onDecrement={() => {
318334
setItemSize((prev) => Math.max(prev - 1024, 1024));
319335
}}
320-
isRequired
321336
value={Math.round(itemSize / 1024)} // Display in KiB
322337
/>
323338
</WrappedFlexItem>
@@ -332,7 +347,7 @@ const App = () => {
332347
<WrappedFlexItem>
333348
<NumberInput
334349
disabled
335-
renderLabel="Chunk size (KiB):"
350+
renderLabel="Chunk size (KiB)"
336351
onChange={(e) => {
337352
const newValue = Math.max(
338353
Number.parseInt(e.target.value || "0", 10) * 1024,
@@ -352,7 +367,22 @@ const App = () => {
352367

353368
<WrappedFlexItem>
354369
<NumberInput
355-
renderLabel="Max total chunks:"
370+
renderLabel={
371+
<Flex alignItems="end">
372+
<Flex.Item as="div">
373+
<View margin="0 xx-small 0 0">Max total chunks</View>
374+
</Flex.Item>
375+
<Tooltip
376+
color="primary-inverse"
377+
renderTip="During cleanup, idb-cache removes the oldest surplus chunks."
378+
offsetY="5px"
379+
>
380+
<Flex.Item as="div">
381+
<IconInfoLine />
382+
</Flex.Item>
383+
</Tooltip>
384+
</Flex>
385+
}
356386
onChange={(e) => {
357387
const newValue =
358388
Number.parseInt(e.target.value || "0", 10) || 1;
@@ -367,6 +397,33 @@ const App = () => {
367397
value={maxTotalChunksStored}
368398
/>
369399
</WrappedFlexItem>
400+
401+
<WrappedFlexItem>
402+
<RadioInputGroup
403+
name="priority"
404+
defaultValue="normal"
405+
description={
406+
<Flex alignItems="end">
407+
<Flex.Item as="div">
408+
<View margin="0 xx-small 0 0">Priority</View>
409+
</Flex.Item>
410+
<Tooltip
411+
color="primary-inverse"
412+
renderTip="Low priority delays start of operations slightly to reduce load on event loop."
413+
offsetY="5px"
414+
>
415+
<Flex.Item as="div">
416+
<IconInfoLine />
417+
</Flex.Item>
418+
</Tooltip>
419+
</Flex>
420+
}
421+
variant="toggle"
422+
>
423+
<RadioInput label="Normal" value="normal" />
424+
<RadioInput label="Low" value="low" />
425+
</RadioInputGroup>
426+
</WrappedFlexItem>
370427
</WrappedFlexContainer>
371428

372429
<Heading level="h2" margin="medium 0 small 0">

packages/idb-cache-app/src/components/CacheBuster.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
import { Button } from "@instructure/ui-buttons";
22
import { Flex } from "@instructure/ui-flex";
3+
import { IconInfoLine } from "@instructure/ui-icons";
34
import { TextInput } from "@instructure/ui-text-input";
5+
import { Tooltip } from "@instructure/ui-tooltip";
6+
import { View } from "@instructure/ui-view";
47

58
export function CacheBuster({ cacheBuster }: { cacheBuster: string }) {
69
return (
710
<Flex alignItems="end">
811
<Flex.Item shouldGrow>
912
<TextInput
10-
renderLabel="Cache buster:"
13+
renderLabel={
14+
<Flex alignItems="end">
15+
<Flex.Item as="div">
16+
<View margin="0 xx-small 0 0">Cache buster</View>
17+
</Flex.Item>
18+
<Tooltip
19+
color="primary-inverse"
20+
renderTip="Unique value (not sensitive) used to invalidate old cache entries."
21+
offsetY="5px"
22+
>
23+
<Flex.Item as="div">
24+
<IconInfoLine />
25+
</Flex.Item>
26+
</Tooltip>
27+
</Flex>
28+
}
1129
interaction="disabled"
1230
defaultValue={cacheBuster}
1331
/>

packages/idb-cache-app/src/components/CacheKey.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Button } from "@instructure/ui-buttons";
22
import { Flex } from "@instructure/ui-flex";
3+
import { IconInfoLine } from "@instructure/ui-icons";
34
import { TextInput } from "@instructure/ui-text-input";
5+
import { Tooltip } from "@instructure/ui-tooltip";
6+
import { View } from "@instructure/ui-view";
47

58
export function CacheKey({
69
cacheKey,
@@ -11,7 +14,22 @@ export function CacheKey({
1114
<Flex alignItems="end">
1215
<Flex.Item shouldGrow>
1316
<TextInput
14-
renderLabel="Cache key:"
17+
renderLabel={
18+
<Flex alignItems="end">
19+
<Flex.Item as="div">
20+
<View margin="0 xx-small 0 0">Cache key</View>
21+
</Flex.Item>
22+
<Tooltip
23+
color="primary-inverse"
24+
renderTip="Sensitive identifier used for securely encrypting data."
25+
offsetY="5px"
26+
>
27+
<Flex.Item as="div">
28+
<IconInfoLine />
29+
</Flex.Item>
30+
</Tooltip>
31+
</Flex>
32+
}
1533
interaction="disabled"
1634
defaultValue={cacheKey}
1735
/>

packages/idb-cache/src/index.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,54 @@ const DURATION_THRESHOLD = 200;
3838
const isSubtleCryptoSupported = crypto?.subtle;
3939

4040
interface IDBCacheConfig {
41-
cacheBuster: string;
41+
/**
42+
* Sensitive identifier used for securely encrypting data.
43+
*/
4244
cacheKey: string;
45+
/**
46+
* Unique value (not sensitive) used to invalidate old cache entries.
47+
*/
48+
cacheBuster: string;
49+
/**
50+
* Size of each chunk in bytes. When an item exceeds this size,
51+
* it splits into multiple chunks. Defaults to 25000 bytes.
52+
*/
4353
chunkSize?: number;
54+
/**
55+
* Milliseconds between cleanup operations to remove expired
56+
* or surplus cached items.
57+
*/
4458
cleanupInterval?: number;
59+
/**
60+
* Name of the IndexedDB database used for caching.
61+
* Defaults to "idb-cache" if not specified.
62+
*/
4563
dbName?: string;
64+
/**
65+
* Enables detailed logging for debugging purposes
66+
* when set to true.
67+
*/
4668
debug?: boolean;
69+
/**
70+
* Milliseconds after which cached items are considered eligible
71+
* for removal during garbage collection.
72+
*/
4773
gcTime?: number;
4874
/**
49-
* The maximum number of chunks to store in the cache.
50-
* If set, during cleanup intervals, the cache will ensure that no more than maxTotalChunks are stored.
51-
* Excess oldest chunks will be removed to enforce this limit.
52-
* Defaults to undefined, meaning no limit.
75+
* The maximum number of chunks to store in the cache. During cleanup,
76+
* idb-cache removes the oldest excess chunks. Defaults to undefined,
77+
* meaning no limit.
5378
*/
5479
maxTotalChunks?: number;
80+
/**
81+
* Iterations used in the encryption algorithm to strengthen cryptographic keys.
82+
* More iterations increase security but also processing time.
83+
*/
5584
pbkdf2Iterations?: number;
85+
/**
86+
* Low priority delays start of operations slightly to reduce load on the event loop.
87+
*/
88+
priority?: "normal" | "low";
5689
}
5790

5891
export interface AsyncStorage {

0 commit comments

Comments
 (0)