~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
82 lines · 3.8 KB Raw History
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Serve on your domain</title>
<script type="importmap">
{
	"imports": {
		"@atproto/oauth-client-browser": "https://esm.sh/@atproto/oauth-client-browser@0.5.14",
		"@publicdomainrelay/atlibs/": "https://cdn.jsdelivr.net/npm/@publicdomainrelay/atlibs@0.3.0/src/",
		"@publicdomainrelay/atlibs-code-mode/": "https://cdn.jsdelivr.net/npm/@publicdomainrelay/atlibs-code-mode@0.3.0/js/",
		"assemblyscript/asc": "https://cdn.jsdelivr.net/npm/assemblyscript@0.28.20/dist/asc.js",
		"assemblyscript": "https://cdn.jsdelivr.net/npm/assemblyscript@0.28.20/dist/assemblyscript.js",
		"binaryen": "https://cdn.jsdelivr.net/npm/binaryen@131.0.0-nightly.20260721/index.js",
		"long": "https://cdn.jsdelivr.net/npm/long@5.3.2/index.js",
		"codemirror": "https://esm.sh/codemirror@6.0.2?deps=@codemirror/state@6.7.6,@codemirror/view@6.43.15,@codemirror/language@6.13.1",
		"@codemirror/lang-javascript": "https://esm.sh/@codemirror/lang-javascript@6.2.5?deps=@codemirror/state@6.7.6,@codemirror/view@6.43.15,@codemirror/language@6.13.1"
	}
}
</script>
<style>
	:root { color-scheme: light dark; }
	body { font-family: system-ui, sans-serif; max-width: 60rem; margin: 1rem auto; padding: 0 1rem; }
	label { margin-right: 0.75rem; }
	fieldset { border: 0; padding: 0; margin: 0; }
	input[name=name] { width: 10rem; }
	#editor { border: 1px solid #8888; min-height: 14rem; }
	#editor .cm-editor { height: 20rem; }
	#log { font-family: ui-monospace, monospace; font-size: 0.85rem; max-height: 20rem; overflow: auto; padding-left: 1.2rem; }
	.error { color: #c33; white-space: pre-wrap; }
	code { word-break: break-all; }
</style>
<script type="module" src="./main.js"></script>

<h1>Serve on your domain</h1>
<p><a href="https://knotless.dev/johnandersen777.bsky.social/atlibs-examples-spa-networking">Source</a></p>
<p>This tab serves from its own did:key host as soon as it loads, signed in or not: the fedproxy ingress forwards each
request here, and the handler below answers it. Sign in to serve a domain you registered through
<a href="https://marque.at">Marque</a> too.</p>

<form id="login" hidden>
	<input name="handle" placeholder="you.bsky.social" required>
	<button>Sign in</button>
</form>
<p id="who" hidden><span></span> <button type="button" id="logout">Sign out</button></p>

<form id="serve">
	<p class="signin">Sign in to use your own domain.</p>
	<fieldset disabled>
	<label>Domain <select name="domain" required></select></label>
	<label>Name <input name="name" value="@" required title="@ for the domain itself, or a subdomain label"></label>
	<button>Serve</button>
	</fieldset>
	<p>Writes a CNAME at that name to the ingress host, replacing what is there (you confirm first), and a TXT at
	<code>_xrpc.&lt;that name&gt;</code> holding the ingress did:key, which is how the relay knows the name is yours.</p>
</form>

<dialog id="confirm">
	<form method="dialog">
		<p>A CNAME must be alone at its name. Writing <code class="cname"></code> removes these records:</p>
		<ul class="remove"></ul>
		<button value="cancel">Keep them</button>
		<button value="ok">Replace them</button>
	</form>
</dialog>

<section id="urls" hidden>
	<h2>Public URLs</h2>
	<ul>
		<li>did:key: <a class="ingress" target="_blank" rel="noopener"></a> <span class="status"></span> <span class="kept"></span></li>
		<li hidden>Your domain: <a class="custom" target="_blank" rel="noopener"></a> <span class="dns"></span> <span class="alias"></span></li>
	</ul>
</section>

<h2>Handler</h2>
<p>AssemblyScript, compiled in a worker and run sandboxed (no imports, 64 MiB, 5 s) once per request.
Apply swaps it in without restarting the ingress.</p>
<div id="editor"></div>
<p><button type="button" id="apply">Apply</button> <span id="compiled"></span></p>

<h2>Requests</h2>
<ol id="log" reversed></ol>
<p class="error" id="error"></p>