Problem: the hexagonal refactor churns the backend tree for nine more phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper, compose/web image) must move to its own repo first so doc/layout rewrites land once on a backend-only tree. Change: - New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/ (updateURL repointed to oikos-web releases), compose/, own CI (web + desktop jobs), own deploy script (CI-green gate, TOCTOU guard, version-tagged images, prune-to-3), own webhook receiver on :9798 + launchd unit, own compose project publishing the same 8091:80. - Cutover executed on mac-mini in order: oikos stack's web service stopped+removed, oikos-web project brought up on 8091; outer Caddy untouched (targets the published port) — serving + Authentik flow + /wails 404 quirk verified post-cutover. - Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install targets, the compose web service, oikos-web from deploy.sh's fallback prune list; wails + go-keyring dropped from go.mod, vendor synced. - README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now point at the new repo; mbse + mascot design docs carry a path note. Risk: production SPA serving depends on the new pipeline now; rollback is versioned-image re-up of the old web service from a pre-split checkout (port 8091). Desktop builds installed before the split still check dtoro/oikos releases — one manual reinstall, noted in the oikos-web release notes. Verification: go vet, make test (race), make generate-check, golangci (no new findings; baseline down 400→365); post-cutover curls — localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
70 lines
2.2 KiB
JavaScript
70 lines
2.2 KiB
JavaScript
import { untrack } from "svelte";
|
|
function runEffect(flush, effect) {
|
|
switch (flush) {
|
|
case "post":
|
|
$effect(effect);
|
|
break;
|
|
case "pre":
|
|
$effect.pre(effect);
|
|
break;
|
|
}
|
|
}
|
|
function runWatcher(sources, flush, effect, options = {}) {
|
|
const { lazy = false } = options;
|
|
// Run the effect immediately if `lazy` is `false`.
|
|
let active = !lazy;
|
|
// On the first run, if the dependencies are an array, pass an empty array
|
|
// to the previous value instead of `undefined` to allow destructuring.
|
|
//
|
|
// watch(() => [a, b], ([a, b], [prevA, prevB]) => { ... });
|
|
let previousValues = Array.isArray(sources)
|
|
? []
|
|
: undefined;
|
|
runEffect(flush, () => {
|
|
const values = Array.isArray(sources) ? sources.map((source) => source()) : sources();
|
|
if (!active) {
|
|
active = true;
|
|
previousValues = values;
|
|
return;
|
|
}
|
|
const cleanup = untrack(() => effect(values, previousValues));
|
|
previousValues = values;
|
|
return cleanup;
|
|
});
|
|
}
|
|
function runWatcherOnce(sources, flush, effect) {
|
|
const cleanupRoot = $effect.root(() => {
|
|
let stop = false;
|
|
runWatcher(sources, flush, (values, previousValues) => {
|
|
if (stop) {
|
|
cleanupRoot();
|
|
return;
|
|
}
|
|
// Since `lazy` is `true`, `previousValues` is always defined.
|
|
const cleanup = effect(values, previousValues);
|
|
stop = true;
|
|
return cleanup;
|
|
},
|
|
// Running the effect immediately just once makes no sense at all.
|
|
// That's just `onMount` with extra steps.
|
|
{ lazy: true });
|
|
});
|
|
$effect(() => {
|
|
return cleanupRoot;
|
|
});
|
|
}
|
|
export function watch(sources, effect, options) {
|
|
runWatcher(sources, "post", effect, options);
|
|
}
|
|
function watchPre(sources, effect, options) {
|
|
runWatcher(sources, "pre", effect, options);
|
|
}
|
|
watch.pre = watchPre;
|
|
export function watchOnce(source, effect) {
|
|
runWatcherOnce(source, "post", effect);
|
|
}
|
|
function watchOncePre(source, effect) {
|
|
runWatcherOnce(source, "pre", effect);
|
|
}
|
|
watchOnce.pre = watchOncePre;
|