@@ -23,9 +23,8 @@ const proxy = URL.createObjectURL(new Blob([`
23
23
24
24
window.MonacoEnvironment = { getWorkerUrl : ( ) => proxy } ;
25
25
26
- const theme = window.matchMedia &&
27
- window.matchMedia('(prefers-color-scheme: dark)').matches
28
- ? 'vs-dark' : undefined;
26
+ //const theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'vs-dark' : undefined;
27
+ const theme = 'vs-dark';
29
28
30
29
let value = `
31
30
import { flavors } from "https://gist.githubusercontent.com/BurntCaramel/d9d2ca7ed6f056632696709a2ae3c413/raw/0234322cf854d52e2f2bd33aa37e8c8b00f9df0a/1.js";
@@ -132,6 +131,116 @@ export default function App() {
132
131
}
133
132
`.trim();
134
133
134
+ value = `
135
+ import { flavors } from "https://gist.githubusercontent.com/BurntCaramel/d9d2ca7ed6f056632696709a2ae3c413/raw/0234322cf854d52e2f2bd33aa37e8c8b00f9df0a/1.js";
136
+
137
+ const a = 1 + 1 + flavors.length;
138
+
139
+ function useTick() {
140
+ return useReducer ( n => n + 1 , 0 ) ;
141
+ }
142
+
143
+ function useDebouncer(duration) {
144
+ const [ count , tick ] = useTick ( ) ;
145
+
146
+ const callback = useMemo ( ( ) => {
147
+ let timeout = null ;
148
+ function clear ( ) {
149
+ if ( timeout ) {
150
+ clearTimeout ( timeout ) ;
151
+ timeout = null ;
152
+ }
153
+ }
154
+ return ( ) => {
155
+ clear ( )
156
+ timeout = setTimeout ( tick , duration ) ;
157
+ return clear;
158
+ } ;
159
+ } , [ duration , tick ] ) ;
160
+
161
+ return [ count , callback ] ;
162
+ }
163
+
164
+ const cache = new Map();
165
+ function cachedWork(key, work) {
166
+ const existing = cache . get ( key ) ;
167
+ if ( existing ) return existing;
168
+
169
+ const created = work ( ) ;
170
+ cache . set ( key , created ) ;
171
+ return created ;
172
+ }
173
+
174
+ function useCacheKey() {
175
+ const [ key ] = useState ( ( ) => Object ( Symbol ( Math . random ( ) ) ) ) ;
176
+ console . log ( 'key' , key ) ; ;
177
+ return key ;
178
+ }
179
+
180
+ function useCached(work) {
181
+ const key = useCacheKey ( ) ;
182
+ return cachedWork ( key , work ) ;
183
+ }
184
+
185
+ function useAsyncCached(work) {
186
+ const key = useCacheKey ( ) ;
187
+ console . log ( key ) ;
188
+
189
+ let record = cache . get ( key ) ;
190
+
191
+ console . log ( 'record' , record )
192
+
193
+ if ( record === undefined ) {
194
+ record = {
195
+ status: 'pending' ,
196
+ result: undefined
197
+ } ;
198
+ cache . set ( key , record ) ;
199
+
200
+ const promise = work ( )
201
+ . then ( result => {
202
+ record . status = 'succeeded' ;
203
+ record. result = result ;
204
+ } )
205
+ . catch ( error => {
206
+ record . status = 'failed' ;
207
+ record. result = error ;
208
+ } ) ;
209
+ record . promise = promise ;
210
+ }
211
+
212
+ if ( record . status === 'pending' ) {
213
+ throw record . promise ;
214
+ }
215
+
216
+ if ( record . status === 'failed' ) {
217
+ throw record . result ;
218
+ }
219
+
220
+ return record . result ;
221
+ }
222
+
223
+ function SHAComponent() {
224
+ const sha = useAsyncCached ( ( ) =>
225
+ crypto . subtle . digest ( 'SHA-256' , new TextEncoder ( ) . encode ( 'abc' ) )
226
+ . then ( arrayBuffer => {
227
+ return Array . from ( new Uint8Array ( arrayBuffer ) , chunk => chunk . toString ( 16 ) . padStart ( 2 , '0' ) ) . join ( '' ) ;
228
+ } )
229
+ ) ;
230
+
231
+ return < div > { sha } < / div > ;
232
+ }
233
+
234
+ export default function App() {
235
+ const [ count , tick ] = useDebouncer ( 1000 ) ;
236
+ return <>
237
+ < div > Hello ! ! { flavors . join ( " " ) } < / div >
238
+ < button onClick = { tick } > Click < / button >
239
+ < div > { count } < / div >
240
+ < />;
241
+ }
242
+ `.trim();
243
+
135
244
const types = fetch("https://workers.cloudflare.com/index.d.ts", { cache : 'force-cache' } )
136
245
.then((response) => response.text())
137
246
.catch((err) = > ` // $ { err . message } `);
@@ -250,6 +359,7 @@ require(["vs/editor/editor.main"], function () {
250
359
})
251
360
})
252
361
.then(({ code, codeBytes, duration }) => {
362
+ console.log(" NEW CODE!");
253
363
const executor = new Function(`${code}; return exports.Example();`);
254
364
const result = executor();
255
365
return new Map()
@@ -281,11 +391,25 @@ require(["vs/editor/editor.main"], function () {
281
391
model.setValue(input.getValue() + " \n") ;
282
392
283
393
const clientAppEl = document.getElementById( 'clientApp') ;
394
+ const reactRenderEl = document . querySelector ( '#clientResult slot[name="reactRenderDuration"]' ) ;
284
395
let renderCount = 0 ;
285
396
clientAppEl. addEventListener ( 'DID_RENDER' , ( { detail } ) => {
286
397
renderCount ++ ;
287
- console.log(" DID_RENDER ");
288
- document.querySelector('#clientResult slot[name="reactRenderDuration "]').textContent = `last ${detail.actualDuration}ms; ${renderCount} times rendered`;
398
+
399
+ if ( renderCount > 1000 ) {
400
+ const previousCount = renderCount ;
401
+ setTimeout ( ( ) => {
402
+ if ( renderCount - previousCount > 100 ) {
403
+ // Too many renders.
404
+ / / Abort client React app!
405
+ clientAppEl. dispatchEvent ( new CustomEvent ('RESET' ) ) ;
406
+
407
+ reactRenderEl. textContent = `aborted due to infinite rendering loop! `;
408
+ }
409
+ } , 1000 ) ;
410
+ }
411
+
412
+ reactRenderEl. textContent = `last ${ detail . actualDuration } ms; ${ renderCount } times rendered `;
289
413
} ) ;
290
414
} );
291
415
</ script >
0 commit comments