custom binding function config

This commit is contained in:
Asaki Yuki 2026-02-21 13:57:10 +07:00
parent 6bd3f54842
commit 63315c35c4
8 changed files with 97 additions and 15 deletions

8
config.d.ts vendored
View file

@ -1,4 +1,9 @@
import { Variable } from "./src/types/properties/value.ts" import { BindingItem, Variable } from "./src/types/properties/value.ts"
export interface RetBindingValue {
generate_bindings?: Array<{ source_property_name: string; target_property_name: string }>
return_value: string
}
export interface Config { export interface Config {
compiler?: { compiler?: {
@ -27,4 +32,5 @@ export interface Config {
}[] }[]
} }
global_variables?: Record<Variable, string> global_variables?: Record<Variable, string>
binding_functions?: Record<string, (...args: string[]) => RetBindingValue>
} }

View file

@ -22,7 +22,7 @@
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"dev": "tsc --watch", "dev": "tsc --watch",
"test": "bun test/app.ts --test", "test": "bun test/app.ts",
"prefetch": "bun scripts/prefetch", "prefetch": "bun scripts/prefetch",
"vanilla:defs": "bun scripts/vanilladefs", "vanilla:defs": "bun scripts/vanilladefs",
"gen:enums": "bun scripts/enum", "gen:enums": "bun scripts/enum",

View file

@ -6,7 +6,7 @@ export const config = {
packinfo: { packinfo: {
name: "AsaJS", name: "AsaJS",
description: "Create your Minecraft JSON-UI resource packs using JavaScript.", description: "Create your Minecraft JSON-UI resource packs using JavaScript.",
version: [4, 0, 1], version: [1, 0, 0],
}, },
compiler: { compiler: {
enabled: true, enabled: true,
@ -14,4 +14,19 @@ export const config = {
autoEnable: true, autoEnable: true,
importToPreview: false, importToPreview: false,
}, },
binding_functions: {
custom_abs: function (number) {
const randomAbs = RandomBindingString(16)
return {
generate_bindings: [
{
source_property_name: `[ abs(${number}) ]`,
target_property_name: randomAbs,
},
],
return_value: randomAbs,
}
},
},
} }

View file

@ -1,7 +1,7 @@
import fs from "fs" import fs from "fs"
import path from "path" import path from "path"
// @ts-ignore // @ts-ignore
import { Config } from "../../config.js" import { Config, RetBindingValue } from "../../config.js"
import { createRequire } from "module" import { createRequire } from "module"
const options: Record<string, unknown> = {} const options: Record<string, unknown> = {}
@ -10,16 +10,43 @@ for (const arg of process.argv) {
if (arg.startsWith("--")) options[arg.slice(2)] = true if (arg.startsWith("--")) options[arg.slice(2)] = true
} }
export const isTestMode = options["test"] ?? false export const isTestMode = !fs.existsSync("node_modules/asajs")
if (!fs.existsSync("asajs.config.js")) { if (!fs.existsSync("asajs.config.js")) {
if (isTestMode) { if (isTestMode) {
fs.writeFileSync( fs.writeFileSync(
"asajs.config.js", "asajs.config.js",
fs.readFileSync("resources/asajs.config.js", "utf-8").replace("asajs/", "./"), [
`export function RandomBindingString(length, base = 32) {
const chars = "0123456789abcdefghijklmnopqrstuvwxyz".slice(0, base)
const out = new Array()
try {
const buffer = new Uint8Array(length)
crypto.getRandomValues(buffer)
for (let i = 0; i < length; i++) {
out[i] = chars[buffer[i] % base]
}
} catch {
for (let i = 0; i < length; i++) {
out[i] = chars[Math.floor(Math.random() * base)]
}
}
return \`#$\{out.join("")}\`
}\n`,
fs.readFileSync("resources/asajs.config.js", "utf-8").replace("asajs/", "./"),
].join("\n"),
) )
} else { } else {
fs.copyFileSync("node_modules/asajs/resources/asajs.config.js", "asajs.config.js") fs.writeFileSync(
"asajs.config.js",
[
'import { RandomBindingString } from "asajs"\n',
fs.readFileSync("node_modules/asajs/resources/asajs.config.js", "utf-8"),
].join("\n"),
)
} }
} }
@ -29,6 +56,8 @@ export const isBuildMode = options["build"] ?? config.compiler?.enabled ?? false
export const isLinkMode = options["link"] ?? config.compiler?.autoImport ?? false export const isLinkMode = options["link"] ?? config.compiler?.autoImport ?? false
export const unLinked = options["unlink"] ?? !(config.compiler?.autoImport ?? true) export const unLinked = options["unlink"] ?? !(config.compiler?.autoImport ?? true)
export const bindingFuntions = config.binding_functions
if (!fs.existsSync(".gitignore")) { if (!fs.existsSync(".gitignore")) {
fs.writeFileSync(".gitignore", `node_modules`, "utf-8") fs.writeFileSync(".gitignore", `node_modules`, "utf-8")
} }

View file

@ -1,4 +1,6 @@
import { RandomBindingString } from "../../components/Utils.js" import { RandomBindingString, ResolveBinding } from "../../components/Utils.js"
import { BindingItem } from "../../types/properties/value.js"
import { bindingFuntions } from "../Configuration.js"
import { Expression, GenBinding } from "./types.js" import { Expression, GenBinding } from "./types.js"
type CallbackRet = { type CallbackRet = {
@ -198,3 +200,24 @@ export const defaultFunctions = {
} satisfies Record<string, Callback> } satisfies Record<string, Callback>
Object.entries(defaultFunctions).forEach(([key, value]) => FunctionMap.set(key, value)) Object.entries(defaultFunctions).forEach(([key, value]) => FunctionMap.set(key, value))
if (bindingFuntions)
Object.entries(bindingFuntions).forEach(([key, value]) => {
// @ts-ignore
FunctionMap.set(key, (...args) => {
const { generate_bindings, return_value } = value(...args)
if (generate_bindings) {
const resolve = ResolveBinding(new Map(), ...(generate_bindings as BindingItem[]))
return {
genBindings: resolve.map(({ source_property_name, target_property_name }) => ({
source: source_property_name!,
target: target_property_name!,
})),
value: return_value,
}
}
return {
value: return_value,
}
})
})

View file

@ -88,7 +88,10 @@ if (isBuildMode) {
console.log("Version:", config.packinfo?.version || [4, 0, 0]) console.log("Version:", config.packinfo?.version || [4, 0, 0])
console.log("UUID:", await BuildCache.get<[string, string]>("uuid")) console.log("UUID:", await BuildCache.get<[string, string]>("uuid"))
if (gamePath) if (gamePath)
console.log("Install Path:", `\x1b[32m"${path.join(gamePath, await getBuildFolderName())}"\x1b[0m`) console.log(
"Install Path:",
`\x1b[32m"${path.join(gamePath, "development_resource_packs", await getBuildFolderName())}"\x1b[0m`,
)
console.log("=============================================================") console.log("=============================================================")
} }
}) })

View file

@ -41,7 +41,7 @@ export async function createBuildFolder() {
} }
export async function getBuildFolderName() { export async function getBuildFolderName() {
return await BuildCache.getWithSetDefault("build-key", () => RandomString(16)) return await BuildCache.getWithSetDefault("build-key", () => `asajs-build-${RandomString(16)}`)
} }
export let gamePath: string | null = null export let gamePath: string | null = null

View file

@ -1,10 +1,16 @@
import { Anchor, Label, Modify } from ".." import { Anchor, Label, Modify } from ".."
const label = Label({ const label = Label(
text: "Hello World from my Custom UI!", {
shadow: true, text: "Hello World from my Custom UI!",
anchor: Anchor.TOP_MIDDLE, shadow: true,
offset: [0, 10], anchor: Anchor.TOP_MIDDLE,
offset: [0, 10],
},
"test",
).addBindings({
source_property_name: `[ custom_abs(#a) ]`,
target_property_name: "#text",
}) })
Modify("start", "start_screen_content").insertChild(label) Modify("start", "start_screen_content").insertChild(label)