app
Circuit Trace Generators
Public Made by Adomby adom
Two dependency-free, seeded circuit-background generators: a seamless torus tile with ambient or progressive reveal, and the v9 continuous field with obstacles, scroll reveal, and five ambient systems.
master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
const EMPTY_STATS = Object.freeze({
chunks: 0,
columns: 0,
chunkRows: 0,
pitch: 0,
width: 0,
generatedThrough: 0,
occupiedCells: 0,
occupancyFill: 0,
occupiedCellsRetained: 0,
occupiedCellsPruned: 0,
occupancyRowsRetained: 0,
occupancyRowsPruned: 0,
flowVorticesRetained: 0,
flowVorticesPruned: 0,
generationCacheMinimumRow: 1,
totalPublished: 0,
retainedTraces: 0,
totalPruned: 0,
rejectedRoutes: 0,
routeGuardRows: 0,
occupancyRetainedForSafety: true,
});
function deferred() {
let resolve;
let reject;
const promise = new Promise((resolvePromise, rejectPromise) => {
resolve = resolvePromise;
reject = rejectPromise;
});
promise.catch(() => {});
return {
promise,
resolve,
reject,
settled: false,
};
}
function abortError(message) {
if (typeof DOMException === "function") {
return new DOMException(message, "AbortError");
}
const error = new Error(message);
error.name = "AbortError";
return error;
}
function errorFromPayload(payload, fallbackMessage) {
const error = new Error(payload?.message || fallbackMessage);
error.name = payload?.name || "Error";
if (payload?.stack) error.stack = payload.stack;
return error;
}
function immutableStats(stats) {
return Object.freeze({ ...EMPTY_STATS, ...(stats || {}) });
}
function immutableTrace(trace) {
return Object.freeze(trace);
}
function notify(callbacks, value, api) {
for (const callback of callbacks) {
try {
callback(value, api);
} catch (error) {
console.error("Circuit field worker callback failed", error);
}
}
}
/**
* Main-thread client for circuit-field-stream-worker.js.
*
* The returned facade is available immediately. Await `ready` before reading
* normalized dimensions. `ensureThrough()` resolves after all append callbacks
* for its requested frontier have run.
*/
export function createStreamingCircuitFieldWorker(options = {}, clientOptions = {}) {
const appendCallbacks = new Set();
const fallbackCallbacks = new Set();
const statusCallbacks = new Set();
const pendingEnsures = new Map();
const pendingPrunes = new Map();
const retained = [];
let currentOptions = { ...options };
let worker;
let workerEpoch = 0;
let requestSequence = 0;
let readyState;
let lastStats = EMPTY_STATS;
let fallbackReason = null;
let state = "starting";
let destroyed = false;
const workerUrl = clientOptions.workerUrl
|| new URL("./circuit-field-stream-worker.js", import.meta.url);
const workerName = clientOptions.name || "circuit-field-stream";
function setState(nextState) {
if (state === nextState) return;
state = nextState;
queueMicrotask(() => notify(statusCallbacks, nextState, api));
}
function rejectPending(error) {
for (const request of pendingEnsures.values()) request.reject(error);
for (const request of pendingPrunes.values()) request.reject(error);
pendingEnsures.clear();
pendingPrunes.clear();
}
function terminateWorker() {
if (!worker) return;
const target = worker;
worker = undefined;
try {
target.postMessage({ type: "destroy" });
} catch {
// The worker may already have stopped.
}
target.terminate();
}
function signalFallback(kind, error, phase = "startup") {
if (destroyed || state === "failed") return;
const normalizedError = error instanceof Error
? error
: errorFromPayload(error, "Circuit field worker failed");
fallbackReason = Object.freeze({
kind,
phase,
error: normalizedError,
options: Object.freeze({ ...currentOptions }),
synchronousFallbackAvailable: true,
});
setState("failed");
terminateWorker();
if (readyState && !readyState.settled) {
readyState.settled = true;
readyState.reject(normalizedError);
}
rejectPending(normalizedError);
notify(fallbackCallbacks, fallbackReason, api);
}
function createWorkerInstance() {
if (typeof clientOptions.workerFactory === "function") {
return clientOptions.workerFactory(workerUrl, {
type: "module",
name: workerName,
});
}
if (typeof Worker !== "function") {
throw new Error("Web Workers are unavailable");
}
return new Worker(workerUrl, {
type: "module",
name: workerName,
});
}
function handleAppend(message) {
lastStats = immutableStats(message.stats);
const batch = Object.freeze(
(message.traces || []).map(immutableTrace),
);
retained.push(...batch);
notify(appendCallbacks, batch, api);
}
function handleEnsured(message) {
lastStats = immutableStats(message.stats);
const request = pendingEnsures.get(message.requestId);
if (!request) return;
pendingEnsures.delete(message.requestId);
request.resolve(Object.freeze({
target: message.target,
generatedThrough: message.generatedThrough,
stats: lastStats,
}));
if (!pendingEnsures.size) setState("ready");
}
function handlePruned(message) {
lastStats = immutableStats(message.stats);
const request = pendingPrunes.get(message.requestId);
if (!request) return;
pendingPrunes.delete(message.requestId);
const removedIds = Object.freeze((message.removedIds || []).slice());
if (removedIds.length) {
const removed = new Set(removedIds);
let writeIndex = 0;
for (const trace of retained) {
if (removed.has(trace.id)) continue;
retained[writeIndex] = trace;
writeIndex += 1;
}
retained.length = writeIndex;
}
request.resolve(removedIds);
}
function handleMessage(event, epoch) {
if (destroyed || epoch !== workerEpoch) return;
const message = event.data || {};
if (message.type === "ready") {
lastStats = immutableStats(message.stats);
setState("ready");
if (!readyState.settled) {
readyState.settled = true;
readyState.resolve(api);
}
} else if (message.type === "append") {
handleAppend(message);
} else if (message.type === "ensured") {
handleEnsured(message);
} else if (message.type === "pruned") {
handlePruned(message);
} else if (message.type === "fatal") {
signalFallback(
"worker-runtime-error",
errorFromPayload(message.error, "Circuit field worker failed"),
message.phase,
);
} else {
signalFallback(
"worker-protocol-error",
new Error(`Unknown worker response: ${String(message.type)}`),
"message",
);
}
}
function startWorker() {
workerEpoch += 1;
const epoch = workerEpoch;
readyState = deferred();
fallbackReason = null;
setState("starting");
try {
worker = createWorkerInstance();
worker.addEventListener("message", (event) => handleMessage(event, epoch));
worker.addEventListener("error", (event) => {
if (epoch !== workerEpoch || destroyed) return;
event.preventDefault?.();
signalFallback(
"worker-runtime-error",
event.error || new Error(event.message || "Circuit field worker crashed"),
"runtime",
);
});
worker.addEventListener("messageerror", () => {
if (epoch !== workerEpoch || destroyed) return;
signalFallback(
"worker-message-error",
new Error("Circuit field worker returned an unreadable message"),
"message",
);
});
worker.postMessage({
type: "init",
options: currentOptions,
});
} catch (error) {
signalFallback("worker-unavailable", error, "startup");
}
return readyState.promise;
}
async function ensureThrough(worldY) {
if (destroyed) throw new Error("Streaming circuit field worker has been destroyed");
const epoch = workerEpoch;
await readyState.promise;
if (destroyed) throw new Error("Streaming circuit field worker has been destroyed");
if (epoch !== workerEpoch) throw abortError("Circuit field worker was reset");
if (state === "failed" || !worker) {
throw fallbackReason?.error || new Error("Circuit field worker is unavailable");
}
const target = Math.max(0, Number(worldY) || 0);
if (lastStats.generatedThrough >= target) {
return Object.freeze({
target,
generatedThrough: lastStats.generatedThrough,
stats: lastStats,
});
}
const requestId = ++requestSequence;
const request = deferred();
pendingEnsures.set(requestId, request);
setState("generating");
try {
worker.postMessage({ type: "ensure", requestId, target });
} catch (error) {
signalFallback("worker-message-error", error, "ensure");
}
return request.promise;
}
async function pruneBefore(worldY) {
if (destroyed) throw new Error("Streaming circuit field worker has been destroyed");
const epoch = workerEpoch;
await readyState.promise;
if (destroyed) throw new Error("Streaming circuit field worker has been destroyed");
if (epoch !== workerEpoch) throw abortError("Circuit field worker was reset");
if (state === "failed" || !worker) {
throw fallbackReason?.error || new Error("Circuit field worker is unavailable");
}
const requestId = ++requestSequence;
const request = deferred();
pendingPrunes.set(requestId, request);
try {
worker.postMessage({
type: "prune",
requestId,
worldY: Number(worldY) || 0,
});
} catch (error) {
signalFallback("worker-message-error", error, "prune");
}
return request.promise;
}
function onAppend(callback) {
if (typeof callback !== "function") throw new TypeError("callback must be a function");
appendCallbacks.add(callback);
return () => appendCallbacks.delete(callback);
}
function onFallback(callback) {
if (typeof callback !== "function") throw new TypeError("callback must be a function");
fallbackCallbacks.add(callback);
if (fallbackReason) {
const reason = fallbackReason;
const epoch = workerEpoch;
queueMicrotask(() => {
if (
destroyed
|| epoch !== workerEpoch
|| fallbackReason !== reason
|| !fallbackCallbacks.has(callback)
) return;
notify([callback], reason, api);
});
}
return () => fallbackCallbacks.delete(callback);
}
function onStatus(callback) {
if (typeof callback !== "function") throw new TypeError("callback must be a function");
statusCallbacks.add(callback);
return () => statusCallbacks.delete(callback);
}
function reset(nextOptions = {}) {
if (destroyed) throw new Error("Streaming circuit field worker has been destroyed");
const resetError = abortError("Circuit field worker was reset");
terminateWorker();
if (readyState && !readyState.settled) {
readyState.settled = true;
readyState.reject(resetError);
}
rejectPending(resetError);
retained.length = 0;
lastStats = EMPTY_STATS;
currentOptions = { ...currentOptions, ...nextOptions };
return startWorker();
}
function destroy() {
if (destroyed) return;
destroyed = true;
const destroyedError = abortError("Circuit field worker was destroyed");
terminateWorker();
if (readyState && !readyState.settled) {
readyState.settled = true;
readyState.reject(destroyedError);
}
rejectPending(destroyedError);
appendCallbacks.clear();
fallbackCallbacks.clear();
statusCallbacks.clear();
retained.length = 0;
state = "destroyed";
}
const api = {
ensureThrough,
onAppend,
onFallback,
onStatus,
pruneBefore,
reset,
destroy,
get ready() { return readyState.promise; },
get status() { return state; },
get fallbackReason() { return fallbackReason; },
get width() { return lastStats.width; },
get height() { return lastStats.generatedThrough; },
get generatedThrough() { return lastStats.generatedThrough; },
get frontier() { return lastStats.generatedThrough; },
get traces() { return retained; },
get retainedTraces() { return retained; },
get stats() { return lastStats; },
};
startWorker();
return api;
}