Daniel Ledda pirms 2 mēnešiem
vecāks
revīzija
ea5be77bc9
7 mainītis faili ar 67 papildinājumiem un 176 dzēšanām
  1. +1
    -1
      deno.json
  2. +5
    -89
      deno.lock
  3. +0
    -2
      deps.ts
  4. +3
    -3
      main.ts
  5. +1
    -1
      public/index.html
  6. +57
    -0
      transpile.ts
  7. +0
    -80
      transpileTs.ts

+ 1
- 1
deno.json Parādīt failu

@@ -2,13 +2,13 @@
"tasks": {
"start": "deno --allow-read --allow-net --allow-env --allow-write --allow-run main.ts",
"watch": "deno --watch --allow-read --allow-net --allow-env --allow-write --allow-run main.ts"
"install": "deno install --entrypoint deps.ts"
},
"fmt": {
"lineWidth": 120,
"indentWidth": 4
},
"imports": {
"@stock3/koala": "npm:@stock3/koala@^15.3.8-esm.0",
"vue": "npm:vue@^3.5.12",
"vue/jsx-runtime": "npm:vue/jsx-runtime",
"@/": "./app/"


+ 5
- 89
deno.lock Parādīt failu

@@ -4,29 +4,21 @@
"jsr:@deno/cache-dir@0.13.2": "0.13.2",
"jsr:@deno/emit@*": "0.46.0",
"jsr:@deno/graph@~0.73.1": "0.73.1",
"jsr:@luca/esbuild-deno-loader@0.11": "0.11.0",
"jsr:@std/assert@0.223": "0.223.0",
"jsr:@std/bytes@0.223": "0.223.0",
"jsr:@std/bytes@^1.0.2": "1.0.2",
"jsr:@std/cli@^1.0.6": "1.0.6",
"jsr:@std/encoding@^1.0.5": "1.0.5",
"jsr:@std/fmt@0.223": "0.223.0",
"jsr:@std/fmt@^1.0.3": "1.0.3",
"jsr:@std/fs@*": "1.0.5",
"jsr:@std/fs@0.223": "0.223.0",
"jsr:@std/http@*": "1.0.9",
"jsr:@std/io@0.223": "0.223.0",
"jsr:@std/media-types@*": "1.0.3",
"jsr:@std/media-types@^1.0.3": "1.0.3",
"jsr:@std/net@^1.0.4": "1.0.4",
"jsr:@std/path@0.223": "0.223.0",
"jsr:@std/path@^1.0.6": "1.0.7",
"jsr:@std/path@^1.0.7": "1.0.7",
"jsr:@std/streams@^1.0.7": "1.0.7",
"npm:@stock3/koala@^15.3.8-esm.0": "15.3.8-esm.0_@stock3+auth-js@4.2.3_bg-auth-legacy@2.5.0_bg-status-js@2.4.3_flora-client-js@0.5.3_m-gate@2.12.8_vue@3.5.12_vue-router@4.4.5__vue@3.5.12",
"npm:@types/node@*": "22.5.4",
"npm:vue@*": "3.5.12",
"npm:vue@3.5.12": "3.5.12",
"npm:vue@^3.5.12": "3.5.12"
},
"jsr": {
@@ -35,7 +27,7 @@
"dependencies": [
"jsr:@deno/graph",
"jsr:@std/fmt@0.223",
"jsr:@std/fs@0.223",
"jsr:@std/fs",
"jsr:@std/io",
"jsr:@std/path@0.223"
]
@@ -50,23 +42,12 @@
"@deno/graph@0.73.1": {
"integrity": "cd69639d2709d479037d5ce191a422eabe8d71bb68b0098344f6b07411c84d41"
},
"@luca/esbuild-deno-loader@0.11.0": {
"integrity": "c05a989aa7c4ee6992a27be5f15cfc5be12834cab7ff84cabb47313737c51a2c",
"dependencies": [
"jsr:@std/bytes@^1.0.2",
"jsr:@std/encoding",
"jsr:@std/path@^1.0.6"
]
},
"@std/assert@0.223.0": {
"integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24"
},
"@std/bytes@0.223.0": {
"integrity": "84b75052cd8680942c397c2631318772b295019098f40aac5c36cead4cba51a8"
},
"@std/bytes@1.0.2": {
"integrity": "fbdee322bbd8c599a6af186a1603b3355e59a5fb1baa139f8f4c3c9a1b3e3d57"
},
"@std/cli@1.0.6": {
"integrity": "d22d8b38c66c666d7ad1f2a66c5b122da1704f985d3c47f01129f05abb6c5d3d"
},
@@ -82,19 +63,13 @@
"@std/fs@0.223.0": {
"integrity": "3b4b0550b2c524cbaaa5a9170c90e96cbb7354e837ad1bdaf15fc9df1ae9c31c"
},
"@std/fs@1.0.5": {
"integrity": "41806ad6823d0b5f275f9849a2640d87e4ef67c51ee1b8fb02426f55e02fd44e",
"dependencies": [
"jsr:@std/path@^1.0.7"
]
},
"@std/http@1.0.9": {
"integrity": "d409fc319a5e8d4a154e576c758752e9700282d74f31357a12fec6420f9ecb6c",
"dependencies": [
"jsr:@std/cli",
"jsr:@std/encoding",
"jsr:@std/fmt@^1.0.3",
"jsr:@std/media-types@^1.0.3",
"jsr:@std/media-types",
"jsr:@std/net",
"jsr:@std/path@^1.0.7",
"jsr:@std/streams"
@@ -104,7 +79,7 @@
"integrity": "2d8c3c2ab3a515619b90da2c6ff5ea7b75a94383259ef4d02116b228393f84f1",
"dependencies": [
"jsr:@std/assert",
"jsr:@std/bytes@0.223"
"jsr:@std/bytes"
]
},
"@std/media-types@1.0.3": {
@@ -133,8 +108,8 @@
"@babel/helper-validator-identifier@7.25.9": {
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="
},
"@babel/parser@7.26.1": {
"integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==",
"@babel/parser@7.26.2": {
"integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
"dependencies": [
"@babel/types"
]
@@ -149,30 +124,6 @@
"@jridgewell/sourcemap-codec@1.5.0": {
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
},
"@stock3/auth-js@4.2.3": {
"integrity": "sha512-zGtenGSxx/PVfbd9oIPPyPA9K2kOWYZ382lSNFZ2JzdB8SBVZinMP5c5s406cnxgMujTpim9lpaY/o7nUUCF1w==",
"dependencies": [
"bg-api-authorization"
]
},
"@stock3/koala@15.3.8-esm.0_@stock3+auth-js@4.2.3_bg-auth-legacy@2.5.0_bg-status-js@2.4.3_flora-client-js@0.5.3_m-gate@2.12.8_vue@3.5.12_vue-router@4.4.5__vue@3.5.12": {
"integrity": "sha512-7VUztN6HIRYVgUjhouR3uBlZmLcQrvt7Z2ZVidb5DvSPRFtpYxGq65fqpovR+8O8k3d8BWs338Vc9sdPBYEV4A==",
"dependencies": [
"@stock3/auth-js",
"bg-auth-legacy",
"bg-status-js",
"flora-client-js",
"m-gate",
"vue",
"vue-router"
]
},
"@types/node@22.5.4": {
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
"dependencies": [
"undici-types"
]
},
"@vue/compiler-core@3.5.12": {
"integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==",
"dependencies": [
@@ -211,9 +162,6 @@
"@vue/shared"
]
},
"@vue/devtools-api@6.6.4": {
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
},
"@vue/reactivity@3.5.12": {
"integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==",
"dependencies": [
@@ -247,15 +195,6 @@
"@vue/shared@3.5.12": {
"integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg=="
},
"bg-api-authorization@2.0.0": {
"integrity": "sha512-eo4lPdyktT3S2i6Ef+1drJuHku3NyvhLzM3JNkRsS70v+0J7C2jrsGQAXTVLnaJ5V+tC51g8C6BoanwQxi//8Q=="
},
"bg-auth-legacy@2.5.0": {
"integrity": "sha512-+V1vVpUDrMJB1s8CcOak4yXBXbz3oejQ16GqKyuRrqy9e43VLozaHl/Xmsj1TCm2TrB7Ha2rExnk7VLbcjFU6w=="
},
"bg-status-js@2.4.3": {
"integrity": "sha512-Ys0rGJGDZuPAfnYhTqwndRtZYxhmGopDZ2t42OGgJXnYxaZT1dDaKV56tXf75tMO9+y0PIOewP6kEgkkSccN1g=="
},
"csstype@3.1.3": {
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
@@ -265,18 +204,6 @@
"estree-walker@2.0.2": {
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"flora-client-js@0.5.3": {
"integrity": "sha512-00CHCjfIDxo+/ROQkHGqS+9mzhGVmdEMErmwBg7roYD4gIKNjDgFJgYoDB8V1VmTeK4LFaPm2B1du1iMxgY8sQ==",
"dependencies": [
"has"
]
},
"has@1.0.4": {
"integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ=="
},
"m-gate@2.12.8": {
"integrity": "sha512-QAyDRBBYFx6k+WoVMpGwWFf2Z554LMNfF6yVmqW92FgP5hx9qUQypWZPl9P2XEw3Htlv/rBVQ9q9n+uBcx6yEg=="
},
"magic-string@0.30.12": {
"integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==",
"dependencies": [
@@ -300,16 +227,6 @@
"source-map-js@1.2.1": {
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
},
"undici-types@6.19.8": {
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
},
"vue-router@4.4.5_vue@3.5.12": {
"integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==",
"dependencies": [
"@vue/devtools-api",
"vue"
]
},
"vue@3.5.12": {
"integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==",
"dependencies": [
@@ -323,7 +240,6 @@
},
"workspace": {
"dependencies": [
"npm:@stock3/koala@^15.3.8-esm.0",
"npm:vue@*",
"npm:vue@^3.5.12"
]


+ 0
- 2
deps.ts Parādīt failu

@@ -1,5 +1,3 @@
import "jsr:@deno/emit";
import "jsr:@std/media-types";
import "jsr:@std/http";
import "vue";
import "@stock3/koala";

+ 3
- 3
main.ts Parādīt failu

@@ -2,7 +2,7 @@ import { serveFile } from "jsr:@std/http/file-server";
import { createSSRApp } from "vue";
import { renderToString } from "vue/server-renderer";
import App from "@/App.tsx";
import transpileResponse from './transpileTs.ts';
import transpileResponse from './transpile.ts';

const utf8Decoder = new TextDecoder("utf-8");

@@ -17,7 +17,7 @@ Deno.serve({
const pathname = URL.parse(req.url)?.pathname ?? "/";
if (pathname === "/") {
const rendered = await renderToString(createSSRApp(App));
const content = utf8Decoder.decode(await Deno.readFile("./playground/index.html"))
const content = utf8Decoder.decode(await Deno.readFile("./public/index.html"))
.replace(`<!-- SSR OUTLET -->`, rendered)
.replace(`<!-- SSR HEAD OUTLET -->`, '');
return new Response(content, { headers: { "Content-Type": "text/html" } });
@@ -29,7 +29,7 @@ Deno.serve({
} else if (pathname.startsWith('/deps')) {
return serveFile(req, `node_modules/${pathname.split('/deps')[1]}`);
} else {
return serveFile(req, `playground${pathname}`);
return serveFile(req, `public${ pathname }`);
}
} else {
return new Response("Only GET allowed.", { status: 500 });


+ 1
- 1
public/index.html Parādīt failu

@@ -19,7 +19,7 @@
<body>
<main class="container">
<h1>G'day, mate!</h1>
<h2>Willkommen auf Daniels Spielwiese</h2>
<h2>YOUR SITE GOES HERE</h2>
<img src="image.jpeg" alt="KANGAROO" />
<div id="app-root"><!-- SSR OUTLET --></div>
</main>


+ 57
- 0
transpile.ts Parādīt failu

@@ -0,0 +1,57 @@
import { CompilerOptions, transpile, TranspileOptions } from "jsr:@deno/emit";
import denoJson from "./deno.json" with { type: "json" };

const contentTypes = {
'js': "application/javascript; charset=utf-8",

// https://github.com/denoland/deno_ast/blob/ea1ccec37e1aa8e5e1e70f983a7ed1472d0e132a/src/media_type.rs#L117
'ts': "text/typescript; charset=utf-8",
'jsx': "text/jsx; charset=utf-8",
'tsx': "text/tsx; charset=utf-8",
} as const;

const transpileOptions = (extension: keyof typeof contentTypes, tsCode: string, targetUrlStr: string): TranspileOptions => ({
importMap: {
imports: denoJson.imports,
},
compilerOptions: denoJson.compilerOptions as CompilerOptions,
load(specifier) {
const correctContent = specifier === targetUrlStr;
return Promise.resolve({
kind: "module",
specifier,
content: correctContent ? tsCode : "",
headers: { "content-type": contentTypes[correctContent ? extension : 'js'] },
});
},
});

export default async function transpileResponse(response: Response, requestUrl: string, filepath?: string): Promise<Response> {
const url = new URL(`ts-serve:///${ requestUrl }`);
const pathname = filepath !== undefined ? filepath : url.pathname;
const extension = pathname.split('.').at(-1) ?? '';
if (response.status === 200 && (extension === 'ts' || extension === 'tsx' || extension === 'jsx')) {
const tsCode = await response.text();
const targetUrlStr = url.toString();
try {
const result = await transpile(url, transpileOptions(extension, tsCode, targetUrlStr));
const jsCode = result.get(targetUrlStr);
response.headers.delete("content-length");
response.headers.set("content-type", contentTypes.js);
return new Response(jsCode, {
status: response.status,
statusText: response.statusText,
headers: response.headers,
});
} catch (e) {
console.error('[transpileResponse]: Error transpiling!\n', e);
if (typeof e === 'string') {
return new Response('Internal Server Error', {
status: 500,
headers: response.headers,
});
}
}
}
return response;
}

+ 0
- 80
transpileTs.ts Parādīt failu

@@ -1,80 +0,0 @@
import { contentType } from "jsr:@std/media-types";
import { transpile } from "jsr:@deno/emit";
import config from "./deno.json" with { type: "json" };

const jsContentType = contentType(".js");

export enum MediaType {
TypeScript,
JSX,
TSX,
};

// https://github.com/denoland/deno_ast/blob/ea1ccec37e1aa8e5e1e70f983a7ed1472d0e132a/src/media_type.rs#L117
const customContentType = {
[MediaType.TypeScript]: "text/typescript; charset=utf-8",
[MediaType.JSX]: "text/jsx; charset=utf-8",
[MediaType.TSX]: "text/tsx; charset=utf-8",
};

async function rewriteTsResponse(response: Response, url: URL, mediaType: MediaType) {
const tsCode = await response.text();
const targetUrlStr = url.toString();
try {
const result = await transpile(url, {
importMap: config,
compilerOptions: config.compilerOptions,
load(specifier) {
if (specifier !== targetUrlStr) {
return Promise.resolve({
kind: "module",
specifier,
content: "",
headers: { "content-type": "application/javascript; charset=utf-8" },
});
} else {
return Promise.resolve({
kind: "module",
specifier,
content: tsCode,
headers: {
"content-type": customContentType[mediaType],
},
});
}
},
});
const jsCode = result.get(targetUrlStr);
const { headers } = response;
headers.set("content-type", jsContentType);
headers.delete("content-length");

return new Response(jsCode, {
status: response.status,
statusText: response.statusText,
headers,
});
} catch (e) {
console.error(e);
return new Response(`${e}`, {
status: 500,
statusText: `${e}`,
headers: response.headers,
});
}
}

export default async function transpileResponse(response: Response, requestUrl: string, filepath?: string): Promise<Response> {
const url = new URL(`ts-serve:///${ requestUrl }`);
if (response.status !== 200) {
return response;
}
const pathname = filepath !== undefined ? filepath : url.pathname;
const extension = pathname.split('.').at(-1) ?? null;
switch (extension) {
case 'ts': return await rewriteTsResponse(response, url, MediaType.TypeScript);
case 'tsx': return await rewriteTsResponse(response, url, MediaType.TSX);
case 'jsx': return await rewriteTsResponse(response, url, MediaType.JSX);
default: return response;
}
}

Notiek ielāde…
Atcelt
Saglabāt