Static site hosting via tangled

Rename to baseDir and add readme

+62 -6
+33
README.md
···
··· 1 + # tangled-pages 2 + 3 + This gives you a way to host a website via a tangled repo. 4 + You can run it as a cloudflare worker or as an express server. 5 + 6 + Create .env: 7 + 8 + ``` 9 + KNOT_DOMAIN=knot.gracekind.net 10 + OWNER_DID=did:plc:p572wxnsuoogcrhlfrlizlrb 11 + REPO_NAME=static-site-example 12 + ``` 13 + 14 + Run: 15 + 16 + ```bash 17 + npm install 18 + npm start 19 + ``` 20 + 21 + ## Config 22 + 23 + You can configure the pages service by creating a `pages_config.yaml` file in the root of the repo. 24 + 25 + ```yaml 26 + baseDir: "/public" 27 + notFoundFilepath: "404.html" 28 + ``` 29 + 30 + ## Limitations 31 + 32 + It fetches files from the repo on request, so it might be slow. 33 + In the future, we could cache the files and use a CI to update the cache.
+9
example/404.html
···
··· 1 + <html> 2 + <head> 3 + <title>404 Not Found</title> 4 + </head> 5 + <body> 6 + <h1>404 Not Found</h1> 7 + <p>This is an example of a custom 404 page.</p> 8 + </body> 9 + </html>
+9
example/index.html
···
··· 1 + <html> 2 + <head> 3 + <title>Tangled Pages Example</title> 4 + </head> 5 + <body> 6 + <h1>Tangled Pages Example</h1> 7 + <p>This is an example of a static page hosted on a tangled repo!</p> 8 + </body> 9 + </html>
+2
pages_config.yaml
···
··· 1 + baseDir: /example 2 + notFoundFilepath: /404.html
+9 -6
src/pages-service.js
··· 36 } 37 38 class PagesConfig { 39 - constructor({ basePath, notFoundFilepath }) { 40 - this.basePath = basePath; 41 this.notFoundFilepath = notFoundFilepath; 42 } 43 44 static default() { 45 return new PagesConfig({ 46 - basePath: "/", 47 notFoundFilepath: null, 48 }); 49 } ··· 59 throw new Error(`Error parsing YAML file ${filePath}: ${error}`); 60 } 61 return new PagesConfig({ 62 - basePath: configObj.basePath || "/", 63 notFoundFilepath: configObj.notFoundFilepath || null, 64 }); 65 } ··· 72 repoName, 73 configFilepath = "pages_config.yaml", 74 verbose = false, 75 }) { 76 this.ownerDid = ownerDid; 77 this.repoName = repoName; 78 this.configFilepath = configFilepath; 79 this.verbose = verbose; 80 this.client = createUnsignedClient(domain, false, verbose); 81 - this.fileCache = new FileCache({ expirationSeconds: 60 }); 82 } 83 84 async getConfig() { ··· 131 filePath = path.join(filePath, "index.html"); 132 } 133 134 - const fullPath = path.join(config.basePath, trimLeadingSlash(filePath)); 135 136 const content = await this.getFileContent(fullPath); 137 if (!content) {
··· 36 } 37 38 class PagesConfig { 39 + constructor({ baseDir, notFoundFilepath }) { 40 + this.baseDir = baseDir; 41 this.notFoundFilepath = notFoundFilepath; 42 } 43 44 static default() { 45 return new PagesConfig({ 46 + baseDir: "/", 47 notFoundFilepath: null, 48 }); 49 } ··· 59 throw new Error(`Error parsing YAML file ${filePath}: ${error}`); 60 } 61 return new PagesConfig({ 62 + baseDir: configObj.baseDir || "/", 63 notFoundFilepath: configObj.notFoundFilepath || null, 64 }); 65 } ··· 72 repoName, 73 configFilepath = "pages_config.yaml", 74 verbose = false, 75 + fileCacheExpirationSeconds = 10, 76 }) { 77 this.ownerDid = ownerDid; 78 this.repoName = repoName; 79 this.configFilepath = configFilepath; 80 this.verbose = verbose; 81 this.client = createUnsignedClient(domain, false, verbose); 82 + this.fileCache = new FileCache({ 83 + expirationSeconds: fileCacheExpirationSeconds, 84 + }); 85 } 86 87 async getConfig() { ··· 134 filePath = path.join(filePath, "index.html"); 135 } 136 137 + const fullPath = path.join(config.baseDir, trimLeadingSlash(filePath)); 138 139 const content = await this.getFileContent(fullPath); 140 if (!content) {