diff --git a/projects/core/logic/api/modules/server/server-basic-core.ts b/projects/core/logic/api/modules/server/server-basic-core.ts index 8c67e1bd..735a0470 100644 --- a/projects/core/logic/api/modules/server/server-basic-core.ts +++ b/projects/core/logic/api/modules/server/server-basic-core.ts @@ -31,7 +31,7 @@ async function requestAsync( method: string = "GET", body: Record = {}, headers: Record = {} -): Promise { +): Promise> { const serializedBodyResult = serialize(body); const serializedHeadersResult = serialize(headers); @@ -46,22 +46,22 @@ async function requestAsync( headers )); - return new Response( + return Result.right(new Response( rawResult.Body ?? "", rawResult.Headers ?? {}, rawResult.Latency ?? 0, rawResult.StatusCode ?? 599, rawResult.Ok ?? false - ); + )); } - return new Response( + return Result.right(new Response( "Invalid body or header values", {}, 0, 400, false - ); + )); } function createHost(options = { diff --git a/projects/core/logic/api/modules/stdlib/encoding-core.ts b/projects/core/logic/api/modules/stdlib/encoding-core.ts index a430b679..811d30aa 100644 --- a/projects/core/logic/api/modules/stdlib/encoding-core.ts +++ b/projects/core/logic/api/modules/stdlib/encoding-core.ts @@ -1,9 +1,13 @@ -class TextDecoder { - decode(octets: number[]) { +import { Result } from "./functional-core"; + +class ByteEncoding { + private memo: Record; + + fromOctets(bytes: number[]): Result { let string = ""; let i = 0; - while (i < octets.length) { - let octet = octets[i]; + while (i < bytes.length) { + let octet = bytes[i]; const getDataFromOctet = (octet: number) => ({ [true]: { bytesNeeded: 0, codePoint: 0 }, @@ -15,32 +19,29 @@ class TextDecoder { let { bytesNeeded, codePoint } = getDataFromOctet(octet); - if (octets.length - i - bytesNeeded > 0) { + if (bytes.length - i - bytesNeeded > 0) { let k = 0; while (k < bytesNeeded) { - octet = octets[i + k + 1]; + octet = bytes[i + k + 1]; codePoint = (codePoint << 6) | (octet & 0x3F); k += 1; } } else { codePoint = 0xFFFD; - bytesNeeded = octets.length - i; + bytesNeeded = bytes.length - i; } string += String.fromCodePoint(codePoint); i += bytesNeeded + 1; } - return string; + return Result.right(string); } -} -class TextEncoder { - _memo: Record = {}; - encode(string: string) { - if(this._memo[string]) { - return this._memo[string]; + toOctets(string: string): Result { + if(this.memo[string]) { + return Result.right(this.memo[string]); } const octets = []; @@ -73,9 +74,9 @@ class TextEncoder { i += codePoint >= 0x10000 ? 2 : 1; } - this._memo[string] = octets; - return octets; + this.memo[string] = octets; + return Result.right(octets); } } -export { TextDecoder, TextEncoder } \ No newline at end of file +export { ByteEncoding } \ No newline at end of file diff --git a/projects/core/logic/api/modules/stdlib/encryption-core.ts b/projects/core/logic/api/modules/stdlib/encryption-core.ts index f68278df..ea8dd25f 100644 --- a/projects/core/logic/api/modules/stdlib/encryption-core.ts +++ b/projects/core/logic/api/modules/stdlib/encryption-core.ts @@ -1,10 +1,13 @@ import { interopCache } from "logic/runtime/interop-cache-core" import { UUID } from "types/internal/generic-types"; +import { Result } from "./functional-core"; -function newUuid(type: "v4" = "v4"): UUID { +function newUuid(type: "v4" = "v4"): Result { switch(type) { case "v4": - return interopCache.guid.newGuid(); + return Result.right(interopCache.guid.newGuid()); + default: + return Result.left(new Error("Invalid UUID type")); } } diff --git a/projects/core/logic/api/modules/stdlib/environment-core.ts b/projects/core/logic/api/modules/stdlib/environment-core.ts index 1cf55890..83bd03e7 100644 --- a/projects/core/logic/api/modules/stdlib/environment-core.ts +++ b/projects/core/logic/api/modules/stdlib/environment-core.ts @@ -1,12 +1,12 @@ import { interopCache } from "logic/runtime/interop-cache-core"; import { Result } from "./functional-core"; -function getArgs() { - return interopCache.environment.getCommandLineArgs(); +function getArgs(): Result { + return Result.right(interopCache.environment.getCommandLineArgs()); } -function getCurrentDir() { - return interopCache.environment.currentDirectory; +function getCurrentDir(): Result { + return Result.right(interopCache.environment.currentDirectory); } function getEnvVar(key: string): Result { @@ -23,13 +23,13 @@ function getEnvVar(key: string): Result { return Result.right(result); } -function getEnvVars(): Record { - return interopCache.environment.getEnvironmentVariables(); +function getEnvVars(): Result> { + return Result.right(interopCache.environment.getEnvironmentVariables()); } function setEnvVar(key: string, value: string | number | boolean | bigint) { const finalValue = value.toString(); - interopCache.environment.setEnvironmentVariable(key, finalValue); + return Result.right(interopCache.environment.setEnvironmentVariable(key, finalValue)); } export { getArgs, getCurrentDir, getEnvVar, getEnvVars, setEnvVar } \ No newline at end of file diff --git a/projects/core/logic/api/modules/stdlib/json-core.ts b/projects/core/logic/api/modules/stdlib/json-core.ts index 0e1ab170..5f10da3e 100644 --- a/projects/core/logic/api/modules/stdlib/json-core.ts +++ b/projects/core/logic/api/modules/stdlib/json-core.ts @@ -1,24 +1,22 @@ import { Result } from "./functional-core"; -function deserialize(json: string) { +function deserialize(json: string): Result { try { const value = JSON.parse(json); - const result = Result.right(value); - return result as T; + return Result.right(value); } catch(e) { return Result.left(e); } } -function serialize(target: T) { +function serialize(target: T): Result { try { const value = JSON.stringify(target); - const result = Result.right(value); - return result as Result; + return Result.right(value); } catch(e) { - return Result.left(e) as Result; + return Result.left(e); } } diff --git a/projects/core/logic/api/modules/stdlib/process-core.ts b/projects/core/logic/api/modules/stdlib/process-core.ts index 519c1ea5..31fef0ed 100644 --- a/projects/core/logic/api/modules/stdlib/process-core.ts +++ b/projects/core/logic/api/modules/stdlib/process-core.ts @@ -1,7 +1,9 @@ import { interopCache } from "logic/runtime/interop-cache-core"; +import { Result } from "./functional-core"; -function exit(exitCode: number) { +function exit(exitCode = 0): Result { interopCache.process.exit(exitCode); + return Result.left(new Error("Failed to finish the current process")) as Result; } function getPid(): number { diff --git a/projects/core/logic/api/modules/stdlib/stdlib.ts b/projects/core/logic/api/modules/stdlib/stdlib.ts index ba379ee6..1fb7b78c 100644 --- a/projects/core/logic/api/modules/stdlib/stdlib.ts +++ b/projects/core/logic/api/modules/stdlib/stdlib.ts @@ -2,21 +2,21 @@ import { getArgs, getCurrentDir, getEnvVar, getEnvVars, setEnvVar } from "./envi import { Result } from "./functional-core"; import { deserialize, serialize } from "./json-core"; import { exit, getPid } from "./process-core"; -import { Moment } from "./time-core"; -import { TextDecoder, TextEncoder } from "./encoding-core"; +import { Moment, now } from "./time-core"; +import { ByteEncoding } from "./encoding-core"; import { newUuid } from "./encryption-core"; const stdlib = { encoding: { - TextDecoder, - TextEncoder + ByteEncoding, }, json: { serialize, deserialize }, time: { - Moment + Moment, + now }, environment: { getArgs, diff --git a/projects/core/logic/api/modules/stdlib/time-core.ts b/projects/core/logic/api/modules/stdlib/time-core.ts index 65396304..bd2c2432 100644 --- a/projects/core/logic/api/modules/stdlib/time-core.ts +++ b/projects/core/logic/api/modules/stdlib/time-core.ts @@ -1,3 +1,5 @@ +import { Result } from "./functional-core"; + type MomentArguments = { year?: number; month?: number; @@ -71,20 +73,25 @@ class Moment { if (shouldThrow) throw new Error("Invalid values for making a time representation."); } - copyWith(args: MomentArguments) { + new(modifiers: MomentArguments) { return new Moment({ - year: this._year + args.year ?? 0, - month: this._month + args.month ?? 1, - day: this._day + args.day ?? 0, - hour: this._hour + args.hour ?? 0, - minute: this._minute + args.minute ?? 0, - second: this._second + args.second ?? 0, - millisecond: this._millisecond + args.millisecond ?? 0, - microsecond: this._microsecond + args.microsecond ?? 0, - nanosecond: this._nanosecond + args.nanosecond ?? 0, - timezoneModifier: args.timezoneModifier ?? 0, + year: this._year + modifiers.year ?? 0, + month: this._month + modifiers.month ?? 1, + day: this._day + modifiers.day ?? 0, + hour: this._hour + modifiers.hour ?? 0, + minute: this._minute + modifiers.minute ?? 0, + second: this._second + modifiers.second ?? 0, + millisecond: this._millisecond + modifiers.millisecond ?? 0, + microsecond: this._microsecond + modifiers.microsecond ?? 0, + nanosecond: this._nanosecond + modifiers.nanosecond ?? 0, + timezoneModifier: modifiers.timezoneModifier ?? 0, }); } } -export { Moment } \ No newline at end of file +function now(): Result { + const moment = new Moment(new Date(performance.now())); + return Result.right(moment); +} + +export { Moment, now } \ No newline at end of file diff --git a/projects/core/logic/runtime/interop-cache-core.ts b/projects/core/logic/runtime/interop-cache-core.ts index 5a420d12..e9f8aa2c 100644 --- a/projects/core/logic/runtime/interop-cache-core.ts +++ b/projects/core/logic/runtime/interop-cache-core.ts @@ -21,7 +21,7 @@ const interopCache = { setEnvironmentVariable: getStaticMethod("System:Environment:SetEnvironmentVariable") }, process: { - exit: getStaticMethod("System:Environment:Exit"), + exit: _$internalBinding["ProcessExit"], getCurrentProcess: getStaticMethod("System.Diagnostics:Process:GetCurrentProcess") }, guid: { diff --git a/projects/native/MelonRuntime.Core/Library/BindingsManager.cs b/projects/native/MelonRuntime.Core/Library/BindingsManager.cs index dfb73fa7..02df59f0 100644 --- a/projects/native/MelonRuntime.Core/Library/BindingsManager.cs +++ b/projects/native/MelonRuntime.Core/Library/BindingsManager.cs @@ -11,6 +11,7 @@ using MelonRuntime.WebServices.Entities; using Microsoft.VisualBasic.FileIO; using Newtonsoft.Json; +using System.Diagnostics; using System.Dynamic; namespace MelonRuntime.Core.Library @@ -50,7 +51,8 @@ public IDictionary GetBindings() GetTimeBindings(), new() { - ["NewGuid"] = new Func(() => Guid.NewGuid().ToString()) + ["NewGuid"] = new Func(() => Guid.NewGuid().ToString()), + ["ProcessExit"] = new Action((code) => Environment.Exit(code)) } };