项目文件夹

文件
wehub-resource-sync 6ede33ccdb
Build and Push Docker Images / create_manifest (web, surfsense-web, , cpu) (push) Has been cancelled
Build and Push Docker Images / finalize_release (push) Has been cancelled
Obsidian Plugin Lint / lint (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_web, cpu, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64, , runner, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_web, cpu, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64, , runner, false, cpu) (push) Has been cancelled
Build and Push Docker Images / compute_version (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cpu, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, , production, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cpu, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, , production, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu126, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, -cuda126, production, true, cuda126) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu126, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, -cuda126, production, true, cuda126) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu128, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, -cuda, production, true, cuda) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu128, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, -cuda, production, true, cuda) (push) Has been cancelled
Build and Push Docker Images / verify_digests (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, , cpu) (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, -cuda, cuda) (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, -cuda126, cuda126) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:33:44 +08:00

145 行
3.6 KiB
TypeScript

import * as Babel from "@babel/standalone";
import React from "react";
import {
AbsoluteFill,
Easing,
interpolate,
Sequence,
spring,
useCurrentFrame,
useVideoConfig,
} from "remotion";
import { DURATION_IN_FRAMES } from "./constants";
export interface CompileResult {
success: boolean;
error: string | null;
}
function createStagger(totalFrames: number) {
return function stagger(
frame: number,
fps: number,
index: number,
total: number
): { opacity: number; transform: string } {
const enterPhase = Math.floor(totalFrames * 0.2);
const exitStart = Math.floor(totalFrames * 0.8);
const gap = Math.max(6, Math.floor(enterPhase / Math.max(total, 1)));
const delay = index * gap;
const s = spring({
frame: Math.max(0, frame - delay),
fps,
config: { damping: 15, stiffness: 120, mass: 0.8 },
});
const exit = interpolate(frame, [exitStart, totalFrames], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
const ambient = s > 0.99 ? Math.sin(frame * 0.05) * 2 : 0;
const opacity = s * (1 - exit);
const translateY =
interpolate(s, [0, 1], [40, 0]) + interpolate(exit, [0, 1], [0, -30]) + ambient;
const scale = interpolate(s, [0, 1], [0.97, 1]);
return {
opacity,
transform: `translateY(${translateY}px) scale(${scale})`,
};
};
}
const defaultStagger = createStagger(DURATION_IN_FRAMES);
const INJECTED_NAMES = [
"React",
"AbsoluteFill",
"useCurrentFrame",
"useVideoConfig",
"spring",
"interpolate",
"Sequence",
"Easing",
"stagger",
] as const;
const linear = (t: number) => t;
const SafeEasing = new Proxy(Easing, {
get(target, prop) {
const val = target[prop as keyof typeof Easing];
if (typeof val === "function") return val;
return linear;
},
});
function buildInjectedValues(staggerFn: ReturnType<typeof createStagger>) {
return [
React,
AbsoluteFill,
useCurrentFrame,
useVideoConfig,
spring,
interpolate,
Sequence,
SafeEasing,
staggerFn,
];
}
export function prepareSource(code: string): string {
const codeWithoutImports = code.replace(/^import\s+.*$/gm, "").trim();
const match = codeWithoutImports.match(
/export\s+(?:const|function)\s+(\w+)\s*(?::\s*React\.FC\s*)?=?\s*\(\s*\)\s*=>\s*\{([\s\S]*)\};?\s*$/
);
if (match) {
return `const DynamicComponent = () => {\n${match[2].trim()}\n};`;
}
const cleanedCode = codeWithoutImports
.replace(/export\s+default\s+/, "")
.replace(/export\s+/, "");
return cleanedCode.replace(/const\s+(\w+)/, "const DynamicComponent");
}
function transpile(code: string): string {
const wrappedSource = prepareSource(code);
const transpiled = Babel.transform(wrappedSource, {
presets: ["react", "typescript"],
filename: "dynamic.tsx",
});
if (!transpiled.code) throw new Error("Transpilation produced no output");
return transpiled.code;
}
export function compileCheck(code: string): CompileResult {
if (!code?.trim()) {
return { success: false, error: "Empty code" };
}
try {
const jsCode = transpile(code);
new Function(...INJECTED_NAMES, `${jsCode}\nreturn DynamicComponent;`);
return { success: true, error: null };
} catch (err) {
return {
success: false,
error: err instanceof Error ? err.message : "Unknown compilation error",
};
}
}
export function compileToComponent(code: string, durationInFrames?: number): React.ComponentType {
const staggerFn = durationInFrames ? createStagger(durationInFrames) : defaultStagger;
const jsCode = transpile(code);
const factory = new Function(...INJECTED_NAMES, `${jsCode}\nreturn DynamicComponent;`);
return factory(...buildInjectedValues(staggerFn)) as React.ComponentType;
}