Organize LLM assets and function lifecycle fixes

This commit is contained in:
Naeel
2026-04-28 13:04:08 +03:00
parent 82eba079f6
commit a534fddd2c
22 changed files with 1409 additions and 72 deletions
+10 -31
View File
@@ -9,24 +9,10 @@ import (
// BuildJSDeployZip упаковывает Node.js код в zip для Fission deployment package.
//
// Почему zip, а не просто literal-код:
// Fission node-env v3 поддерживает ESM модули. Чтобы Node.js трактовал файл
// как ESM, нужен package.json с {"type":"module"} рядом с main.js.
// Без него `import` синтаксис вызовет "require is not defined" или SyntaxError.
//
// Почему new Function:
// Пользовательский код пишет CJS-стиль (module.exports = ...) но мы хотим ESM wrapper.
// new Function() изолирует module/exports от глобального ESM контекста и позволяет
// исполнять CJS-код без изменений.
//
// Результат: zip с двумя файлами:
// - package.json: {"type":"module"}
// - main.js: ESM wrapper + инлайн пользовательский код через new Function
//
// Совместимость entrypoint:
// UI исторически отправлял entrypoint="handler", а backend по умолчанию использует
// entrypoint="main". Чтобы specialization не ломался из-за несовпадения,
// wrapper экспортирует обе точки входа: named exports main и handler, а также default.
// Генерируем CommonJS wrapper: так Fission/node executor не упирается в ESM export
// синтаксис и может исполнять результат без package.json и type=module.
// Пользовательский код остаётся CJS-стилем через new Function(module, exports).
// Wrapper экспортирует main, handler и default через module.exports.
func BuildJSDeployZip(code string) ([]byte, error) {
// Сериализуем пользовательский код в JSON строку чтобы безопасно инлайнить
// в JavaScript-литерал — экранирует кавычки, переводы строк, спецсимволы.
@@ -35,10 +21,10 @@ func BuildJSDeployZip(code string) ([]byte, error) {
return nil, fmt.Errorf("marshal user code: %w", err)
}
// main.js — ESM wrapper:
// main.js — CommonJS wrapper:
// 1. new Function создаёт функцию в пустом модульном контексте (нет import/export)
// 2. Передаём ей module и exports как параметры → пользовательский CJS код работает
// 3. Экспортируем default async function для Fission node-env entrypoint
// 3. Экспортируем main/handler/default через module.exports
wrapper := fmt.Sprintf(`const __mod = { exports: {} };
(new Function('module', 'exports', %s))(__mod, __mod.exports);
const _fn = __mod.exports;
@@ -52,22 +38,15 @@ const _fn = __mod.exports;
return { status: 200, ...result };
}
export { __invoke as main, __invoke as handler };
export default __invoke;
module.exports = __invoke;
module.exports.main = __invoke;
module.exports.handler = __invoke;
module.exports.default = __invoke;
`, string(codeJSON))
var buf bytes.Buffer
zw := zip.NewWriter(&buf)
// package.json: включает ESM режим для всего архива
pkgfw, err := zw.Create("package.json")
if err != nil {
return nil, err
}
if _, err := pkgfw.Write([]byte(`{"type":"module"}`)); err != nil {
return nil, err
}
fw, err := zw.Create("main.js")
if err != nil {
return nil, err