- Mar 2023
-
web.dev web.dev
Tags
Annotators
URL
-
-
www.mattstobbs.com www.mattstobbs.com
Tags
Annotators
URL
-
-
www.infoxicator.com www.infoxicator.com
-
www.infoxicator.com www.infoxicator.com
-
```js
export const loader = async () => {
// fire them all at once<br /> const critical1Promise = fetch('/test?text=critical1&delay=250').then(res => res.json()); const critical2Promise = fetch('/test?text=critical2&delay=500').then(res => res.json()); const lazyResolvedPromise = fetch('/test?text=lazyResolved&delay=100').then(res => res.json()); const lazy1Promise = fetch('/test?text=lazy1&delay=500').then(res => res.json()); const lazy2Promise = fetch('/test?text=lazy2&delay=1500').then(res => res.json()); const lazy3Promise = fetch('/test?text=lazy3&delay=2500').then(res => res.json()); const lazyErrorPromise = fetch('/test?text=lazy3&delay=3000').then(res => { throw Error('Oh noo!') });
// await for the response return defer({ critical1: await critical1Promise, critical2: await critical2Promise, lazyResolved: lazyResolvedPromise, lazy1: lazy1Promise, lazy2: lazy2Promise, lazy3: lazy3Promise, lazyError: lazyErrorPromise }) } ```
-
-
hydrogen.shopify.dev hydrogen.shopify.devRoadmap1
-
```js import {defer} from "@shopify/remix-oxygen";
export async function loader({ params: {handle}, context: {storefront} }) { const {product} = storefront.query({ query:
#graphql query Product( $country: CountryCode, $language: LanguageCode, $handle: String! ) @inContext(country: $country, language: $language) product(handle: $handle) { id title }
, variables: {handle}, cache: storefront.CacheLong() }); const {productRecommendations} = storefront.query({ query:#graphql query ProductRecommendations( $country: CountryCode, $language: LanguageCode, $handle: String! ) @inContext(country: $country, language: $language) productRecommendations(handle: $handle) { id title } }
, variables: {handle} }); if (!product) { throw new Response('Not Found', { status: 404, }); } return defer({ product: await product, productRecommendations, }); } ```
Tags
Annotators
URL
-
-
www.npmjs.com www.npmjs.com
Tags
Annotators
URL
-
-
github.com github.com
-
www.jacobparis.com www.jacobparis.com
-
We present deferred data by using React Suspense to conditionally show the content when it's ready. Suspense provides a fallback element to show when the data is not yet ready. Normally a loading spinner would go here, but we can use that to show our streamed progress instead.
js export default function Index() { const data = useLoaderData() const params = useParams() const stream = useEventSource( `/items/${params.hash}/progress`, { event: "progress", }, ) return ( <div> <Suspense fallback={<span> {stream}% </span>}> <Await resolve={data.promise} errorElement={<p>Error loading img!</p>} > {(promise) => <img alt="" src={promise.img} />} </Await> </Suspense> </div> ) }
-
On the client, while we're waiting for our deferred promise to resolve, we can consume that stream to know how far along our process is.
js const stream = useEventSource( `/items/${params.hash}/progress`, { event: "progress", }, )
-
In Remix, we can use a resource route to make this endpoint, and our loader will return a stream that constant checks our JSON file for its progress.
js export async function loader({ request, params, }: LoaderArgs) { const hash = params.hash return eventStream(request.signal, function setup(send) { const interval = setInterval(() => { const file = fs.readFileSync( path.join("public", "items", `${hash}.json`), ) if (file.toString()) { const data = JSON.parse(file.toString()) const progress = data.progress send({ event: "progress", data: String(progress) }) if (progress === 100) { clearInterval(interval) } } }, 200) return function clear(timer: number) { clearInterval(interval) clearInterval(timer) } }) }
-
server sent events work by having an endpoint that does not immediately close its connection, and which sends a content type of text/event-stream.
-
The loader defers a promise that will resolve only when the json's progress has hit 100.
js export async function loader({ params }: LoaderArgs) { if (!params.hash) return redirect("/") const pathname = path.join( "public", "items", `${params.hash}.json`, ) const file = fs.readFileSync(pathname) if (!file) return redirect("/") const item = JSON.parse(file.toString()) if (!item) return redirect("/") if (item.progress === 100) { return defer({ promise: item, }) } return defer({ promise: new Promise((resolve) => { const interval = setInterval(() => { const file = fs.readFileSync(pathname) if (!file) return const item = JSON.parse(file.toString()) if (!item) return if (item.progress === 100) { clearInterval(interval) resolve(item) } return }) }), }) }
-
Defer is a feature of Remix that allows you to return an unresolved Promise from a loader. The page will server-side render without waiting for the promise to resolve, and then when it finally does, the client will re-render with the new data.
-
-
gist.github.com gist.github.com
-
www.bortzmeyer.org www.bortzmeyer.org
Tags
Annotators
URL
-
-
datatracker.ietf.org datatracker.ietf.org
Tags
Annotators
URL
-
-
dummyjson.com dummyjson.com
-
-
-
What could be happening is dates being parsed with a different timezone during SSR and CSR for example.
Tags
Annotators
URL
-
-
matthewherbert.bandcamp.com matthewherbert.bandcamp.com
-
matthewherbert.bandcamp.com matthewherbert.bandcamp.com
-
pirxpilot.me pirxpilot.me
Tags
Annotators
URL
-
-
dev.to dev.to
Tags
Annotators
URL
-
-
blog.cloudflare.com blog.cloudflare.com
Tags
Annotators
URL
-
-
actu.fr actu.fr
-
www.sprague-thomson.com www.sprague-thomson.com
-
soundcloud.com soundcloud.com
-
soundcloud.com soundcloud.com
-
developer.mozilla.org developer.mozilla.org
-
developer.mozilla.org developer.mozilla.org
-
```js function makeDocument() { let frame = document.getElementById("theFrame");
let doc = document.implementation.createHTMLDocument("New Document"); let p = doc.createElement("p"); p.textContent = "This is a new paragraph.";
try { doc.body.appendChild(p); } catch (e) { console.log(e); }
// Copy the new HTML document into the frame
let destDocument = frame.contentDocument; let srcNode = doc.documentElement; let newNode = destDocument.importNode(srcNode, true);
destDocument.replaceChild(newNode, destDocument.documentElement); } ```
-
-
blog.dwac.dev blog.dwac.dev
-
document.implementation.createHTMLDocument() which can stream dynamic HTML content directly into the page DOM
-
-
www.youtube.com www.youtube.com
-
-
developer.mozilla.org developer.mozilla.org
-
developer.mozilla.org developer.mozilla.orgimport1
-
soundcloud.com soundcloud.com
Tags
Annotators
URL
-
-
-
Suspense itself will show fallbacks when not ready and reveal the contents when promises resolve, problem is that if there are multiple Suspense components, it could lead to flickering because of the order is not assured, that’s why we need sorta coordinating. SuspenseList is exactly for this.
```html
<div>Hi</div><React.SuspenseList revealOrder="forwards"> <React.Suspense fallback={\<p>loading...\
}> <Child resource={resource1} /> </React.Suspense> <React.Suspense fallback={\<p>loading...\}> <Child resource={resource2} /> </React.Suspense> <React.Suspense fallback={\<p>loading...\}> <Child resource={resource3} /> </React.Suspense> </React.SuspenseList> ```We can see that the revealing order is kept, from top to bottom, even though the 2nd promise if fulfilled sooner.
-
-
-
Fortunately with webpackChunkName in an inline comment, we can instruct webpack to name the file something much friendlier.
js const HeavyComponent = lazy(() => import(/* webpackChunkName: "HeavyComponent" */ './HeavyComponent');
-
-
plainenglish.io plainenglish.io
-
Similar to prefetching, you can specify the chunk name with an inline comment using the webpackChunkName key
js const LazyLoad = lazy(() => import(/* webpackChunkName: 'lazyload' */ './LazyLoad') );
-
For example, if the user is on the login page, you can load the post-login home page. An inline comment with the webpackPrefetch key within the dynamic import function will instruct Webpack to do just this.
```js const PrefetchLoad = lazy(() => import( / webpackPrefetch: true / './PrefetchLoad' ) );
const App = () => { return ( <Suspense fallback="Loading"> {condition && <PrefetchLoad />} </Suspense> ); }; ```
-
Now when App is rendered and a request is initiated to get the LazyLoad code, the fallback Loading is rendered. When this request completes, React will then render LazyLoad.
js const App = () => { return ( <Suspense fallback="Loading"> <LazyLoad /> </Suspense> ); };
-
Now, App and LazyLoad are in separate code chunks. A request is sent to fetch the LazyLoad code chunk only when App is rendered. When the request completes, React will then renderLazyLoad. You can verify this by looking at the Javascript requests in the network inspector.
```js import React, { lazy } from 'react';
const LazyLoad = lazy(() => import('./LazyLoad'));
const App = () => { return <LazyLoad />; }; ```
-
-
Tags
Annotators
URL
-
-
linguinecode.com linguinecode.com
-
You can have multiple nested React.lazy components inside React.Suspense.
```js
const CatAvatar = React.lazy(() => import('./path/to/cat/avatar')); const ThorAvatar = React.lazy(() => import('./path/to/cat/thor-avatar'));
const AppContainer = () => ( <React.Suspense fallback="loading..."> <CatAvatar /> <ThorAvatar /> </React.Suspense> ); ```
-
-
biot.com biot.com
-
www.wireshark.org www.wireshark.org
-
Use Follow TCP Stream to display HTTP response chunks
-
-
danielmiessler.com danielmiessler.com
Tags
Annotators
URL
-
-
raw.githubusercontent.com raw.githubusercontent.com
-
dl.geekboy.pro:8080 dl.geekboy.pro:8080
-
soundcloud.com soundcloud.com
-
remix.run remix.run
-
-
www.youtube.com www.youtube.com
-
-
france3-regions.francetvinfo.fr france3-regions.francetvinfo.fr
-
developer.mozilla.org developer.mozilla.org
-
Chunked encoding is useful when larger amounts of data are sent to the client and the total size of the response may not be known until the request has been fully processed. For example, when generating a large HTML table resulting from a database query or when transmitting large images.A chunked response looks like this:
```http HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked
7\r\n Mozilla\r\n 11\r\n Developer Network\r\n 0\r\n \r\n ```
-
chunked Data is sent in a series of chunks. The Content-Length header is omitted in this case and at the beginning of each chunk you need to add the length of the current chunk in hexadecimal format, followed by '\r\n' and then the chunk itself, followed by another '\r\n'. The terminating chunk is a regular chunk, with the exception that its length is zero. It is followed by the trailer, which consists of a (possibly empty) sequence of header fields.
-
```abnf Transfer-Encoding: chunked Transfer-Encoding: compress Transfer-Encoding: deflate Transfer-Encoding: gzip
// Several values can be listed, separated by a comma Transfer-Encoding: gzip, chunked ```
-
-
remix.run remix.run
Tags
Annotators
URL
-
-
developer.apple.com developer.apple.com
-
developer.apple.com developer.apple.com
-
developer.android.com developer.android.com
-
Tags
Annotators
URL
-
-
schema.org schema.org
Tags
Annotators
URL
-
-
artsy.github.io artsy.github.io
-
Now we have autocomplete and typechecking.
```ts type ColorDSValue = "black100" | "black80" | "blue100" | "red150" // | etc type ColorOtherString = string & {}
type Color = ColorDSValue | ColorOtherString ```
-
This is so so useful for types or props where you want the general type for support (string), but you also want the specific type for autocomplete ("black100"). It made my whole week when I figured that out and made that color type.
-
This weird-looking intersection of string & {} makes it so that the specific strings "hello" and "world" are distinguished from string as a whole type.
ts const wow: ("hello" | "world") | (string & {}) // `wow` is of type `"hello"` or `"world"` or `string`.
Tags
Annotators
URL
-
-
www.ismn-international.org www.ismn-international.org
-
cisaciswcuat.portal.azure-api.net cisaciswcuat.portal.azure-api.net
-
musicbrainz.org musicbrainz.org
-
MusicBrainz stores ISWCs for works (since the May 2011 server release).
Tags
Annotators
URL
-
-
iswcnet.cisac.org iswcnet.cisac.org
-
-
music-encoding.org music-encoding.org
Tags
Annotators
URL
-
-
music-encoding.org music-encoding.org
-
Tags
Annotators
URL
-
-
meld.web.ox.ac.uk meld.web.ox.ac.ukOverview1
Tags
Annotators
URL
-
-
github.com github.com
Tags
Annotators
URL
-
-
trompamusic.eu trompamusic.eu
-
trompamusic.eu trompamusic.eu
-
trompace-client.readthedocs.io trompace-client.readthedocs.io
-
dl.acm.org dl.acm.org
-
A social data infrastructure for music annotation
-
-
dnotes.github.io dnotes.github.io
-
Tags
Annotators
URL
-
-
Tags
Annotators
URL
-
-
developer.mozilla.org developer.mozilla.org
-
developer.mozilla.org developer.mozilla.org
-
developer.mozilla.org developer.mozilla.org
-
CSS-generated content is not included in the DOM. Because of this, it will not be represented in the accessibility tree and certain assistive technology/browser combinations will not announce it. If the content conveys information that is critical to understanding the page's purpose, it is better to include it in the main document.
-
```abnf content = normal | none | [ <content-replacement> | <content-list> ] [ / [ <string> | <counter> ]+ ]? | element( )
<content-replacement> = <image>
<content-list> = [ <string> | contents | <image> | <counter> | <quote> | <target> | <leader()> ]+
<counter> = <counter()> | <counters()>
<image> = <url> | <gradient>
<quote> = open-quote | close-quote | no-open-quote | no-close-quote
<target> = <target-counter()> | <target-counters()> | <target-text()>
<leader()> = leader( <leader-type> )
<counter()> = counter( <counter-name> , <counter-style>? )
<counters()> = counters( <counter-name> , <string> , <counter-style>? )
<url> = url( <string> <url-modifier> ) | src( <string> <url-modifier> )
<target-counter()> = target-counter( [ <string> | <url> ] , <custom-ident> , <counter-style>? )
<target-counters()> = target-counters( [ <string> | <url> ] , <custom-ident> , <string> , <counter-style>? )
<target-text()> = target-text( [ <string> | <url> ] , [ content | before | after | first-letter ]? )
<leader-type> = dotted | solid | space | <string>
<counter-style> = <counter-style-name> | <symbols()>
<symbols()> = symbols( <symbols-type>? [ <string> | <image> ]+ )
<symbols-type> = cyclic | numeric | alphabetic | symbolic | fixed <br /> ```
-
-
soundcloud.com soundcloud.com
-
soundcloud.com soundcloud.comLithium1
-
yewtu.be yewtu.be
-
soundcloud.com soundcloud.com
-
www.youtube.com www.youtube.com
-
stackoverflow.com stackoverflow.com
-
tailwindcss.com tailwindcss.com
-
```html
<div data-size="large" class="data-[size=large]:p-8"> </div> <div data-size="medium" class="data-[size=large]:p-8"> </div> <style> .data-\[size\=large\]\:p-8[data-size="large"] { padding: 2rem; } </style>```
-
-
-
www.youtube.com www.youtube.com
-
www.youtube.com www.youtube.comYouTube1
-
-
Remix uses the ?index parameter to indicate when a URL refers to the index route instead of the layout route
Tags
Annotators
URL
-
-
github.com github.com
Tags
Annotators
URL
-
-
github.com github.com
-
z-pattern-matching.github.io z-pattern-matching.github.io
-
- Matches by Object property ```js const { matches } = require('z')
const person = { name: 'Maria' } matches(person)( (x = { name: 'John' }) => console.log('John you are not welcome!'), (x) => console.log(
Hey ${x.name}, you are welcome!
) )- Matches by type or instances
js const { matches } = require('z')const result = matches(1)( (x = 2) => 'number 2 is the best!!!', (x = Number) =>
number ${x} is not that good
, (x = Date) => 'blaa.. dates are awful!' )console.log(result) // output: number 1 is not that good
- Matches Array content
js const { matches } = require('z')matches([1, 2, 3, 4, 5])( (a, b, c, tail) => 'a = 1, b = 2, c = 3, tail = [4, 5]'<br /> )
matches([1, 2])( (a, tail) => 'a = 1, tail = [2]'<br /> )
matches([1])( (a, b, tail) => 'Will not match here', (a = 2, tail = []) => 'Will not match here', (a = 1, tail) => 'Will match here, tail = []' ) ```
- Powerful recursive code which will remove sequential repeated items from Array ```js const { matches } = require('z')
const compress = (numbers) => { return matches(numbers)( (x, y, xs) => x === y ? compress([x].concat(xs)) : [x].concat(compress([y].concat(xs))), (x, xs) => x // stopping condition ) }
compress([1, 1, 2, 3, 4, 4, 4]) //output: [1, 2, 3, 4] ```
Tags
Annotators
URL
-
-
soundcloud.com soundcloud.com
-
developer.mozilla.org developer.mozilla.org
-
soundcloud.com soundcloud.com
-
yewtu.be yewtu.be
-
soundcloud.com soundcloud.com
-
Tags
Annotators
URL
-
-
developer.mozilla.org developer.mozilla.org
-
abnf object-fit = fill | contain | cover | none | scale-down
-
-
developer.mozilla.org developer.mozilla.org
-
```abnf object-position = <position>
<position> = [ left | center | right ] || [ top | center | bottom ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]? | [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ]
<length-percentage> = <length> | <percentage> ```
-
-
developer.mozilla.org developer.mozilla.org
-
css-tricks.com css-tricks.com
Tags
Annotators
URL
-
-
www.builder.io www.builder.io
Tags
Annotators
URL
-
-
blog.bitsrc.io blog.bitsrc.io
-
developer.mozilla.org developer.mozilla.org
-
Warning: Microdata were implemented in some browsers for a long time. Nowadays, they have been abandoned and removed from all browsers and are therefore deprecated. You can't use them anymore and this document is kept as information only.
-
-
dev.opera.com dev.opera.com
-
js var biography = document.getItems("http://example.org/biography")[0]; alert('Hi there ' + biography.properties['name'][0].textContent + '!');
-
-
bugs.webkit.org bugs.webkit.org
Tags
Annotators
URL
-
-
bugzilla.mozilla.org bugzilla.mozilla.org
Tags
Annotators
URL
-
-
Tags
Annotators
URL
-
-
lists.w3.org lists.w3.org
-
Tags
Annotators
URL
-
-
web.archive.org web.archive.org
-
The microdata becomes even more useful when scripts can use it to expose information to the user, for example offering it in a form that can be used by other applications.The document.getItems(typeNames) method provides access to the top-level microdata items. It returns a NodeList containing the items with the specified types, or all types if no argument is specified.Each item is represented in the DOM by the element on which the relevant itemscope attribute is found. These elements have their element.itemScope IDL attribute set to true.The type of items can be obtained using the element.itemType IDL attribute on the element with the itemscope attribute.
```js // This sample shows how the getItems() method can be used to obtain a list // of all the top-level microdata items of one type given in the document:
var cats = document.getItems("http://example.com/feline"); ```
```js // This sample gets the first item of type "http://example.net/user" // and then pops up an alert using the "name" property from that item.
var user = document.getItems('http://example.net/user')[0]; alert('Hello ' + user.properties['name'][0].content + '!'); ```
```js // The HTMLPropertiesCollection object, when indexed by name in this way, // actually returns a PropertyNodeList object with all the matching properties. // The PropertyNodeList object can be used to obtain all the values at once // using its values attribute, which returns an array of all the values.
var cat = document.getItems('http://example.org/animals#cat')[0]; var colors = cat.properties['http://example.com/color'].values; var result; if (colors.length == 0) { result = 'Color unknown.'; } else if (colors.length == 1) { result = 'Color: ' + colors[0]; } else { result = 'Colors:'; for (var i = 0; i < colors.length; i += 1) result += ' ' + colors[i]; } ```
-
-
stackoverflow.com stackoverflow.com
-
www.npmjs.com www.npmjs.com
Tags
Annotators
URL
-
-
www.npmjs.com www.npmjs.com
Tags
Annotators
URL
-
-
developer.mozilla.org developer.mozilla.org
-
Tags
Annotators
URL
-
-
css-tricks.com css-tricks.com
-
developer.mozilla.org developer.mozilla.org
-
developer.mozilla.org developer.mozilla.orgdata-*1
-
emnudge.dev emnudge.dev
-
-
giscus.app giscus.appgiscus1
-
-
w3c.github.io w3c.github.io
-
-
www.w3.org www.w3.org
Tags
Annotators
URL
-
-
developer.mozilla.org developer.mozilla.org
-
www.w3.org www.w3.org
-
gorillazforbeginners.com gorillazforbeginners.com
-
soundcloud.com soundcloud.comPeople1
-
soundcloud.com soundcloud.comDARE1