From 5bd8452312fcaffee756044293ca413fe08e7e57 Mon Sep 17 00:00:00 2001 From: ForestOfLight Date: Sat, 30 May 2026 12:51:36 +0200 Subject: [PATCH] refactor: upgrade AddonAPIKit and propogate changes --- .../API/controllers/InstancesController.js | 17 ++-- packs/BP/scripts/lib/AddonAPIKit.js | 90 +++++++++++++++---- 2 files changed, 79 insertions(+), 28 deletions(-) diff --git a/packs/BP/scripts/API/controllers/InstancesController.js b/packs/BP/scripts/API/controllers/InstancesController.js index ba97d39..3cdfb4a 100644 --- a/packs/BP/scripts/API/controllers/InstancesController.js +++ b/packs/BP/scripts/API/controllers/InstancesController.js @@ -1,21 +1,20 @@ import { InstanceExistsError } from "../../classes/Errors/InstanceExistsError"; import { InstanceNotFoundError } from "../../classes/Errors/InstanceNotFoundError"; import { StructureNotFoundError } from "../../classes/Errors/StructureNotFoundError"; -import { APICallerError, VoidModel } from "../../lib/AddonAPIKit"; +import { APICallerError, VoidModel, APIController } from "../../lib/AddonAPIKit"; import { AddInstanceParameterModel, InstanceModel, InstanceNameParameterModel, InstancesModel, StructureMaterialsModel } from "../models/InstancesModel"; export class InstancesController extends APIController { #context; constructor(context) { - super({ - "instances": { callback: this.getInstances, parameterModel: VoidModel, returnModel: InstancesModel }, - "instance:get": { callback: this.getInstance, parameterModel: InstanceNameParameterModel, returnModel: InstanceModel }, - "instance:add": { callback: this.addInstance, parameterModel: AddInstanceParameterModel, returnModel: InstanceModel }, - "instance:edit": { callback: this.editInstance, parameterModel: InstanceModel, returnModel: InstanceModel }, - "instance:delete": { callback: this.deleteInstance, parameterModel: InstanceNameParameterModel, returnModel: VoidModel }, - "instance:materials": { callback: this.getMaterials, parameterModel: InstanceNameParameterModel, returnModel: StructureMaterialsModel } - }); + super(); + this.addEndpoint("instances", this.getInstances, VoidModel, InstancesModel); + this.addEndpoint("instance:get", this.getInstance, InstanceNameParameterModel, InstanceModel); + this.addEndpoint("instance:add", this.addInstance, AddInstanceParameterModel, InstanceModel); + this.addEndpoint("instance:edit", this.editInstance, InstanceModel, InstanceModel); + this.addEndpoint("instance:delete", this.deleteInstance, InstanceNameParameterModel, VoidModel); + this.addEndpoint("instance:materials", this.getMaterials, InstanceNameParameterModel, StructureMaterialsModel); this.#context = context; } diff --git a/packs/BP/scripts/lib/AddonAPIKit.js b/packs/BP/scripts/lib/AddonAPIKit.js index 97670ca..bb662ff 100644 --- a/packs/BP/scripts/lib/AddonAPIKit.js +++ b/packs/BP/scripts/lib/AddonAPIKit.js @@ -4,7 +4,7 @@ * See LICENSE for details. */ -// MCBE-IPC/ipc.js +// src/MCBE-IPC/ipc.js import { ScriptEventSource, system } from "@minecraft/server"; var UTIL; (function(UTIL2) { @@ -629,7 +629,7 @@ var IPC; IPC2.handle = handle; })(IPC || (IPC = {})); -// Errors/APIErrorEnum.js +// src/Errors/APIErrorEnum.js var APIErrorEnum = Object.freeze({ Unknown: 0, Success: 1, @@ -637,7 +637,7 @@ var APIErrorEnum = Object.freeze({ Server: 3 }); -// Errors/APICallerError.js +// src/Errors/APICallerError.js var APICallerError = class extends Error { constructor(error) { super(error.message); @@ -648,7 +648,7 @@ var APICallerError = class extends Error { } }; -// Errors/APIServerError.js +// src/Errors/APIServerError.js var APIServerError = class extends Error { constructor(error) { super(error.message); @@ -658,7 +658,7 @@ var APIServerError = class extends Error { } }; -// Errors/APIVersionMismatchError.js +// src/Errors/APIVersionMismatchError.js var APIVersionMismatchError = class extends Error { constructor(serverApiVersion, callerApiVersion) { super(`API version numbers do not match (${callerApiVersion} != ${serverApiVersion}). Please use API version ${serverApiVersion}.`); @@ -666,7 +666,7 @@ var APIVersionMismatchError = class extends Error { } }; -// APIModels.js +// src/APIModels.js var VoidModel = PROTO.Void; var ErrorModel = PROTO.Optional(PROTO.Object({ code: PROTO.Int8, @@ -682,14 +682,50 @@ var CallModelShell = { apiVersion: PROTO.String, parameterMap: void 0 }; +var EndpointModel = PROTO.String; +var EndpointsModel = PROTO.Array(EndpointModel); -// AddonAPI.js +// src/APIController.js +var APIController = class _APIController { + #endpoints = {}; + constructor() { + if (this.constructor === _APIController) + throw new Error("Cannot instantiate abstract class 'APIController'"); + } + get endpoints() { + return this.#endpoints; + } + addEndpoint(endpoint, callback, parameterModel, returnModel) { + this.#endpoints[endpoint] = { callback, parameterModel, returnModel }; + } +}; + +// src/EndpointsController.js +var EndpointsController = class extends APIController { + #api; + constructor(api) { + this.#api = api; + this.addEndpoint("endpoints", this.getEndpoints, VoidModel, EndpointsModel); + this.addEndpoint("endpoints:has", this.hasEndpoint, EndpointModel, PROTO.Boolean); + } + getEndpoints() { + return this.#api.endpoints; + } + hasEndpoint(endpoint) { + return this.getEndpoints().includes(endpoint); + } +}; + +// src/AddonAPI.js var AddonAPI = class { #name; #version; + #allEndpoints; constructor(name, version) { this.#name = name; this.#version = version; + const endpointsController = new EndpointsController(this); + this.setupController(endpointsController); } get name() { return this.#name; @@ -700,6 +736,9 @@ var AddonAPI = class { get endpointBase() { return this.#name + ":"; } + get endpoints() { + return this.#allEndpoints; + } setupController(apiController) { for (const [endpoint, features] of Object.entries(apiController.endpoints)) { const { callback, parameterModel, returnModel } = features; @@ -715,6 +754,7 @@ var AddonAPI = class { const parameters = Object.values(callPacket.parameterMap); return this.#handleCallback(apiVersion, callback, parameters); }); + this.#allEndpoints.push(endpointPath); } #handleCallback(apiVersion, callback, parameters) { try { @@ -760,28 +800,40 @@ var AddonAPI = class { } }; -// APIController.js -var APIController = class _APIController { - #endpoints; - constructor(endpoints) { - if (this.constructor === _APIController) - throw new Error("Cannot instantiate abstract class 'APIController'"); - this.#endpoints = endpoints; - } - get endpoints() { - return this.#endpoints; +// src/AddonAPICaller.js +import { system as system2 } from "@minecraft/server"; + +// src/Errors/APIEndpointNotFoundError.js +var APIEndpointNotFoundError = class extends Error { + constructor(endpoint) { + super(`Endpoint "${endpoint}" was not found.`); + this.name = "APIEndpointNotFoundError"; } }; -// AddonAPICaller.js +// src/AddonAPICaller.js var AddonAPICaller = class { + static #validEndpointCache = []; static async call(endpoint, parameterModel, parameterMap, returnDataModel) { - return await IPC.invoke(endpoint, parameterModel, parameterMap, returnDataModel).then((result) => result.value); + if (this.#validEndpointCache.length === 0) { + const endpointBase = endpoint.split(":")[0]; + await this.#populateValidEndpointCache(endpointBase); + } + if (this.#validEndpointCache.includes(endpoint)) + return await IPC.invoke(endpoint, parameterModel, parameterMap, returnDataModel).then((result) => result.value); + else + throw new APIEndpointNotFoundError(endpoint); + } + static async #populateValidEndpointCache(endpointBase) { + const endpointsEndpoint = endpointBase + ":endpoints"; + const validEndpoints = await IPC.invoke(endpointsEndpoint, VoidModel, void 0, PROTO.Boolean); + this.#validEndpointCache.push(...validEndpoints); } }; export { APICallerError, APIController, + APIErrorEnum, AddonAPI, AddonAPICaller, PROTO,