Skip to content

Commit 17694c4

Browse files
feat(runtime): add main thread boot script and Service Worker for TypeScript transpilation
1 parent 957cd66 commit 17694c4

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

dist/rawscript.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"use strict";
2+
(() => {
3+
// src/boot.ts
4+
var SW_PATH = "/rawscript-sw.js";
5+
if ("serviceWorker" in navigator) {
6+
navigator.serviceWorker.register(SW_PATH, { type: "module" }).then((reg) => {
7+
if (reg.installing) {
8+
reg.installing.addEventListener("statechange", (e) => {
9+
if (e.target.state === "activated") {
10+
location.reload();
11+
}
12+
});
13+
}
14+
});
15+
}
16+
})();

packages/runtime/build.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// packages/runtime/build.js
22
// Plain JS — runs with Node without compilation
33
import * as esbuild from 'esbuild'
4+
import { cpSync, mkdirSync } from 'fs'
45

56
// Build rawscript.js (main thread boot script — IIFE, self-executing)
67
await esbuild.build({
@@ -26,4 +27,13 @@ await esbuild.build({
2627
external: ['https://unpkg.com/*'],
2728
})
2829

30+
// Copy dist files to repo root so examples work when served from project root
31+
// /dist/rawscript.js — referenced by <script src="/dist/rawscript.js">
32+
// /rawscript-sw.js — SW must be at root for scope to cover all routes
33+
const repoRoot = '../../'
34+
mkdirSync(repoRoot + 'dist', { recursive: true })
35+
cpSync('dist/rawscript.js', repoRoot + 'dist/rawscript.js')
36+
cpSync('dist/rawscript-sw.js', repoRoot + 'rawscript-sw.js')
37+
2938
console.log('✓ rawscript built to dist/')
39+
console.log('✓ copied to repo root for local dev')

rawscript-sw.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// src/transpiler.ts
2+
import * as esbuild from "https://unpkg.com/esbuild-wasm@0.20.2/esm/browser.js";
3+
var initPromise = null;
4+
async function ensureInitialized() {
5+
if (!initPromise) {
6+
initPromise = esbuild.initialize({
7+
wasmURL: "https://unpkg.com/esbuild-wasm@0.20.2/esbuild.wasm",
8+
worker: false
9+
});
10+
}
11+
await initPromise;
12+
}
13+
async function transpile(source, filename) {
14+
await ensureInitialized();
15+
const result = await esbuild.transform(source, {
16+
loader: "ts",
17+
format: "esm",
18+
target: "esnext",
19+
sourcefile: filename,
20+
sourcemap: "inline"
21+
});
22+
return result.code;
23+
}
24+
25+
// src/sw.ts
26+
async function handleFetch(event) {
27+
const url = new URL(event.request.url);
28+
if (url.pathname.endsWith(".ts") || url.pathname.endsWith(".tsx")) {
29+
const response = await fetch(event.request);
30+
const source = await response.text();
31+
const transpiled = await transpile(source, url.pathname);
32+
return new Response(transpiled, {
33+
headers: { "Content-Type": "application/javascript" }
34+
});
35+
}
36+
return fetch(event.request);
37+
}
38+
self.addEventListener("fetch", (event) => {
39+
event.respondWith(handleFetch(event));
40+
});

0 commit comments

Comments
 (0)