Static site hosting via tangled

Rename to baseDir and add readme

+33
README.md
···
+
# tangled-pages
+
+
This gives you a way to host a website via a tangled repo.
+
You can run it as a cloudflare worker or as an express server.
+
+
Create .env:
+
+
```
+
KNOT_DOMAIN=knot.gracekind.net
+
OWNER_DID=did:plc:p572wxnsuoogcrhlfrlizlrb
+
REPO_NAME=static-site-example
+
```
+
+
Run:
+
+
```bash
+
npm install
+
npm start
+
```
+
+
## Config
+
+
You can configure the pages service by creating a `pages_config.yaml` file in the root of the repo.
+
+
```yaml
+
baseDir: "/public"
+
notFoundFilepath: "404.html"
+
```
+
+
## Limitations
+
+
It fetches files from the repo on request, so it might be slow.
+
In the future, we could cache the files and use a CI to update the cache.
+9
example/404.html
···
+
<html>
+
<head>
+
<title>404 Not Found</title>
+
</head>
+
<body>
+
<h1>404 Not Found</h1>
+
<p>This is an example of a custom 404 page.</p>
+
</body>
+
</html>
+9
example/index.html
···
+
<html>
+
<head>
+
<title>Tangled Pages Example</title>
+
</head>
+
<body>
+
<h1>Tangled Pages Example</h1>
+
<p>This is an example of a static page hosted on a tangled repo!</p>
+
</body>
+
</html>
+2
pages_config.yaml
···
+
baseDir: /example
+
notFoundFilepath: /404.html
+9 -6
src/pages-service.js
···
}
class PagesConfig {
-
constructor({ basePath, notFoundFilepath }) {
-
this.basePath = basePath;
+
constructor({ baseDir, notFoundFilepath }) {
+
this.baseDir = baseDir;
this.notFoundFilepath = notFoundFilepath;
}
static default() {
return new PagesConfig({
-
basePath: "/",
+
baseDir: "/",
notFoundFilepath: null,
});
}
···
throw new Error(`Error parsing YAML file ${filePath}: ${error}`);
}
return new PagesConfig({
-
basePath: configObj.basePath || "/",
+
baseDir: configObj.baseDir || "/",
notFoundFilepath: configObj.notFoundFilepath || null,
});
}
···
repoName,
configFilepath = "pages_config.yaml",
verbose = false,
+
fileCacheExpirationSeconds = 10,
}) {
this.ownerDid = ownerDid;
this.repoName = repoName;
this.configFilepath = configFilepath;
this.verbose = verbose;
this.client = createUnsignedClient(domain, false, verbose);
-
this.fileCache = new FileCache({ expirationSeconds: 60 });
+
this.fileCache = new FileCache({
+
expirationSeconds: fileCacheExpirationSeconds,
+
});
}
async getConfig() {
···
filePath = path.join(filePath, "index.html");
}
-
const fullPath = path.join(config.basePath, trimLeadingSlash(filePath));
+
const fullPath = path.join(config.baseDir, trimLeadingSlash(filePath));
const content = await this.getFileContent(fullPath);
if (!content) {