Skip to content

Commit

Permalink
chore: add download/hash scripts for sandbox (#15218)
Browse files Browse the repository at this point in the history
* chore: add download/hash scripts for sandbox

* remove logging
  • Loading branch information
Rich-Harris authored Feb 5, 2025
1 parent d39d8c0 commit ed1cf75
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 4 deletions.
2 changes: 1 addition & 1 deletion playgrounds/sandbox/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<script type="module">
import { mount, hydrate, unmount } from 'svelte';
import App from '/src/main.svelte';
import App from '/src/App.svelte';

const root = document.getElementById('root');
const render = root.firstChild?.nextSibling ? hydrate : mount;
Expand Down
4 changes: 3 additions & 1 deletion playgrounds/sandbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"ssr": "node --conditions=development ./ssr-dev.js",
"build": "vite build --outDir dist/client && vite build --outDir dist/server --ssr ssr-prod.js",
"prod": "npm run build && node dist/server/ssr-prod",
"preview": "vite preview"
"preview": "vite preview",
"download": "node scripts/download.js",
"hash": "node scripts/hash.js | pbcopy && echo \"copied URL to clipboard\""
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.6",
Expand Down
52 changes: 52 additions & 0 deletions playgrounds/sandbox/scripts/download.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import fs from 'node:fs';

const arg = process.argv[2];

/** @type {URL} */
let url;

try {
url = new URL(arg);
} catch (e) {
console.error(`${arg} is not a URL`);
process.exit(1);
}

if (url.origin !== 'https://svelte.dev' || !url.pathname.startsWith('/playground/')) {
console.error(`${arg} is not a Svelte playground URL`);
process.exit(1);
}

let files;

if (url.hash.length > 1) {
const decoded = atob(url.hash.slice(1).replaceAll('-', '+').replaceAll('_', '/'));
// putting it directly into the blob gives a corrupted file
const u8 = new Uint8Array(decoded.length);
for (let i = 0; i < decoded.length; i++) {
u8[i] = decoded.charCodeAt(i);
}
const stream = new Blob([u8]).stream().pipeThrough(new DecompressionStream('gzip'));
const json = await new Response(stream).text();

files = JSON.parse(json).files;
} else {
const id = url.pathname.split('/')[2];
const response = await fetch(`https://svelte.dev/playground/api/${id}.json`);

files = (await response.json()).components.map((data) => {
const basename = `${data.name}.${data.type}`;

return {
type: 'file',
name: basename,
basename,
contents: data.source,
text: true
};
});
}

for (const file of files) {
fs.writeFileSync(`src/${file.name}`, file.contents);
}
45 changes: 45 additions & 0 deletions playgrounds/sandbox/scripts/hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import fs from 'node:fs';

const files = [];

for (const basename of fs.readdirSync('src')) {
if (fs.statSync(`src/${basename}`).isDirectory()) continue;

files.push({
type: 'file',
name: basename,
basename,
contents: fs.readFileSync(`src/${basename}`, 'utf-8'),
text: true // TODO might not be
});
}

const payload = JSON.stringify({
name: 'sandbox',
files
});

async function compress(payload) {
const reader = new Blob([payload])
.stream()
.pipeThrough(new CompressionStream('gzip'))
.getReader();

let buffer = '';
for (;;) {
const { done, value } = await reader.read();

if (done) {
reader.releaseLock();
return btoa(buffer).replaceAll('+', '-').replaceAll('/', '_');
} else {
for (let i = 0; i < value.length; i++) {
// decoding as utf-8 will make btoa reject the string
buffer += String.fromCharCode(value[i]);
}
}
}
}

const hash = await compress(payload);
console.log(`https://svelte.dev/playground/untitled#${hash}`);
2 changes: 1 addition & 1 deletion playgrounds/sandbox/ssr-dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ polka()
.use(async (req, res) => {
const template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8');
const transformed_template = await vite.transformIndexHtml(req.url, template);
const { default: App } = await vite.ssrLoadModule('/src/main.svelte');
const { default: App } = await vite.ssrLoadModule('/src/App.svelte');
const { head, body } = render(App);

const html = transformed_template
Expand Down
2 changes: 1 addition & 1 deletion playgrounds/sandbox/ssr-prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'node:fs';
import path from 'node:path';
import polka from 'polka';
import { render } from 'svelte/server';
import App from './src/main.svelte';
import App from './src/App.svelte';

const { head, body } = render(App);

Expand Down

0 comments on commit ed1cf75

Please sign in to comment.