* Don't require auth for .ping * Finally introducing loggers * Remove file list caching from disk_space_primitives I don't think this is required anymore with the sync model * Simplification of space primitives and more tests * More reliable online status * Add .zed settings * Remove selfUpdate argument from `writeFile` no longer used - Add `sync` config schema and document sync options - Move sync config handling to client boot logic - Move BootConfig type to ui_types.ts - Remove sync env vars from server - Update documentation for sync and architecture * Improve sync logic and proxy routing for full sync state * Add BoxProxy for late-bound client and improve Lua boot - Add isMobile syscall for editor * Add concurrency to sync process and log indexing duration * Better service worker lifecycle management
98 lines
2.7 KiB
TypeScript
98 lines
2.7 KiB
TypeScript
import type { System } from "../lib/plugos/system.ts";
|
|
import type { ScriptObject } from "../plugs/index/script.ts";
|
|
import {
|
|
LuaEnv,
|
|
LuaRuntimeError,
|
|
LuaStackFrame,
|
|
} from "../lib/space_lua/runtime.ts";
|
|
import {
|
|
parse as parseLua,
|
|
parseExpressionString,
|
|
} from "../lib/space_lua/parse.ts";
|
|
import { evalStatement } from "../lib/space_lua/eval.ts";
|
|
import {
|
|
encodeRef,
|
|
parseToRef,
|
|
type Ref,
|
|
} from "@silverbulletmd/silverbullet/lib/ref";
|
|
import type { ASTCtx } from "../lib/space_lua/ast.ts";
|
|
import { buildLuaEnv } from "./space_lua_api.ts";
|
|
import type { LuaCollectionQuery } from "../lib/space_lua/query_collection.ts";
|
|
|
|
export class SpaceLuaEnvironment {
|
|
env: LuaEnv;
|
|
|
|
constructor(private system: System<any>) {
|
|
this.env = buildLuaEnv(system);
|
|
}
|
|
|
|
/**
|
|
* Loads all Lua scripts from the database and evaluates them in a new environment
|
|
* @param system
|
|
*/
|
|
async reload() {
|
|
const allScripts: ScriptObject[] = await this.system.invokeFunction(
|
|
"index.queryLuaObjects",
|
|
["space-lua", {
|
|
objectVariable: "script",
|
|
orderBy: [{
|
|
expr: parseExpressionString("script.priority"),
|
|
desc: true,
|
|
}],
|
|
} as LuaCollectionQuery],
|
|
);
|
|
try {
|
|
this.env = buildLuaEnv(this.system);
|
|
const tl = new LuaEnv();
|
|
tl.setLocal("_GLOBAL", this.env);
|
|
for (const script of allScripts) {
|
|
try {
|
|
console.log("Now evaluating", script.ref);
|
|
const ast = parseLua(script.script, { ref: script.ref });
|
|
// We create a local scope for each script
|
|
const scriptEnv = new LuaEnv(this.env);
|
|
const sf = new LuaStackFrame(tl, ast.ctx);
|
|
await evalStatement(ast, scriptEnv, sf);
|
|
} catch (e: any) {
|
|
if (e instanceof LuaRuntimeError) {
|
|
const origin = resolveASTReference(e.sf.astCtx!);
|
|
if (origin) {
|
|
console.error(
|
|
`Error evaluating script: ${e.message} at [[${
|
|
encodeRef(origin)
|
|
}]]`,
|
|
);
|
|
continue;
|
|
}
|
|
}
|
|
console.error(
|
|
`Error evaluating script: ${e.message} for script: ${script.script}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
console.log("[Lua] Loaded", allScripts.length, "scripts");
|
|
} catch (e: any) {
|
|
console.error("Error reloading Lua scripts:", e.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
export function resolveASTReference(ctx?: ASTCtx): Ref | null {
|
|
if (!ctx?.ref) {
|
|
return null;
|
|
}
|
|
const ref = parseToRef(ctx.ref);
|
|
if (!ref) {
|
|
return null;
|
|
}
|
|
|
|
if (ref.details?.type === "position") {
|
|
ref.details.pos = (ref.details.pos as number) +
|
|
"```space-lua\n".length +
|
|
ctx.from!;
|
|
}
|
|
|
|
return ref;
|
|
}
|