Package Conduit Market as an Archipelago app
Pure client-side Nostr+Lightning marketplace (apps/market from Conduit-BTC/conduit-mono) built into a static nginx image. Public/private is a genuine runtime toggle, not two separate builds: Vite bakes VITE_* relay config into the bundle at build time, so config.ts is patched (apply-runtime-override.py) to merge in a window.__CONDUIT_RUNTIME_ENV__ override written by docker-entrypoint.sh from CONDUIT_MODE / CONDUIT_PRIVATE_RELAY_URLS at container start -- flipping mode only needs a restart, not a rebuild. Verified end-to-end: build succeeds, the override survives bundling/minification, and public/private/missing-relay all produce the correct runtime-env.js (private with no relay URL refuses to start rather than silently falling back to the public network). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Patches packages/core/src/config.ts so it can be reconfigured
|
||||
public/private at container-start time instead of only at build time.
|
||||
|
||||
Vite bakes VITE_* env vars into the bundle as literal strings when it
|
||||
compiles (import.meta.env.VITE_FOO is a static replacement, not a runtime
|
||||
lookup) -- confirmed directly in config.ts's own comment on getViteEnv().
|
||||
That means a container image built once can never be flipped between an
|
||||
isolated private relay and the public Conduit network via ordinary env
|
||||
vars after the fact; the values are frozen into the compiled JS.
|
||||
|
||||
This packaging needs exactly that live toggle, so docker-entrypoint.sh
|
||||
writes a small /runtime-env.js at *container start* (from real env vars)
|
||||
setting window.__CONDUIT_RUNTIME_ENV__ before the app bundle runs. This
|
||||
script inserts one small override function right before the single call
|
||||
site that consumes getViteEnv()'s result (`const env = getViteEnv()`,
|
||||
confirmed to be the only call site in the file and to run once at module
|
||||
load), so only that one merge point needs to change. Only non-empty
|
||||
string fields override the Vite-baked default; a build with no runtime
|
||||
override behaves identically to stock upstream Conduit.
|
||||
|
||||
Uses a literal string anchor rather than a line-numbered diff/patch --
|
||||
more robust against upstream reformatting a comment or reflowing
|
||||
unrelated lines than a traditional unified diff would be.
|
||||
"""
|
||||
import sys
|
||||
|
||||
CONFIG_PATH = "packages/core/src/config.ts"
|
||||
ANCHOR = "const env = getViteEnv()"
|
||||
|
||||
OVERRIDE_BLOCK = '''// --- Archipelago runtime relay override -------------------------------------
|
||||
// See docker/conduit-market/apply-runtime-override.py in the archy repo for
|
||||
// why this exists: Vite bakes VITE_* env vars into the bundle at build
|
||||
// time, so a container image built once can never be reconfigured
|
||||
// public/private afterward via ordinary env vars. docker-entrypoint.sh
|
||||
// writes window.__CONDUIT_RUNTIME_ENV__ from real environment variables at
|
||||
// container start, before this bundle runs.
|
||||
function getRuntimeOverrides(): Partial<ReturnType<typeof getViteEnv>> {
|
||||
if (typeof window === "undefined") return {}
|
||||
const raw = (window as unknown as Record<string, unknown>)
|
||||
.__CONDUIT_RUNTIME_ENV__
|
||||
if (!raw || typeof raw !== "object") return {}
|
||||
const out: Record<string, string> = {}
|
||||
for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {
|
||||
if (typeof value === "string" && value.length > 0) out[key] = value
|
||||
}
|
||||
return out as Partial<ReturnType<typeof getViteEnv>>
|
||||
}
|
||||
|
||||
const env = { ...getViteEnv(), ...getRuntimeOverrides() }'''
|
||||
|
||||
with open(CONFIG_PATH) as f:
|
||||
content = f.read()
|
||||
|
||||
count = content.count(ANCHOR)
|
||||
if count != 1:
|
||||
print(
|
||||
f"FATAL: expected exactly 1 occurrence of anchor line in {CONFIG_PATH}, "
|
||||
f"found {count}. Upstream config.ts has likely changed in a way that "
|
||||
"needs this script re-checked by hand before it can safely patch it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
content = content.replace(ANCHOR, OVERRIDE_BLOCK, 1)
|
||||
|
||||
with open(CONFIG_PATH, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
print(f"Patched {CONFIG_PATH}: runtime relay override installed.")
|
||||
Reference in New Issue
Block a user