') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - Cysharp/ValueTaskSupplement: Append supplemental methods(WhenAny, WhenAll, Lazy) to ValueTask. · GitHub
Skip to content

Repository files navigation

GitHub ActionsReleases

ValueTaskSupplement

ValueTask<T> is a new standard of define async methods especially after being introduced IValueTaskSource. But it lacks utility like WhenAny, etc. ValueTaskSupplement appends supplemental methods(WhenAny, WhenAll, Lazy) to ValueTask and it is implemented by IValueTaskSource so fast and less allocation.

PM> Install-Package ValueTaskSupplement

Table of Contents

How to Use

usingValueTaskSupplement;// namespaceasyncValueTaskDemo(){// `ValueTaskEx` is the only types from provided this library// like this individual typesValueTask<int>task1=LoadAsyncA();ValueTask<string>task2=LoadAsyncB();ValueTask<bool>task3=LoadAsyncC();// await ValueTasks(has different type each other) with tuplevar(a,b,c)=awaitValueTaskEx.WhenAll(task1,task2,task3);// WhenAny with int winIndexvar(winIndex,a,b,c)=awaitValueTaskEx.WhenAny(task1,task2,task2);// like Timeoutvar(hasLeftResult,value)=awaitValueTaskEx.WhenAny(task1,Task.Delay(TimeSpan.FromSeconds(1)));if(!hasLeftResult)thrownewTimeoutException();// Lazy(called factory once and delayed)AsyncLazy<int>asyncLazy=ValueTaskEx.Lazy(async()=>9999);}

WhenAll

// Same type and return array(same as Task.WhenAll).publicstaticValueTask<T[]>WhenAll<T>(IEnumerable<ValueTask<T>>tasks);// T0, T1, to...publicstaticValueTask<(T0,T1)>WhenAll<T0,T1>(ValueTask<T0>task0,ValueTask<T1>task1);
...// T0 ~ T15
public static ValueTask<(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15)>WhenAll<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15>(ValueTask<T0>task0,ValueTask<T1>task1,ValueTask<T2>task2,ValueTask<T3>task3,ValueTask<T4>task4,ValueTask<T5>task5,ValueTask<T6>task6,ValueTask<T7>task7,ValueTask<T8>task8,ValueTask<T9>task9,ValueTask<T10>task10,ValueTask<T11>task11,ValueTask<T12>task12,ValueTask<T13>task13,ValueTask<T14>task14,ValueTask<T15>task15);

IEnumerable<ValueTask<T>> and (ValueTask<T0>, ValueTask<T1>, ...) can await directly.

usingValueTaskSupplement;// same as ValueTaskEx.WhenAll(new []{ }), ValueTaskEx.WhenAll(A, B, C)varresult=awaitnew[]{LoadAsyncA(),LoadAsyncB(),LoadAsyncC()};var(x,y,z)=await(LoadAsyncA(),LoadAsyncB(),LoadAsyncC());

WhenAny

// binary api is useful to await with Delay(like for check Timeout).publicstaticValueTask<(boolhasResultLeft,Tresult)>WhenAny<T>(ValueTask<T>left,Taskright);publicstaticValueTask<(boolhasResultLeft,Tresult)>WhenAny<T>(ValueTask<T>left,ValueTaskright);// receive sequence is like Task.WhenAny but returns `int winArgumentIndex`.publicstaticValueTask<(intwinArgumentIndex,Tresult)>WhenAny<T>(IEnumerable<ValueTask<T>>tasks);// Return result of tuple methods is guaranteed only winArgumentIndex valuepublicstaticValueTask<(intwinArgumentIndex,T0result0,T1result1)>WhenAny<T0,T1>(ValueTask<T0>task0,ValueTask<T1>task1);
...// T0 ~ T15
public static ValueTask<(intwinArgumentIndex,T0result0,T1result1,T2result2,T3result3,T4result4,T5result5,T6result6,T7result7,T8result8,T9result9,T10result10,T11result11,T12result12,T13result13,T14result14,T15result15)>WhenAny<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15>(ValueTask<T0>task0,ValueTask<T1>task1,ValueTask<T2>task2,ValueTask<T3>task3,ValueTask<T4>task4,ValueTask<T5>task5,ValueTask<T6>task6,ValueTask<T7>task7,ValueTask<T8>task8,ValueTask<T9>task9,ValueTask<T10>task10,ValueTask<T11>task11,ValueTask<T12>task12,ValueTask<T13>task13,ValueTask<T14>task14,ValueTask<T15>task15);

Lazy

// AsyncLazy<T> is similar to Lazy<T>, it can store in field// it await directly or can convert to ValueTask easily to use WhenAll.publicstaticAsyncLazy<T>Lazy<T>(Func<ValueTask<T>>factory);publicclassAsyncLazy<T>{publicValueTask<T>AsValueTask();publicValueTaskAwaiter<T>GetAwaiter();publicstaticimplicitoperatorValueTask<T>(AsyncLazy<T>source);}

Factory

publicstaticValueTask<T>FromResult<T>(Tresult);publicstaticValueTaskFromTask(Taskresult);publicstaticValueTask<T>FromTask<T>(Task<T>result);publicstaticValueTaskAsValueTask(thisTaskresult);publicstaticValueTask<T>AsValueTask<T>(thisTask<T>result);

License

This library is under the MIT License.

About

Append supplemental methods(WhenAny, WhenAll, Lazy) to ValueTask.

Resources

Stars

163 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages