BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup

This commit is contained in:
Bernt
2026-07-28 23:08:32 +00:00
parent 0b4f160af1
commit af874040ca
11541 changed files with 1654104 additions and 1103 deletions
+73
View File
@@ -0,0 +1,73 @@
import { MotionGlobalConfig } from 'motion-utils';
import { stepsOrder } from './order.mjs';
import { createRenderStep } from './render-step.mjs';
const maxElapsed = 40;
function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
let runNextFrame = false;
let useDefaultElapsed = true;
const state = {
delta: 0.0,
timestamp: 0.0,
isProcessing: false,
};
const flagRunNextFrame = () => (runNextFrame = true);
const steps = stepsOrder.reduce((acc, key) => {
acc[key] = createRenderStep(flagRunNextFrame);
return acc;
}, {});
const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender, } = steps;
const processBatch = () => {
const useManualTiming = MotionGlobalConfig.useManualTiming;
const timestamp = useManualTiming
? state.timestamp
: performance.now();
runNextFrame = false;
if (!useManualTiming) {
state.delta = useDefaultElapsed
? 1000 / 60
: Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
}
state.timestamp = timestamp;
state.isProcessing = true;
// Unrolled render loop for better per-frame performance
setup.process(state);
read.process(state);
resolveKeyframes.process(state);
preUpdate.process(state);
update.process(state);
preRender.process(state);
render.process(state);
postRender.process(state);
state.isProcessing = false;
if (runNextFrame && allowKeepAlive) {
useDefaultElapsed = false;
scheduleNextBatch(processBatch);
}
};
const wake = () => {
runNextFrame = true;
useDefaultElapsed = true;
if (!state.isProcessing) {
scheduleNextBatch(processBatch);
}
};
const schedule = stepsOrder.reduce((acc, key) => {
const step = steps[key];
acc[key] = (process, keepAlive = false, immediate = false) => {
if (!runNextFrame)
wake();
return step.schedule(process, keepAlive, immediate);
};
return acc;
}, {});
const cancel = (process) => {
for (let i = 0; i < stepsOrder.length; i++) {
steps[stepsOrder[i]].cancel(process);
}
};
return { schedule, cancel, state, steps };
}
export { createRenderBatcher };
//# sourceMappingURL=batcher.mjs.map
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
import { noop } from 'motion-utils';
import { createRenderBatcher } from './batcher.mjs';
const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = /* @__PURE__ */ createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
export { cancelFrame, frame, frameData, frameSteps };
//# sourceMappingURL=frame.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"frame.mjs","sources":["../../../src/frameloop/frame.ts"],"sourcesContent":["import { noop } from \"motion-utils\"\nimport { createRenderBatcher } from \"./batcher\"\n\nexport const {\n schedule: frame,\n cancel: cancelFrame,\n state: frameData,\n steps: frameSteps,\n} = /* @__PURE__ */ createRenderBatcher(\n typeof requestAnimationFrame !== \"undefined\" ? requestAnimationFrame : noop,\n true\n)\n"],"names":[],"mappings":";;;AAGO,MAAM,EACT,QAAQ,EAAE,KAAK,EACf,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,UAAU,GACpB,mBAAmB,mBAAmB,CACnC,OAAO,qBAAqB,KAAK,WAAW,GAAG,qBAAqB,GAAG,IAAI,EAC3E,IAAI;;;;"}
+21
View File
@@ -0,0 +1,21 @@
import { stepsOrder } from './order.mjs';
import { frame, cancelFrame } from './frame.mjs';
/**
* @deprecated
*
* Import as `frame` instead.
*/
const sync = frame;
/**
* @deprecated
*
* Use cancelFrame(callback) instead.
*/
const cancelSync = stepsOrder.reduce((acc, key) => {
acc[key] = (process) => cancelFrame(process);
return acc;
}, {});
export { cancelSync, sync };
//# sourceMappingURL=index-legacy.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"index-legacy.mjs","sources":["../../../src/frameloop/index-legacy.ts"],"sourcesContent":["import { cancelFrame, frame } from \".\"\nimport { stepsOrder } from \"./order\"\nimport { Process } from \"./types\"\n\n/**\n * @deprecated\n *\n * Import as `frame` instead.\n */\nexport const sync = frame\n\n/**\n * @deprecated\n *\n * Use cancelFrame(callback) instead.\n */\nexport const cancelSync = stepsOrder.reduce((acc, key) => {\n acc[key] = (process: Process) => cancelFrame(process)\n return acc\n}, {} as Record<string, (process: Process) => void>)\n"],"names":[],"mappings":";;;AAIA;;;;AAIG;AACI,MAAM,IAAI,GAAG;AAEpB;;;;AAIG;AACI,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,KAAI;AACrD,IAAA,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAgB,KAAK,WAAW,CAAC,OAAO,CAAC;AACrD,IAAA,OAAO,GAAG;AACd,CAAC,EAAE,EAAgD;;;;"}
+7
View File
@@ -0,0 +1,7 @@
import { createRenderBatcher } from './batcher.mjs';
const { schedule: microtask, cancel: cancelMicrotask } =
/* @__PURE__ */ createRenderBatcher(queueMicrotask, false);
export { cancelMicrotask, microtask };
//# sourceMappingURL=microtask.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"microtask.mjs","sources":["../../../src/frameloop/microtask.ts"],"sourcesContent":["import { createRenderBatcher } from \"./batcher\"\n\nexport const { schedule: microtask, cancel: cancelMicrotask } =\n /* @__PURE__ */ createRenderBatcher(queueMicrotask, false)\n"],"names":[],"mappings":";;AAEO,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE;AACzD,gBAAgB,mBAAmB,CAAC,cAAc,EAAE,KAAK;;;;"}
+13
View File
@@ -0,0 +1,13 @@
const stepsOrder = [
"setup", // Compute
"read", // Read
"resolveKeyframes", // Write/Read/Write/Read
"preUpdate", // Compute
"update", // Compute
"preRender", // Compute
"render", // Write
"postRender", // Compute
];
export { stepsOrder };
//# sourceMappingURL=order.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"order.mjs","sources":["../../../src/frameloop/order.ts"],"sourcesContent":["import { StepId } from \"./types\"\n\nexport const stepsOrder: StepId[] = [\n \"setup\", // Compute\n \"read\", // Read\n \"resolveKeyframes\", // Write/Read/Write/Read\n \"preUpdate\", // Compute\n \"update\", // Compute\n \"preRender\", // Compute\n \"render\", // Write\n \"postRender\", // Compute\n] as const\n\nexport type StepNames = (typeof stepsOrder)[number]\n"],"names":[],"mappings":"AAEO,MAAM,UAAU,GAAa;AAChC,IAAA,OAAO;AACP,IAAA,MAAM;AACN,IAAA,kBAAkB;AAClB,IAAA,WAAW;AACX,IAAA,QAAQ;AACR,IAAA,WAAW;AACX,IAAA,QAAQ;AACR,IAAA,YAAY;;;;;"}
+84
View File
@@ -0,0 +1,84 @@
function createRenderStep(runNextFrame) {
/**
* We create and reuse two queues, one to queue jobs for the current frame
* and one for the next. We reuse to avoid triggering GC after x frames.
*/
let thisFrame = new Set();
let nextFrame = new Set();
/**
* Track whether we're currently processing jobs in this step. This way
* we can decide whether to schedule new jobs for this frame or next.
*/
let isProcessing = false;
let flushNextFrame = false;
/**
* A set of processes which were marked keepAlive when scheduled.
*/
const toKeepAlive = new WeakSet();
let latestFrameData = {
delta: 0.0,
timestamp: 0.0,
isProcessing: false,
};
function triggerCallback(callback) {
if (toKeepAlive.has(callback)) {
step.schedule(callback);
runNextFrame();
}
callback(latestFrameData);
}
const step = {
/**
* Schedule a process to run on the next frame.
*/
schedule: (callback, keepAlive = false, immediate = false) => {
const addToCurrentFrame = immediate && isProcessing;
const queue = addToCurrentFrame ? thisFrame : nextFrame;
if (keepAlive)
toKeepAlive.add(callback);
queue.add(callback);
return callback;
},
/**
* Cancel the provided callback from running on the next frame.
*/
cancel: (callback) => {
nextFrame.delete(callback);
toKeepAlive.delete(callback);
},
/**
* Execute all schedule callbacks.
*/
process: (frameData) => {
latestFrameData = frameData;
/**
* If we're already processing we've probably been triggered by a flushSync
* inside an existing process. Instead of executing, mark flushNextFrame
* as true and ensure we flush the following frame at the end of this one.
*/
if (isProcessing) {
flushNextFrame = true;
return;
}
isProcessing = true;
// Swap this frame and the next to avoid GC
const prevFrame = thisFrame;
thisFrame = nextFrame;
nextFrame = prevFrame;
// Execute this frame
thisFrame.forEach(triggerCallback);
// Clear the frame so no callbacks remain. This is to avoid
// memory leaks should this render step not run for a while.
thisFrame.clear();
isProcessing = false;
if (flushNextFrame) {
flushNextFrame = false;
step.process(frameData);
}
},
};
return step;
}
export { createRenderStep };
//# sourceMappingURL=render-step.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"render-step.mjs","sources":["../../../src/frameloop/render-step.ts"],"sourcesContent":["import { FrameData, Process, Step } from \"./types\"\n\nexport function createRenderStep(runNextFrame: () => void): Step {\n /**\n * We create and reuse two queues, one to queue jobs for the current frame\n * and one for the next. We reuse to avoid triggering GC after x frames.\n */\n let thisFrame = new Set<Process>()\n let nextFrame = new Set<Process>()\n\n /**\n * Track whether we're currently processing jobs in this step. This way\n * we can decide whether to schedule new jobs for this frame or next.\n */\n let isProcessing = false\n\n let flushNextFrame = false\n\n /**\n * A set of processes which were marked keepAlive when scheduled.\n */\n const toKeepAlive = new WeakSet<Process>()\n\n let latestFrameData: FrameData = {\n delta: 0.0,\n timestamp: 0.0,\n isProcessing: false,\n }\n\n function triggerCallback(callback: Process) {\n if (toKeepAlive.has(callback)) {\n step.schedule(callback)\n runNextFrame()\n }\n\n callback(latestFrameData)\n }\n\n const step: Step = {\n /**\n * Schedule a process to run on the next frame.\n */\n schedule: (callback, keepAlive = false, immediate = false) => {\n const addToCurrentFrame = immediate && isProcessing\n const queue = addToCurrentFrame ? thisFrame : nextFrame\n\n if (keepAlive) toKeepAlive.add(callback)\n\n queue.add(callback)\n\n return callback\n },\n\n /**\n * Cancel the provided callback from running on the next frame.\n */\n cancel: (callback) => {\n nextFrame.delete(callback)\n toKeepAlive.delete(callback)\n },\n\n /**\n * Execute all schedule callbacks.\n */\n process: (frameData) => {\n latestFrameData = frameData\n\n /**\n * If we're already processing we've probably been triggered by a flushSync\n * inside an existing process. Instead of executing, mark flushNextFrame\n * as true and ensure we flush the following frame at the end of this one.\n */\n if (isProcessing) {\n flushNextFrame = true\n return\n }\n\n isProcessing = true\n\n // Swap this frame and the next to avoid GC\n const prevFrame = thisFrame\n thisFrame = nextFrame\n nextFrame = prevFrame\n\n // Execute this frame\n thisFrame.forEach(triggerCallback)\n\n // Clear the frame so no callbacks remain. This is to avoid\n // memory leaks should this render step not run for a while.\n thisFrame.clear()\n\n isProcessing = false\n\n if (flushNextFrame) {\n flushNextFrame = false\n step.process(frameData)\n }\n },\n }\n\n return step\n}\n"],"names":[],"mappings":"AAEM,SAAU,gBAAgB,CAAC,YAAwB,EAAA;AACrD;;;AAGG;AACH,IAAA,IAAI,SAAS,GAAG,IAAI,GAAG,EAAW;AAClC,IAAA,IAAI,SAAS,GAAG,IAAI,GAAG,EAAW;AAElC;;;AAGG;IACH,IAAI,YAAY,GAAG,KAAK;IAExB,IAAI,cAAc,GAAG,KAAK;AAE1B;;AAEG;AACH,IAAA,MAAM,WAAW,GAAG,IAAI,OAAO,EAAW;AAE1C,IAAA,IAAI,eAAe,GAAc;AAC7B,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,SAAS,EAAE,GAAG;AACd,QAAA,YAAY,EAAE,KAAK;KACtB;IAED,SAAS,eAAe,CAAC,QAAiB,EAAA;AACtC,QAAA,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAC3B,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACvB,YAAA,YAAY,EAAE;QAClB;QAEA,QAAQ,CAAC,eAAe,CAAC;IAC7B;AAEA,IAAA,MAAM,IAAI,GAAS;AACf;;AAEG;AACH,QAAA,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,KAAI;AACzD,YAAA,MAAM,iBAAiB,GAAG,SAAS,IAAI,YAAY;YACnD,MAAM,KAAK,GAAG,iBAAiB,GAAG,SAAS,GAAG,SAAS;AAEvD,YAAA,IAAI,SAAS;AAAE,gBAAA,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;AAExC,YAAA,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;AAEnB,YAAA,OAAO,QAAQ;QACnB,CAAC;AAED;;AAEG;AACH,QAAA,MAAM,EAAE,CAAC,QAAQ,KAAI;AACjB,YAAA,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC1B,YAAA,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChC,CAAC;AAED;;AAEG;AACH,QAAA,OAAO,EAAE,CAAC,SAAS,KAAI;YACnB,eAAe,GAAG,SAAS;AAE3B;;;;AAIG;YACH,IAAI,YAAY,EAAE;gBACd,cAAc,GAAG,IAAI;gBACrB;YACJ;YAEA,YAAY,GAAG,IAAI;;YAGnB,MAAM,SAAS,GAAG,SAAS;YAC3B,SAAS,GAAG,SAAS;YACrB,SAAS,GAAG,SAAS;;AAGrB,YAAA,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC;;;YAIlC,SAAS,CAAC,KAAK,EAAE;YAEjB,YAAY,GAAG,KAAK;YAEpB,IAAI,cAAc,EAAE;gBAChB,cAAc,GAAG,KAAK;AACtB,gBAAA,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAC3B;QACJ,CAAC;KACJ;AAED,IAAA,OAAO,IAAI;AACf;;;;"}
+32
View File
@@ -0,0 +1,32 @@
import { MotionGlobalConfig } from 'motion-utils';
import { frameData } from './frame.mjs';
let now;
function clearTime() {
now = undefined;
}
/**
* An eventloop-synchronous alternative to performance.now().
*
* Ensures that time measurements remain consistent within a synchronous context.
* Usually calling performance.now() twice within the same synchronous context
* will return different values which isn't useful for animations when we're usually
* trying to sync animations to the same frame.
*/
const time = {
now: () => {
if (now === undefined) {
time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming
? frameData.timestamp
: performance.now());
}
return now;
},
set: (newTime) => {
now = newTime;
queueMicrotask(clearTime);
},
};
export { time };
//# sourceMappingURL=sync-time.mjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"sync-time.mjs","sources":["../../../src/frameloop/sync-time.ts"],"sourcesContent":["import { MotionGlobalConfig } from \"motion-utils\"\nimport { frameData } from \"./frame\"\n\nlet now: number | undefined\n\nfunction clearTime() {\n now = undefined\n}\n\n/**\n * An eventloop-synchronous alternative to performance.now().\n *\n * Ensures that time measurements remain consistent within a synchronous context.\n * Usually calling performance.now() twice within the same synchronous context\n * will return different values which isn't useful for animations when we're usually\n * trying to sync animations to the same frame.\n */\nexport const time = {\n now: (): number => {\n if (now === undefined) {\n time.set(\n frameData.isProcessing || MotionGlobalConfig.useManualTiming\n ? frameData.timestamp\n : performance.now()\n )\n }\n\n return now!\n },\n set: (newTime: number) => {\n now = newTime\n queueMicrotask(clearTime)\n },\n}\n"],"names":[],"mappings":";;;AAGA,IAAI,GAAuB;AAE3B,SAAS,SAAS,GAAA;IACd,GAAG,GAAG,SAAS;AACnB;AAEA;;;;;;;AAOG;AACI,MAAM,IAAI,GAAG;IAChB,GAAG,EAAE,MAAa;AACd,QAAA,IAAI,GAAG,KAAK,SAAS,EAAE;YACnB,IAAI,CAAC,GAAG,CACJ,SAAS,CAAC,YAAY,IAAI,kBAAkB,CAAC;kBACvC,SAAS,CAAC;AACZ,kBAAE,WAAW,CAAC,GAAG,EAAE,CAC1B;QACL;AAEA,QAAA,OAAO,GAAI;IACf,CAAC;AACD,IAAA,GAAG,EAAE,CAAC,OAAe,KAAI;QACrB,GAAG,GAAG,OAAO;QACb,cAAc,CAAC,SAAS,CAAC;IAC7B,CAAC;;;;;"}