Skip to content
This repository was archived by the owner on Nov 13, 2022. It is now read-only.

Commit b74ff72

Browse files
committed
vendering react-cache build due to facebook doesn't publish new code to NPM
1 parent 902f271 commit b74ff72

File tree

9 files changed

+509
-16
lines changed

9 files changed

+509
-16
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ yarn.lock linguist-generated
44
*.rei linguist-language=Reason
55

66
*.bs.js linguist-generated
7+
/lib/*.js linguist-vendored
78

89
* text eol=lf

bsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
],
1717
"package-specs": [
1818
{
19-
"module": "commonjs",
19+
"module": "es6",
2020
"in-source": true
2121
}
2222
],

examples/SuspenseImage.bs.js

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/LRU.js

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
/**
11+
* Modified by Hyeseong Kim <[email protected]>
12+
13+
* Taken this source code from https://github.com/facebook/react/blob/3e94bce765/packages/react-cache/src/LRU.js
14+
* due to Facebook doesn't publish new implementation to NPM.
15+
*/
16+
import * as Scheduler from 'scheduler'; // Intentionally not named imports because Rollup would
17+
// use dynamic dispatch for CommonJS interop named imports.
18+
19+
const {
20+
unstable_scheduleCallback: scheduleCallback,
21+
unstable_IdlePriority: IdlePriority
22+
} = Scheduler;
23+
/*:: type Entry<T> = {|
24+
value: T,
25+
onDelete: () => mixed,
26+
previous: Entry<T>,
27+
next: Entry<T>,
28+
|};*/
29+
30+
export function createLRU
31+
/*:: <T>*/
32+
(limit
33+
/*: number*/
34+
) {
35+
let LIMIT = limit; // Circular, doubly-linked list
36+
37+
let first
38+
/*: Entry<T> | null*/
39+
= null;
40+
let size
41+
/*: number*/
42+
= 0;
43+
let cleanUpIsScheduled
44+
/*: boolean*/
45+
= false;
46+
47+
function scheduleCleanUp() {
48+
if (cleanUpIsScheduled === false && size > LIMIT) {
49+
// The cache size exceeds the limit. Schedule a callback to delete the
50+
// least recently used entries.
51+
cleanUpIsScheduled = true;
52+
scheduleCallback(IdlePriority, cleanUp);
53+
}
54+
}
55+
56+
function cleanUp() {
57+
cleanUpIsScheduled = false;
58+
deleteLeastRecentlyUsedEntries(LIMIT);
59+
}
60+
61+
function deleteLeastRecentlyUsedEntries(targetSize
62+
/*: number*/
63+
) {
64+
// Delete entries from the cache, starting from the end of the list.
65+
if (first !== null) {
66+
const resolvedFirst
67+
/*: Entry<T>*/
68+
= (first
69+
/*: any*/
70+
);
71+
let last = resolvedFirst.previous;
72+
73+
while (size > targetSize && last !== null) {
74+
const onDelete = last.onDelete;
75+
const previous = last.previous;
76+
last.onDelete = (null
77+
/*: any*/
78+
); // Remove from the list
79+
80+
last.previous = last.next = (null
81+
/*: any*/
82+
);
83+
84+
if (last === first) {
85+
// Reached the head of the list.
86+
first = last = null;
87+
} else {
88+
(first
89+
/*: any*/
90+
).previous = previous;
91+
previous.next = (first
92+
/*: any*/
93+
);
94+
last = previous;
95+
}
96+
97+
size -= 1; // Call the destroy method after removing the entry from the list. If it
98+
// throws, the rest of cache will not be deleted, but it will be in a
99+
// valid state.
100+
101+
onDelete();
102+
}
103+
}
104+
}
105+
106+
function add(value
107+
/*: Object*/
108+
, onDelete
109+
/*: () => mixed*/
110+
)
111+
/*: Entry<Object>*/
112+
{
113+
const entry = {
114+
value,
115+
onDelete,
116+
next: (null
117+
/*: any*/
118+
),
119+
previous: (null
120+
/*: any*/
121+
)
122+
};
123+
124+
if (first === null) {
125+
entry.previous = entry.next = entry;
126+
first = entry;
127+
} else {
128+
// Append to head
129+
const last = first.previous;
130+
last.next = entry;
131+
entry.previous = last;
132+
first.previous = entry;
133+
entry.next = first;
134+
first = entry;
135+
}
136+
137+
size += 1;
138+
return entry;
139+
}
140+
141+
function update(entry
142+
/*: Entry<T>*/
143+
, newValue
144+
/*: T*/
145+
)
146+
/*: void*/
147+
{
148+
entry.value = newValue;
149+
}
150+
151+
function access(entry
152+
/*: Entry<T>*/
153+
)
154+
/*: T*/
155+
{
156+
const next = entry.next;
157+
158+
if (next !== null) {
159+
// Entry already cached
160+
const resolvedFirst
161+
/*: Entry<T>*/
162+
= (first
163+
/*: any*/
164+
);
165+
166+
if (first !== entry) {
167+
// Remove from current position
168+
const previous = entry.previous;
169+
previous.next = next;
170+
next.previous = previous; // Append to head
171+
172+
const last = resolvedFirst.previous;
173+
last.next = entry;
174+
entry.previous = last;
175+
resolvedFirst.previous = entry;
176+
entry.next = resolvedFirst;
177+
first = entry;
178+
}
179+
} else {// Cannot access a deleted entry
180+
// TODO: Error? Warning?
181+
}
182+
183+
scheduleCleanUp();
184+
return entry.value;
185+
}
186+
187+
function setLimit(newLimit
188+
/*: number*/
189+
) {
190+
LIMIT = newLimit;
191+
scheduleCleanUp();
192+
}
193+
194+
return {
195+
add,
196+
update,
197+
access,
198+
setLimit
199+
};
200+
}

0 commit comments

Comments
 (0)