@api.global/typedserver
Version:
A TypeScript-based project for easy serving of static files with support for live reloading, compression, and typed requests.
100 lines • 9.17 kB
JavaScript
import * as plugins from '../plugins.js';
import * as paths from '../paths.js';
import * as interfaces from '../../dist_ts_interfaces/index.js';
// Lazy-loaded service worker bundle content
let swBundleJs = null;
let swBundleJsMap = null;
const loadServiceWorkerBundle = async () => {
if (swBundleJs === null) {
swBundleJs = (await plugins.fsInstance
.file(plugins.path.join(paths.serviceworkerBundleDir, './serviceworker.bundle.js'))
.encoding('utf8')
.read());
}
if (swBundleJsMap === null) {
swBundleJsMap = (await plugins.fsInstance
.file(plugins.path.join(paths.serviceworkerBundleDir, './serviceworker.bundle.js.map'))
.encoding('utf8')
.read());
}
};
let swVersionInfo = null;
export const addServiceWorkerRoute = (typedserverInstance, swDataFunc) => {
// Set the version info
swVersionInfo = swDataFunc();
// Handler function for serviceworker bundle requests
const handleServiceWorkerRequest = async (request) => {
await loadServiceWorkerBundle();
const url = new URL(request.url);
const path = url.pathname;
if (path === '/serviceworker/serviceworker.bundle.js' || path === '/serviceworker.bundle.js') {
return new Response(swBundleJs + '\n' + `/** appSemVer: ${swVersionInfo?.appSemVer || 'not set'} */`, {
status: 200,
headers: { 'Content-Type': 'text/javascript' },
});
}
else if (path === '/serviceworker/serviceworker.bundle.js.map' ||
path === '/serviceworker.bundle.js.map') {
return new Response(swBundleJsMap, {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
return null;
};
// Service worker bundle handler - nested path
typedserverInstance.addRoute('/serviceworker/*splat', 'GET', handleServiceWorkerRequest);
// Service worker bundle handler - root level (for /serviceworker.bundle.js)
typedserverInstance.addRoute('/serviceworker.bundle.js', 'GET', handleServiceWorkerRequest);
typedserverInstance.addRoute('/serviceworker.bundle.js.map', 'GET', handleServiceWorkerRequest);
// Typed request handler for service worker
typedserverInstance.addRoute('/sw-typedrequest', 'POST', async (request) => {
try {
const body = await request.json();
// Create a local typed router for service worker requests
const typedrouter = new plugins.typedrequest.TypedRouter();
typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('serviceworker_versionInfo', async () => {
return swDataFunc();
}));
// Speedtest handler for measuring connection speed (time-based chunked approach)
typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('serviceworker_speedtest', async (reqArg) => {
const chunkSizeKB = reqArg.chunkSizeKB || 64;
const sizeBytes = chunkSizeKB * 1024;
let payload;
let bytesTransferred = 0;
switch (reqArg.type) {
case 'download_chunk':
// Generate chunk payload for download test
payload = 'x'.repeat(sizeBytes);
bytesTransferred = sizeBytes;
break;
case 'upload_chunk':
// For upload, measure bytes received from client
bytesTransferred = reqArg.payload?.length || 0;
break;
case 'latency':
// Simple ping - no payload needed
bytesTransferred = 0;
break;
}
return {
bytesTransferred,
timestamp: Date.now(),
payload, // Only for download_chunk tests
};
}));
const response = await typedrouter.routeAndAddResponse(body);
return new Response(plugins.smartjson.stringify(response), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
catch (error) {
return new Response(JSON.stringify({ error: 'Invalid request' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
});
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHMuc2VydmljZXdvcmtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3NlcnZlcnRvb2xzL3Rvb2xzLnNlcnZpY2V3b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxLQUFLLEtBQUssTUFBTSxhQUFhLENBQUM7QUFFckMsT0FBTyxLQUFLLFVBQVUsTUFBTSxtQ0FBbUMsQ0FBQztBQUdoRSw0Q0FBNEM7QUFDNUMsSUFBSSxVQUFVLEdBQWtCLElBQUksQ0FBQztBQUNyQyxJQUFJLGFBQWEsR0FBa0IsSUFBSSxDQUFDO0FBRXhDLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxJQUFtQixFQUFFO0lBQ3hELElBQUksVUFBVSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3hCLFVBQVUsR0FBRyxDQUFDLE1BQU0sT0FBTyxDQUFDLFVBQVU7YUFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO2FBQ2xGLFFBQVEsQ0FBQyxNQUFNLENBQUM7YUFDaEIsSUFBSSxFQUFFLENBQVcsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBSSxhQUFhLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDM0IsYUFBYSxHQUFHLENBQUMsTUFBTSxPQUFPLENBQUMsVUFBVTthQUN0QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLCtCQUErQixDQUFDLENBQUM7YUFDdEYsUUFBUSxDQUFDLE1BQU0sQ0FBQzthQUNoQixJQUFJLEVBQUUsQ0FBVyxDQUFDO0lBQ3ZCLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixJQUFJLGFBQWEsR0FDZixJQUFJLENBQUM7QUFFUCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUNuQyxt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