@davidsouther/jiffies 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/assert.d.ts +23 -23
- package/build/assert.js +33 -33
- package/build/case.d.ts +1 -1
- package/build/case.js +5 -5
- package/build/components/button_bar.d.ts +8 -8
- package/build/components/button_bar.js +27 -27
- package/build/components/inline_edit.d.ts +12 -12
- package/build/components/inline_edit.js +48 -48
- package/build/components/logger.d.ts +6 -7
- package/build/components/logger.js +22 -22
- package/build/components/select.d.ts +13 -10
- package/build/components/select.js +3 -3
- package/build/components/test.d.ts +1 -1
- package/build/components/test.js +2 -2
- package/build/components/virtual_scroll.d.ts +40 -41
- package/build/components/virtual_scroll.js +94 -94
- package/build/components/virtual_scroll.test.d.ts +1 -1
- package/build/components/virtual_scroll.test.js +21 -21
- package/build/context.d.ts +15 -15
- package/build/context.js +43 -43
- package/build/context.test.d.ts +1 -1
- package/build/context.test.js +46 -46
- package/build/debounce.d.ts +1 -1
- package/build/debounce.js +7 -7
- package/build/display.d.ts +5 -5
- package/build/display.js +11 -11
- package/build/dom/css/border.d.ts +11 -11
- package/build/dom/css/border.js +27 -27
- package/build/dom/css/constants.d.ts +31 -31
- package/build/dom/css/constants.js +28 -28
- package/build/dom/css/core.d.ts +5 -5
- package/build/dom/css/core.js +24 -24
- package/build/dom/css/fstyle.d.ts +5 -5
- package/build/dom/css/fstyle.js +32 -32
- package/build/dom/css/sizing.d.ts +5 -5
- package/build/dom/css/sizing.js +10 -10
- package/build/dom/dom.d.ts +26 -27
- package/build/dom/dom.js +95 -95
- package/build/dom/fc.d.ts +14 -14
- package/build/dom/fc.js +36 -35
- package/build/dom/fc.test.d.ts +1 -1
- package/build/dom/fc.test.js +21 -21
- package/build/dom/form/form.app.d.ts +1 -1
- package/build/dom/form/form.app.js +23 -23
- package/build/dom/form/form.d.ts +26 -26
- package/build/dom/form/form.js +34 -34
- package/build/dom/form/form.test.js +1 -1
- package/build/dom/html.d.ts +113 -117
- package/build/dom/html.js +114 -114
- package/build/dom/html.test.d.ts +1 -1
- package/build/dom/html.test.js +58 -58
- package/build/dom/provide.d.ts +3 -3
- package/build/dom/provide.js +7 -7
- package/build/dom/router/link.d.ts +6 -6
- package/build/dom/router/link.js +3 -3
- package/build/dom/router/router.d.ts +12 -12
- package/build/dom/router/router.js +49 -49
- package/build/dom/svg.d.ts +64 -64
- package/build/dom/svg.js +65 -65
- package/build/dom/test.d.ts +1 -1
- package/build/dom/test.js +2 -2
- package/build/dom/types/css.d.ts +6612 -6612
- package/build/dom/types/css.js +23 -23
- package/build/dom/types/dom.js +1 -1
- package/build/dom/types/html.d.ts +616 -616
- package/build/dom/types/html.js +1 -1
- package/build/dom/xml.d.ts +1 -1
- package/build/dom/xml.js +4 -5
- package/build/equal.d.ts +5 -5
- package/build/equal.js +37 -37
- package/build/equal.test.d.ts +1 -1
- package/build/equal.test.js +20 -20
- package/build/flags.d.ts +7 -7
- package/build/flags.js +48 -48
- package/build/flags.test.d.ts +1 -1
- package/build/flags.test.js +35 -35
- package/build/fs.d.ts +48 -48
- package/build/fs.js +144 -144
- package/build/fs.test.d.ts +1 -1
- package/build/fs.test.js +43 -43
- package/build/generator.d.ts +1 -1
- package/build/generator.js +10 -10
- package/build/generator.test.d.ts +1 -1
- package/build/generator.test.js +24 -24
- package/build/is_browser.d.ts +1 -1
- package/build/is_browser.js +1 -1
- package/build/loader.d.mts +22 -22
- package/build/loader.mjs +35 -35
- package/build/lock.d.ts +1 -1
- package/build/lock.js +23 -23
- package/build/lock.test.d.ts +1 -1
- package/build/lock.test.js +16 -16
- package/build/log.d.ts +26 -26
- package/build/log.js +46 -46
- package/build/observable/observable.d.ts +83 -0
- package/build/observable/observable.js +148 -0
- package/build/observable/observable.test.d.ts +1 -0
- package/build/observable/observable.test.js +21 -0
- package/build/range.d.ts +1 -1
- package/build/range.js +7 -7
- package/build/result.d.ts +31 -31
- package/build/result.js +65 -65
- package/build/result.test.d.ts +1 -1
- package/build/result.test.js +71 -71
- package/build/safe.d.ts +1 -1
- package/build/safe.js +10 -10
- package/build/scope/describe.d.ts +18 -14
- package/build/scope/describe.js +61 -52
- package/build/scope/display/console.d.ts +2 -2
- package/build/scope/display/console.js +21 -21
- package/build/scope/display/dom.d.ts +3 -3
- package/build/scope/display/dom.js +26 -26
- package/build/scope/display/junit.d.ts +2 -2
- package/build/scope/display/junit.js +17 -17
- package/build/scope/execute.d.ts +12 -12
- package/build/scope/execute.js +85 -85
- package/build/scope/expect.d.ts +23 -23
- package/build/scope/expect.js +108 -108
- package/build/scope/fix.d.ts +4 -4
- package/build/scope/fix.js +22 -22
- package/build/scope/index.d.ts +3 -3
- package/build/scope/index.js +3 -3
- package/build/scope/scope.d.ts +17 -17
- package/build/scope/scope.js +1 -1
- package/build/server/http/apps.d.ts +5 -5
- package/build/server/http/apps.js +23 -23
- package/build/server/http/css.d.ts +5 -5
- package/build/server/http/css.js +50 -47
- package/build/server/http/index.d.ts +21 -21
- package/build/server/http/index.js +73 -73
- package/build/server/http/response.d.ts +4 -4
- package/build/server/http/response.js +40 -40
- package/build/server/http/sitemap.d.ts +2 -2
- package/build/server/http/sitemap.js +42 -42
- package/build/server/http/static.d.ts +2 -2
- package/build/server/http/static.js +21 -21
- package/build/server/http/typescript.d.ts +5 -5
- package/build/server/http/typescript.js +40 -40
- package/build/server/main.d.ts +2 -2
- package/build/server/main.js +9 -9
- package/build/test.d.mts +2 -2
- package/build/test.mjs +23 -23
- package/build/test_all.d.ts +7 -7
- package/build/test_all.js +18 -18
- package/build/transpile.d.mts +3 -3
- package/build/transpile.mjs +18 -18
- package/package.json +3 -3
- package/src/components/logger.ts +2 -3
- package/src/components/virtual_scroll.test.ts +4 -4
- package/src/components/virtual_scroll.ts +8 -8
- package/src/diff.test.ts +48 -0
- package/src/diff.ts +84 -0
- package/src/dom/dom.ts +73 -61
- package/src/dom/fc.ts +10 -9
- package/src/dom/html.test.ts +5 -5
- package/src/dom/html.ts +7 -10
- package/src/dom/observable.test.ts +43 -0
- package/src/dom/observable.ts +11 -0
- package/src/dom/router/router.ts +4 -4
- package/src/dom/test.ts +5 -1
- package/src/dom/xml.ts +1 -2
- package/src/index.html +6 -3
- package/src/observable/_notes +21 -8
- package/src/observable/event.ts +93 -0
- package/src/observable/observable.test.ts +73 -0
- package/src/observable/observable.ts +403 -0
- package/src/scope/describe.ts +14 -1
- package/src/scope/display/dom.ts +2 -2
- package/src/scope/execute.ts +2 -5
- package/src/server/http/css.ts +3 -1
- package/src/test_all.ts +10 -8
- package/src/observable/observable._js +0 -175
package/build/server/http/css.js
CHANGED
|
@@ -1,47 +1,50 @@
|
|
|
1
|
-
import * as fs from "fs/promises";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import { contentResponse } from "./response.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// .replaceAll(`
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { contentResponse } from "./response.js";
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import sass from "sass";
|
|
6
|
+
const { compileStringAsync } = sass;
|
|
7
|
+
function render(source) {
|
|
8
|
+
// Replace `from "@scope` with `from "/@scope`, for browsers
|
|
9
|
+
// source = source
|
|
10
|
+
// .replaceAll(`from "@`, 'from "/@')
|
|
11
|
+
// .replaceAll(`import("@`, 'import("/@');
|
|
12
|
+
return contentResponse(source, "text/css");
|
|
13
|
+
}
|
|
14
|
+
async function compile(filename, root, vars) {
|
|
15
|
+
vars = vars.substring(1).replaceAll("=", ":");
|
|
16
|
+
filename = filename.replaceAll("\\", "/"); // Normalize for dart-sass
|
|
17
|
+
const sassString = `// Using variables: ${vars}\n${vars};\n@import "${filename}";`;
|
|
18
|
+
return (await compileStringAsync(sassString, { loadPaths: [root] })).css;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Serves .css files statically. Finds .sass files and transpiles them to css.
|
|
22
|
+
*/
|
|
23
|
+
export const cssFileServer = async ({ root, scopes = {} }) => async (req) => {
|
|
24
|
+
const Url = new URL(req.url ?? "/", `http://${req.headers.host}`);
|
|
25
|
+
if (Url.pathname.endsWith(".css")) {
|
|
26
|
+
let scope = Object.entries(scopes).find(([s]) => Url.pathname.startsWith(`/${s}`));
|
|
27
|
+
// Expand url with found scope
|
|
28
|
+
Url.protocol = "file";
|
|
29
|
+
let url = scope ? Url.pathname.replace(scope[0], scope[1]) : Url.pathname;
|
|
30
|
+
let filename = path.join(root, url);
|
|
31
|
+
try {
|
|
32
|
+
const stat = await fs.stat(filename);
|
|
33
|
+
if (stat.isFile()) {
|
|
34
|
+
const css = (await fs.readFile(filename)).toString("utf-8");
|
|
35
|
+
return render(css);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
filename = filename.replace(/\.css$/, ".scss");
|
|
40
|
+
try {
|
|
41
|
+
const stat = await fs.stat(filename);
|
|
42
|
+
if (stat.isFile()) {
|
|
43
|
+
const css = await compile(filename.replace(root, "."), root, Url.search);
|
|
44
|
+
return render(css);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/// <reference types="node" />
|
|
4
|
-
import { IncomingMessage } from "http";
|
|
5
|
-
export interface StaticResponse {
|
|
6
|
-
status: 200 | 404 | 500;
|
|
7
|
-
content: Buffer;
|
|
8
|
-
contentType: string;
|
|
9
|
-
contentLength?: number;
|
|
10
|
-
}
|
|
11
|
-
export interface ServerConfig {
|
|
12
|
-
root: string;
|
|
13
|
-
scopes?: Record<`@${string}`, string>;
|
|
14
|
-
}
|
|
15
|
-
export interface MiddlewareFactory {
|
|
16
|
-
(config: ServerConfig): Promise<StaticMiddleware>;
|
|
17
|
-
}
|
|
18
|
-
export interface StaticMiddleware {
|
|
19
|
-
(req: IncomingMessage): Promise<undefined | (() => Promise<StaticResponse>)>;
|
|
20
|
-
}
|
|
21
|
-
export declare const makeServer: (config: ServerConfig, middlewares?: MiddlewareFactory[]) => Promise<import("http").Server>;
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
4
|
+
import { IncomingMessage } from "http";
|
|
5
|
+
export interface StaticResponse {
|
|
6
|
+
status: 200 | 404 | 500;
|
|
7
|
+
content: Buffer;
|
|
8
|
+
contentType: string;
|
|
9
|
+
contentLength?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ServerConfig {
|
|
12
|
+
root: string;
|
|
13
|
+
scopes?: Record<`@${string}`, string>;
|
|
14
|
+
}
|
|
15
|
+
export interface MiddlewareFactory {
|
|
16
|
+
(config: ServerConfig): Promise<StaticMiddleware>;
|
|
17
|
+
}
|
|
18
|
+
export interface StaticMiddleware {
|
|
19
|
+
(req: IncomingMessage): Promise<undefined | (() => Promise<StaticResponse>)>;
|
|
20
|
+
}
|
|
21
|
+
export declare const makeServer: (config: ServerConfig, middlewares?: MiddlewareFactory[]) => Promise<import("http").Server>;
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createServer, } from "http";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import { info } from "../../log.js";
|
|
5
|
-
import { findIndex } from "./apps.js";
|
|
6
|
-
import { cssFileServer } from "./css.js";
|
|
7
|
-
import { fileResponse } from "./response.js";
|
|
8
|
-
import { sitemap } from "./sitemap.js";
|
|
9
|
-
import { staticFileServer } from "./static.js";
|
|
10
|
-
import { tsFileServer } from "./typescript.js";
|
|
11
|
-
const notFound = async ({ root }) => async () => fileResponse(
|
|
12
|
-
// path.join(path.dirname(FLAGS.argv0), "404.html"),
|
|
13
|
-
path.join(root, "404.html"), undefined, 404);
|
|
14
|
-
const BASE_MIDDLEWARES = [
|
|
15
|
-
sitemap,
|
|
16
|
-
tsFileServer,
|
|
17
|
-
cssFileServer,
|
|
18
|
-
staticFileServer,
|
|
19
|
-
findIndex,
|
|
20
|
-
notFound,
|
|
21
|
-
];
|
|
22
|
-
const error = (res, message) => {
|
|
23
|
-
console.error(message);
|
|
24
|
-
res.statusCode = 500;
|
|
25
|
-
res.write(message);
|
|
26
|
-
res.end();
|
|
27
|
-
return true;
|
|
28
|
-
};
|
|
29
|
-
const sendContent = async (res, { content, contentType, contentLength }) => {
|
|
30
|
-
res.setHeader("Content-Length", `${contentLength}`);
|
|
31
|
-
res.setHeader("Content-Type", contentType);
|
|
32
|
-
await res.write(content);
|
|
33
|
-
res.end();
|
|
34
|
-
return true;
|
|
35
|
-
};
|
|
36
|
-
const log = (req) => {
|
|
37
|
-
const when = new Date().toISOString();
|
|
38
|
-
const who = req.socket.remoteAddress;
|
|
39
|
-
const what = req.url;
|
|
40
|
-
const how = `${req.method} ${what}`;
|
|
41
|
-
info("Request", { when, who, how });
|
|
42
|
-
};
|
|
43
|
-
export const makeServer = async (config, middlewares = []) => {
|
|
44
|
-
const handlers = await Promise.all([...middlewares, ...BASE_MIDDLEWARES].map(async (m) => m(config)));
|
|
45
|
-
const middlewareHandler = async (req, res) => {
|
|
46
|
-
log(req);
|
|
47
|
-
let handler;
|
|
48
|
-
try {
|
|
49
|
-
for (const middleware of handlers) {
|
|
50
|
-
handler = await middleware(req);
|
|
51
|
-
if (handler !== undefined) {
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (handler) {
|
|
56
|
-
sendContent(res, await handler());
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
res.end();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch (e) {
|
|
63
|
-
error(res, e.message + "\n" + e.stack);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
// TODO(https)
|
|
67
|
-
const server = createServer(middlewareHandler);
|
|
68
|
-
server.on("listening", () => {
|
|
69
|
-
const { address, port } = server.address();
|
|
70
|
-
info("Server listening", { address: `http://${address}:${port}` });
|
|
71
|
-
});
|
|
72
|
-
return server;
|
|
73
|
-
};
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer, } from "http";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { info } from "../../log.js";
|
|
5
|
+
import { findIndex } from "./apps.js";
|
|
6
|
+
import { cssFileServer } from "./css.js";
|
|
7
|
+
import { fileResponse } from "./response.js";
|
|
8
|
+
import { sitemap } from "./sitemap.js";
|
|
9
|
+
import { staticFileServer } from "./static.js";
|
|
10
|
+
import { tsFileServer } from "./typescript.js";
|
|
11
|
+
const notFound = async ({ root }) => async () => fileResponse(
|
|
12
|
+
// path.join(path.dirname(FLAGS.argv0), "404.html"),
|
|
13
|
+
path.join(root, "404.html"), undefined, 404);
|
|
14
|
+
const BASE_MIDDLEWARES = [
|
|
15
|
+
sitemap,
|
|
16
|
+
tsFileServer,
|
|
17
|
+
cssFileServer,
|
|
18
|
+
staticFileServer,
|
|
19
|
+
findIndex,
|
|
20
|
+
notFound,
|
|
21
|
+
];
|
|
22
|
+
const error = (res, message) => {
|
|
23
|
+
console.error(message);
|
|
24
|
+
res.statusCode = 500;
|
|
25
|
+
res.write(message);
|
|
26
|
+
res.end();
|
|
27
|
+
return true;
|
|
28
|
+
};
|
|
29
|
+
const sendContent = async (res, { content, contentType, contentLength }) => {
|
|
30
|
+
res.setHeader("Content-Length", `${contentLength}`);
|
|
31
|
+
res.setHeader("Content-Type", contentType);
|
|
32
|
+
await res.write(content);
|
|
33
|
+
res.end();
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
const log = (req) => {
|
|
37
|
+
const when = new Date().toISOString();
|
|
38
|
+
const who = req.socket.remoteAddress;
|
|
39
|
+
const what = req.url;
|
|
40
|
+
const how = `${req.method} ${what}`;
|
|
41
|
+
info("Request", { when, who, how });
|
|
42
|
+
};
|
|
43
|
+
export const makeServer = async (config, middlewares = []) => {
|
|
44
|
+
const handlers = await Promise.all([...middlewares, ...BASE_MIDDLEWARES].map(async (m) => m(config)));
|
|
45
|
+
const middlewareHandler = async (req, res) => {
|
|
46
|
+
log(req);
|
|
47
|
+
let handler;
|
|
48
|
+
try {
|
|
49
|
+
for (const middleware of handlers) {
|
|
50
|
+
handler = await middleware(req);
|
|
51
|
+
if (handler !== undefined) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (handler) {
|
|
56
|
+
sendContent(res, await handler());
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
res.end();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
error(res, e.message + "\n" + e.stack);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
// TODO(https)
|
|
67
|
+
const server = createServer(middlewareHandler);
|
|
68
|
+
server.on("listening", () => {
|
|
69
|
+
const { address, port } = server.address();
|
|
70
|
+
info("Server listening", { address: `http://${address}:${port}` });
|
|
71
|
+
});
|
|
72
|
+
return server;
|
|
73
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Stats } from "fs";
|
|
2
|
-
import { StaticResponse } from ".";
|
|
3
|
-
export declare const fileResponse: (filename: string, stat?: Stats, status?: 200 | 404 | 500) => () => Promise<StaticResponse>;
|
|
4
|
-
export declare const contentResponse: (content: string, contentType: string, status?: 200 | 404 | 500) => () => Promise<StaticResponse>;
|
|
1
|
+
import { Stats } from "fs";
|
|
2
|
+
import { StaticResponse } from ".";
|
|
3
|
+
export declare const fileResponse: (filename: string, stat?: Stats, status?: 200 | 404 | 500) => () => Promise<StaticResponse>;
|
|
4
|
+
export declare const contentResponse: (content: string, contentType: string, status?: 200 | 404 | 500) => () => Promise<StaticResponse>;
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import * as fs from "fs/promises";
|
|
2
|
-
const MIME_TYPES = {
|
|
3
|
-
js: "text/javascript",
|
|
4
|
-
json: "text/javascript",
|
|
5
|
-
css: "text/css",
|
|
6
|
-
html: "text/html",
|
|
7
|
-
png: "image/png",
|
|
8
|
-
jpg: "image/jpeg",
|
|
9
|
-
jpeg: "image/jpeg",
|
|
10
|
-
svg: "image/svg+xml",
|
|
11
|
-
eot: "application/vnd.ms-fontobject",
|
|
12
|
-
ttf: "application/font-ttf",
|
|
13
|
-
woff: "application/font-woff",
|
|
14
|
-
woff2: "application/font-woff2",
|
|
15
|
-
};
|
|
16
|
-
const mime = (basename) => {
|
|
17
|
-
const extension = basename
|
|
18
|
-
.substring(basename.lastIndexOf(".") + 1)
|
|
19
|
-
.toLowerCase();
|
|
20
|
-
return MIME_TYPES[extension] ?? "application/octet-stream";
|
|
21
|
-
};
|
|
22
|
-
export const fileResponse = (filename, stat, status = 200) => async () => {
|
|
23
|
-
if (!stat) {
|
|
24
|
-
stat = await fs.stat(filename);
|
|
25
|
-
}
|
|
26
|
-
const content = await fs.readFile(filename);
|
|
27
|
-
const contentType = mime(filename);
|
|
28
|
-
const contentLength = stat.size;
|
|
29
|
-
return { status, contentType, contentLength, content };
|
|
30
|
-
};
|
|
31
|
-
const CHARSET = "utf-8";
|
|
32
|
-
export const contentResponse = (content, contentType, status = 200) => async () => {
|
|
33
|
-
const contentBuffer = Buffer.from(content, CHARSET);
|
|
34
|
-
return {
|
|
35
|
-
content: contentBuffer,
|
|
36
|
-
contentType: contentType.split(";")[0] + "; charset=" + CHARSET,
|
|
37
|
-
status,
|
|
38
|
-
contentLength: contentBuffer.length,
|
|
39
|
-
};
|
|
40
|
-
};
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
const MIME_TYPES = {
|
|
3
|
+
js: "text/javascript",
|
|
4
|
+
json: "text/javascript",
|
|
5
|
+
css: "text/css",
|
|
6
|
+
html: "text/html",
|
|
7
|
+
png: "image/png",
|
|
8
|
+
jpg: "image/jpeg",
|
|
9
|
+
jpeg: "image/jpeg",
|
|
10
|
+
svg: "image/svg+xml",
|
|
11
|
+
eot: "application/vnd.ms-fontobject",
|
|
12
|
+
ttf: "application/font-ttf",
|
|
13
|
+
woff: "application/font-woff",
|
|
14
|
+
woff2: "application/font-woff2",
|
|
15
|
+
};
|
|
16
|
+
const mime = (basename) => {
|
|
17
|
+
const extension = basename
|
|
18
|
+
.substring(basename.lastIndexOf(".") + 1)
|
|
19
|
+
.toLowerCase();
|
|
20
|
+
return MIME_TYPES[extension] ?? "application/octet-stream";
|
|
21
|
+
};
|
|
22
|
+
export const fileResponse = (filename, stat, status = 200) => async () => {
|
|
23
|
+
if (!stat) {
|
|
24
|
+
stat = await fs.stat(filename);
|
|
25
|
+
}
|
|
26
|
+
const content = await fs.readFile(filename);
|
|
27
|
+
const contentType = mime(filename);
|
|
28
|
+
const contentLength = stat.size;
|
|
29
|
+
return { status, contentType, contentLength, content };
|
|
30
|
+
};
|
|
31
|
+
const CHARSET = "utf-8";
|
|
32
|
+
export const contentResponse = (content, contentType, status = 200) => async () => {
|
|
33
|
+
const contentBuffer = Buffer.from(content, CHARSET);
|
|
34
|
+
return {
|
|
35
|
+
content: contentBuffer,
|
|
36
|
+
contentType: contentType.split(";")[0] + "; charset=" + CHARSET,
|
|
37
|
+
status,
|
|
38
|
+
contentLength: contentBuffer.length,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MiddlewareFactory } from "./index.js";
|
|
2
|
-
export declare const sitemap: MiddlewareFactory;
|
|
1
|
+
import { MiddlewareFactory } from "./index.js";
|
|
2
|
+
export declare const sitemap: MiddlewareFactory;
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import * as fs from "fs/promises";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import { info } from "../../log.js";
|
|
4
|
-
import { contentResponse } from "./response.js";
|
|
5
|
-
const findSiteMap = async (root, prefix = root) => {
|
|
6
|
-
if (root.startsWith("node_modules")) {
|
|
7
|
-
return [];
|
|
8
|
-
}
|
|
9
|
-
const children = (await fs.readdir(root, { withFileTypes: true })).map(async (entry) => {
|
|
10
|
-
const next = path
|
|
11
|
-
.join(root, entry.name)
|
|
12
|
-
// Normalize separators for web
|
|
13
|
-
.replaceAll(path.sep, "/");
|
|
14
|
-
if (entry.isFile()) {
|
|
15
|
-
if (entry.name === "index.html") {
|
|
16
|
-
let index = next.replace(prefix, "");
|
|
17
|
-
info(`Adding to sitemap`, { index });
|
|
18
|
-
return [index];
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
else if (entry.isDirectory()) {
|
|
22
|
-
if (entry.name.startsWith(".")) {
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
const flattened = (await Promise.all(await findSiteMap(next, prefix))).flat();
|
|
26
|
-
return flattened;
|
|
27
|
-
}
|
|
28
|
-
return [];
|
|
29
|
-
});
|
|
30
|
-
return children;
|
|
31
|
-
};
|
|
32
|
-
export const sitemap = async ({ root }) => {
|
|
33
|
-
const apps = await (await Promise.all(await findSiteMap(root)))
|
|
34
|
-
.flat()
|
|
35
|
-
.filter((a) => a !== undefined);
|
|
36
|
-
return async (req) => {
|
|
37
|
-
if ((req.url ?? "").endsWith("sitemap.json")) {
|
|
38
|
-
return contentResponse(JSON.stringify(apps), "application/json");
|
|
39
|
-
}
|
|
40
|
-
return undefined;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { info } from "../../log.js";
|
|
4
|
+
import { contentResponse } from "./response.js";
|
|
5
|
+
const findSiteMap = async (root, prefix = root) => {
|
|
6
|
+
if (root.startsWith("node_modules")) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const children = (await fs.readdir(root, { withFileTypes: true })).map(async (entry) => {
|
|
10
|
+
const next = path
|
|
11
|
+
.join(root, entry.name)
|
|
12
|
+
// Normalize separators for web
|
|
13
|
+
.replaceAll(path.sep, "/");
|
|
14
|
+
if (entry.isFile()) {
|
|
15
|
+
if (entry.name === "index.html") {
|
|
16
|
+
let index = next.replace(prefix, "");
|
|
17
|
+
info(`Adding to sitemap`, { index });
|
|
18
|
+
return [index];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else if (entry.isDirectory()) {
|
|
22
|
+
if (entry.name.startsWith(".")) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const flattened = (await Promise.all(await findSiteMap(next, prefix))).flat();
|
|
26
|
+
return flattened;
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
29
|
+
});
|
|
30
|
+
return children;
|
|
31
|
+
};
|
|
32
|
+
export const sitemap = async ({ root }) => {
|
|
33
|
+
const apps = await (await Promise.all(await findSiteMap(root)))
|
|
34
|
+
.flat()
|
|
35
|
+
.filter((a) => a !== undefined);
|
|
36
|
+
return async (req) => {
|
|
37
|
+
if ((req.url ?? "").endsWith("sitemap.json")) {
|
|
38
|
+
return contentResponse(JSON.stringify(apps), "application/json");
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { MiddlewareFactory } from "./index.js";
|
|
2
|
-
export declare const staticFileServer: MiddlewareFactory;
|
|
1
|
+
import type { MiddlewareFactory } from "./index.js";
|
|
2
|
+
export declare const staticFileServer: MiddlewareFactory;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import * as path from "path";
|
|
2
|
-
import * as fs from "fs/promises";
|
|
3
|
-
import { fileResponse } from "./response.js";
|
|
4
|
-
export const staticFileServer = async ({ root, scopes = {} }) => async (req) => {
|
|
5
|
-
const scope = Object.entries(scopes).find(([s]) => req.url?.startsWith(`/${s}`));
|
|
6
|
-
const url = new URL(req.url ?? "", `http://localhost`);
|
|
7
|
-
const pathname = scope
|
|
8
|
-
? url.pathname.replace(scope[0], scope[1])
|
|
9
|
-
: url.pathname;
|
|
10
|
-
const filename = path.join(root, pathname);
|
|
11
|
-
// Expand url with found scope
|
|
12
|
-
console.log(scope, req.url, filename);
|
|
13
|
-
try {
|
|
14
|
-
const stat = await fs.stat(filename);
|
|
15
|
-
return stat.isDirectory() ? undefined : fileResponse(filename, stat);
|
|
16
|
-
}
|
|
17
|
-
catch (e) {
|
|
18
|
-
console.error(e);
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import * as fs from "fs/promises";
|
|
3
|
+
import { fileResponse } from "./response.js";
|
|
4
|
+
export const staticFileServer = async ({ root, scopes = {} }) => async (req) => {
|
|
5
|
+
const scope = Object.entries(scopes).find(([s]) => req.url?.startsWith(`/${s}`));
|
|
6
|
+
const url = new URL(req.url ?? "", `http://localhost`);
|
|
7
|
+
const pathname = scope
|
|
8
|
+
? url.pathname.replace(scope[0], scope[1])
|
|
9
|
+
: url.pathname;
|
|
10
|
+
const filename = path.join(root, pathname);
|
|
11
|
+
// Expand url with found scope
|
|
12
|
+
console.log(scope, req.url, filename);
|
|
13
|
+
try {
|
|
14
|
+
const stat = await fs.stat(filename);
|
|
15
|
+
return stat.isDirectory() ? undefined : fileResponse(filename, stat);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
console.error(e);
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MiddlewareFactory } from "./index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Serves .js files statically. Finds .ts files and transpiles them to JS.
|
|
4
|
-
*/
|
|
5
|
-
export declare const tsFileServer: MiddlewareFactory;
|
|
1
|
+
import { MiddlewareFactory } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Serves .js files statically. Finds .ts files and transpiles them to JS.
|
|
4
|
+
*/
|
|
5
|
+
export declare const tsFileServer: MiddlewareFactory;
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import * as fs from "fs/promises";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import { contentResponse } from "./response.js";
|
|
4
|
-
import { transpile } from "../../transpile.mjs";
|
|
5
|
-
function render(source) {
|
|
6
|
-
// Replace `from "@scope` with `from "/@scope`, for browsers
|
|
7
|
-
source = source
|
|
8
|
-
.replaceAll(`from "@`, 'from "/@')
|
|
9
|
-
.replaceAll(`import("@`, 'import("/@');
|
|
10
|
-
return contentResponse(source, "application/javascript");
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Serves .js files statically. Finds .ts files and transpiles them to JS.
|
|
14
|
-
*/
|
|
15
|
-
export const tsFileServer = async ({ root, scopes = {} }) => async (req) => {
|
|
16
|
-
if (req.url?.endsWith(".js")) {
|
|
17
|
-
let scope = Object.entries(scopes).find(([s]) => req.url?.startsWith(`/${s}`));
|
|
18
|
-
// Expand url with found scope
|
|
19
|
-
let url = scope ? req.url.replace(scope[0], scope[1]) : req.url;
|
|
20
|
-
let filename = path.join(root, url);
|
|
21
|
-
try {
|
|
22
|
-
const stat = await fs.stat(filename);
|
|
23
|
-
if (stat.isFile()) {
|
|
24
|
-
const js = (await fs.readFile(filename)).toString("utf-8");
|
|
25
|
-
return render(js);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
catch { }
|
|
29
|
-
filename = filename.replace(/\.js$/, ".ts");
|
|
30
|
-
try {
|
|
31
|
-
const stat = await fs.stat(filename);
|
|
32
|
-
if (stat.isFile()) {
|
|
33
|
-
const js = await transpile(filename, () => fs.readFile(filename));
|
|
34
|
-
return render(js);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
catch { }
|
|
38
|
-
}
|
|
39
|
-
return undefined;
|
|
40
|
-
};
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { contentResponse } from "./response.js";
|
|
4
|
+
import { transpile } from "../../transpile.mjs";
|
|
5
|
+
function render(source) {
|
|
6
|
+
// Replace `from "@scope` with `from "/@scope`, for browsers
|
|
7
|
+
source = source
|
|
8
|
+
.replaceAll(`from "@`, 'from "/@')
|
|
9
|
+
.replaceAll(`import("@`, 'import("/@');
|
|
10
|
+
return contentResponse(source, "application/javascript");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Serves .js files statically. Finds .ts files and transpiles them to JS.
|
|
14
|
+
*/
|
|
15
|
+
export const tsFileServer = async ({ root, scopes = {} }) => async (req) => {
|
|
16
|
+
if (req.url?.endsWith(".js")) {
|
|
17
|
+
let scope = Object.entries(scopes).find(([s]) => req.url?.startsWith(`/${s}`));
|
|
18
|
+
// Expand url with found scope
|
|
19
|
+
let url = scope ? req.url.replace(scope[0], scope[1]) : req.url;
|
|
20
|
+
let filename = path.join(root, url);
|
|
21
|
+
try {
|
|
22
|
+
const stat = await fs.stat(filename);
|
|
23
|
+
if (stat.isFile()) {
|
|
24
|
+
const js = (await fs.readFile(filename)).toString("utf-8");
|
|
25
|
+
return render(js);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
filename = filename.replace(/\.js$/, ".ts");
|
|
30
|
+
try {
|
|
31
|
+
const stat = await fs.stat(filename);
|
|
32
|
+
if (stat.isFile()) {
|
|
33
|
+
const js = await transpile(filename, () => fs.readFile(filename));
|
|
34
|
+
return render(js);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
};
|
package/build/server/main.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node --experimental-loader ../loader.mjs
|
|
2
|
-
export {};
|
|
1
|
+
#!/usr/bin/env node --experimental-loader ../loader.mjs
|
|
2
|
+
export {};
|
package/build/server/main.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#!/usr/bin/env node --experimental-loader ../loader.mjs
|
|
2
|
-
import { info } from "../log.js";
|
|
3
|
-
info("Starting server", { cwd: process.cwd() });
|
|
4
|
-
import { parse } from "../flags.js";
|
|
5
|
-
const FLAGS = parse(process.argv);
|
|
6
|
-
import { makeServer } from "./http/index.js";
|
|
7
|
-
import * as path from "node:path";
|
|
8
|
-
const server = await makeServer({ root: path.join(process.cwd(), "src") });
|
|
9
|
-
server.listen(FLAGS.asNumber("port", 8080), FLAGS.asString("host", "0.0.0.0"));
|
|
1
|
+
#!/usr/bin/env node --experimental-loader ../loader.mjs
|
|
2
|
+
import { info } from "../log.js";
|
|
3
|
+
info("Starting server", { cwd: process.cwd() });
|
|
4
|
+
import { parse } from "../flags.js";
|
|
5
|
+
const FLAGS = parse(process.argv);
|
|
6
|
+
import { makeServer } from "./http/index.js";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
const server = await makeServer({ root: path.join(process.cwd(), "src") });
|
|
9
|
+
server.listen(FLAGS.asNumber("port", 8080), FLAGS.asString("host", "0.0.0.0"));
|
package/build/test.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
export {};
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export {};
|