Skip to content

Commit

Permalink
Lazily initialize ResponseWithEncoding (#8253)
Browse files Browse the repository at this point in the history
* Lazily initialize ResponseWithEncoding

* Fix things

* Add a TODO about removing the workaround

* Remove unused lint ignore

* Use canplaythrough instead

* Use an inline script

* Check the readystate first

* Download the video locally

* Capture consoles

* More debugging

* Use autoplay instead of a ready event
  • Loading branch information
matthewp committed Aug 28, 2023
1 parent 46c4c0e commit 1048aca
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 26 deletions.
5 changes: 5 additions & 0 deletions .changeset/grumpy-years-remember.md
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix, lazily initialize ResponseWithEncoding
@@ -1,3 +1,3 @@
<video controls="" autoplay="" name="media" transition:persist transition:name="video">
<video controls="" autoplay="" name="media" transition:persist transition:name="video" autoplay>
<source src="https://ia804502.us.archive.org/33/items/GoldenGa1939_3/GoldenGa1939_3_512kb.mp4" type="video/mp4">
</video>
Expand Up @@ -6,12 +6,4 @@ import Video from '../components/Video.astro';
<p id="video-one">Page 1</p>
<a id="click-two" href="/video-two">go to 2</a>
<Video />
<script>
const vid = document.querySelector('video');
vid.addEventListener('canplay', () => {
// Jump to the 1 minute mark
vid.currentTime = 60;
vid.dataset.ready = '';
}, { once: true });
</script>
</Layout>
2 changes: 1 addition & 1 deletion packages/astro/e2e/view-transitions.test.js
Expand Up @@ -302,7 +302,7 @@ test.describe('View Transitions', () => {

// Go to page 1
await page.goto(astro.resolveUrl('/video-one'));
const vid = page.locator('video[data-ready]');
const vid = page.locator('video');
await expect(vid).toBeVisible();
const firstTime = await page.evaluate(getTime);

Expand Down
45 changes: 29 additions & 16 deletions packages/astro/src/core/endpoint/index.ts
Expand Up @@ -39,6 +39,7 @@ export function createAPIContext({
props,
adapterName,
}: CreateAPIContext): APIContext {
initResponseWithEncoding();
const context = {
cookies: new AstroCookies(request),
request,
Expand Down Expand Up @@ -91,27 +92,39 @@ export function createAPIContext({

type ResponseParameters = ConstructorParameters<typeof Response>;

export class ResponseWithEncoding extends Response {
constructor(body: ResponseParameters[0], init: ResponseParameters[1], encoding?: BufferEncoding) {
// If a body string is given, try to encode it to preserve the behaviour as simple objects.
// We don't do the full handling as simple objects so users can control how headers are set instead.
if (typeof body === 'string') {
// In NodeJS, we can use Buffer.from which supports all BufferEncoding
if (typeof Buffer !== 'undefined' && Buffer.from) {
body = Buffer.from(body, encoding);
export let ResponseWithEncoding: ReturnType<typeof initResponseWithEncoding>;
// TODO Remove this after StackBlitz supports Node 18.
let initResponseWithEncoding = () => {
class LocalResponseWithEncoding extends Response {
constructor(body: ResponseParameters[0], init: ResponseParameters[1], encoding?: BufferEncoding) {
// If a body string is given, try to encode it to preserve the behaviour as simple objects.
// We don't do the full handling as simple objects so users can control how headers are set instead.
if (typeof body === 'string') {
// In NodeJS, we can use Buffer.from which supports all BufferEncoding
if (typeof Buffer !== 'undefined' && Buffer.from) {
body = Buffer.from(body, encoding);
}
// In non-NodeJS, use the web-standard TextEncoder for utf-8 strings
else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') {
body = encoder.encode(body);
}
}
// In non-NodeJS, use the web-standard TextEncoder for utf-8 strings
else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') {
body = encoder.encode(body);

super(body, init);

if (encoding) {
this.headers.set('X-Astro-Encoding', encoding);
}
}
}

super(body, init);
// Set the module scoped variable.
ResponseWithEncoding = LocalResponseWithEncoding;

if (encoding) {
this.headers.set('X-Astro-Encoding', encoding);
}
}
// Turn this into a noop.
initResponseWithEncoding = (() => {}) as any;

return LocalResponseWithEncoding;
}

export async function callEndpoint<MiddlewareResult = Response | EndpointOutput>(
Expand Down

0 comments on commit 1048aca

Please sign in to comment.