feat(playground): add svelte 5 playground (#270)

* feat(playground): add svelte 5 playground

* fix(playground): exclude svelte 5 examples that includes html files since it does not work

* fix: use "/untitled" on Svelte 5 playground base url

Co-authored-by: brunnerh <brunnerh@users.noreply.github.com>

* feat(playground): include snippet title key in json hashed

---------

Co-authored-by: brunnerh <brunnerh@users.noreply.github.com>
This commit is contained in:
Mathieu Schimmerling
2024-10-25 09:35:08 +02:00
committed by GitHub
parent c951f4268a
commit 522d669a0f
4 changed files with 70 additions and 9 deletions

2
.gitignore vendored
View File

@@ -29,3 +29,5 @@ dist-ssr
src/generatedContent
archive
vite.config.js.timestamp*

View File

@@ -110,9 +110,10 @@ export default async function generateContent() {
(f) => f.id === frameworkId
);
frameworkSnippet.files = filesSorter(frameworkSnippet.files);
const playgroundURL = generatePlaygroundURL(
const playgroundURL = await generatePlaygroundURL(
frameworkId,
frameworkSnippet.files
frameworkSnippet.files,
title
);
if (playgroundURL) {
@@ -205,7 +206,7 @@ async function writeJsFile(filepath, jsCode) {
await fs.writeFile(filepath, codeFormatted);
}
function generatePlaygroundURL(frameworkId, files) {
async function generatePlaygroundURL(frameworkId, files, title) {
const frameworkIdPlayground = frameworkPlayground[frameworkId];
if (!frameworkIdPlayground) {
return;
@@ -220,8 +221,10 @@ function generatePlaygroundURL(frameworkId, files) {
return acc;
}, {});
const playgroundURL =
frameworkIdPlayground.fromContentByFilename(contentByFilename);
const playgroundURL = await frameworkIdPlayground.fromContentByFilename(
contentByFilename,
title
);
return playgroundURL;
}

View File

@@ -0,0 +1,57 @@
import path from "node:path";
export default function createSvelte5Playground() {
const BASE_URL = "https://svelte.dev/playground/untitled?version=5#";
async function fromContentByFilename(contentByFilename, title) {
const filenames = Object.keys(contentByFilename);
if (filenames.some((f) => f.includes(".html"))) {
return;
}
const files = filenames.map((filename, index) => {
const contents = contentByFilename[filename];
const name = index === 0 ? "App.svelte" : path.parse(filename).base;
return {
type: "file",
name,
basename: name,
contents,
text: true,
};
});
const payload = { title, files };
const hash = await compress_and_encode_text(JSON.stringify(payload));
const url = `${BASE_URL}${hash}`;
return url;
}
return {
fromContentByFilename,
};
}
// method `compress_and_encode_text` from https://github.com/sveltejs/svelte.dev/blob/main/apps/svelte.dev/src/routes/(authed)/playground/%5Bid%5D/gzip.js
export async function compress_and_encode_text(input) {
const reader = new Blob([input])
.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]);
}
}
}
}

View File

@@ -1,13 +1,12 @@
import createAlpinePlayground from "./createAlpinePlayground.js";
// import createSveltePlayground from "./createSveltePlayground.js";
import createSvelte5Playground from "./createSvelte5Playground.js";
import createVue3Playground from "./createVue3Playground.js";
import createSolidPlayground from "./createSolidPlayground.js";
import createMarkoPlayground from "./createMarkoPlayground.js";
export default {
vue3: createVue3Playground(),
// @TODO: Svelte playground is broken, fixing it when possible
//svelte: createSveltePlayground(),
svelte5: createSvelte5Playground(),
alpine: createAlpinePlayground(),
solid: createSolidPlayground(),
marko: createMarkoPlayground(),