Skip to content

Commit 6df68b6

Browse files
committed
new scripts: jaylydb and assert
Fix JaylyDev#240
1 parent 5b63756 commit 6df68b6

File tree

8 files changed

+141
-41
lines changed

8 files changed

+141
-41
lines changed

scripts/assert/index.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Indicates the failure of an assertion. All errors thrown by the `assert` function
3+
* will be instances of the `AssertionError` class.
4+
*/
5+
export class AssertionError extends Error {
6+
constructor(options) {
7+
if (typeof options.message !== "object" && typeof options.message !== "undefined")
8+
throw new Error('The "options" argument must be an object.' + "\n");
9+
super();
10+
this.code = "ERR_ASSERTION";
11+
this.name = AssertionError.name;
12+
this.generatedMessage = !options.message;
13+
this.actual = this.generatedMessage ? options.actual : false;
14+
this.expected = this.generatedMessage ? options.expected : true;
15+
this.operator = this.generatedMessage ? options.operator : "==";
16+
this.message = this.generatedMessage ? `${JSON.stringify(this.actual)} ${this.operator} ${JSON.stringify(this.expected)}` + "\n" : options.message + "\n";
17+
}
18+
}
19+
/**
20+
* Tests if `value` is equal to true, an `AssertionError` is thrown otherwise.
21+
*/
22+
export function assert(value, message) {
23+
let error;
24+
if (typeof message === "string")
25+
error = new AssertionError({ message });
26+
else if (message instanceof Error)
27+
error = message;
28+
else
29+
error = new AssertionError({ actual: false, expected: true, operator: "!=" });
30+
if (!value)
31+
throw error;
32+
}

scripts/assert/index.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
/**
3+
* Indicates the failure of an assertion. All errors thrown by the `assert` function
4+
* will be instances of the `AssertionError` class.
5+
*/
6+
export class AssertionError extends Error {
7+
actual: unknown;
8+
expected: unknown;
9+
operator: string;
10+
generatedMessage: boolean;
11+
code = "ERR_ASSERTION";
12+
constructor(options?: {
13+
/** If provided, the error message is set to this value. */
14+
message?: string | undefined;
15+
/** The `actual` property on the error instance. */
16+
actual?: unknown | undefined;
17+
/** The `expected` property on the error instance. */
18+
expected?: unknown | undefined;
19+
/** The `operator` property on the error instance. */
20+
operator?: string | undefined;
21+
}) {
22+
if (typeof options.message !== "object" && typeof options.message !== "undefined") throw new Error('The "options" argument must be an object.' + "\n");
23+
super();
24+
this.name = AssertionError.name;
25+
this.generatedMessage = !options.message;
26+
this.actual = this.generatedMessage ? options.actual : false;
27+
this.expected = this.generatedMessage ? options.expected : true;
28+
this.operator = this.generatedMessage ? options.operator : "==";
29+
this.message = this.generatedMessage ? `${JSON.stringify(this.actual)} ${this.operator} ${JSON.stringify(this.expected)}` + "\n" : options.message + "\n";
30+
}
31+
}
32+
/**
33+
* Tests if `value` is equal to true, an `AssertionError` is thrown otherwise.
34+
*/
35+
export function assert(value: unknown, message?: string | Error): asserts value {
36+
let error: string | Error;
37+
if (typeof message === "string") error = new AssertionError({ message });
38+
else if (message instanceof Error) error = message;
39+
else error = new AssertionError({ actual: false, expected: true, operator: "!=" });
40+
if (!value) throw error;
41+
}

scripts/jaylydb/index.d.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,48 @@
11
/**
2-
* Database using scoreboard
3-
* @beta
2+
* A simple database for storing data in a Minecraft world, using scoreboard.
43
*/
54
declare class JaylyDB implements Map<string, string | number | boolean> {
6-
constructor(id: string);
7-
private objective;
8-
private getParticipant;
5+
/**
6+
* @param id An identifier for the database
7+
* @param encrypted whether this database is encrypted or not, note that encryption state cannot be changed after creation
8+
*/
9+
constructor(id: string, encrypted?: boolean);
10+
/**
11+
* @returns the number of elements in the database.
12+
*/
13+
get size(): number;
14+
/**
15+
* Clears every element in the database.
16+
*/
917
clear(): void;
18+
/**
19+
* @returns — true if an element in the database exists and has been removed, false otherwise.
20+
*/
1021
delete(key: string): boolean;
11-
forEach(callbackfn: (value: string | number | boolean, key: string, map: Map<string, string | number | boolean>) => void): void;
12-
get(key: string): string | number | boolean;
22+
/**
23+
* Executes a provided function once per each key/value pair in the database, in insertion order.
24+
*/
25+
forEach(callbackfn: (value: string | number | boolean, key: string, map: this) => void): void;
26+
/**
27+
* Returns a specified element from the database.
28+
* @param key The key of the element to return.
29+
* @param reloadCache If set to true, the database object reloads cache before returning the element. This is made for when the database is modified from a external source.
30+
* @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
31+
*/
32+
get(key: string, reloadCache?: boolean): string | number | boolean | undefined;
1333
has(key: string): boolean;
34+
/**
35+
* Adds a new element with a specified key and value to the database. If an element with the same key already exists, the element will be updated.
36+
*/
1437
set(key: string, value: string | number | boolean): this;
15-
get size(): number;
1638
entries(): IterableIterator<[string, string | number | boolean]>;
39+
/**
40+
* Returns an iterable of keys in the database
41+
*/
1742
keys(): IterableIterator<string>;
43+
/**
44+
* Returns an iterable of values in the map
45+
*/
1846
values(): IterableIterator<string | number | boolean>;
1947
[Symbol.iterator](): IterableIterator<[string, string | number | boolean]>;
2048
[Symbol.toStringTag]: string;

scripts/jaylydb/index.js

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
// Script example for ScriptAPI
2-
// Author: Jayly <https://github.com/JaylyDev>
3-
// Project: https://github.com/JaylyDev/ScriptAPI
41
var _a;
52
// Script example for ScriptAPI
63
// Author: Jayly <https://github.com/JaylyDev>
74
// Project: https://github.com/JaylyDev/ScriptAPI
85
import { ScoreboardIdentityType, world } from "@minecraft/server";
9-
const version = "1.0.4";
6+
const version = "1.0.5";
107
const str = () => ('00000000000000000' + (Math.random() * 0xffffffffffffffff).toString(16)).slice(-16);
118
/**
129
* A rough mechanism for create a random uuid. Not as secure as uuid without as much of a guarantee of uniqueness,
@@ -19,22 +16,22 @@ const uuid = () => {
1916
return `${a.slice(0, 8)}-${a.slice(8, 12)}-4${a.slice(13)}-a${b.slice(1, 4)}-${b.slice(4)}`;
2017
};
2118
const allowedTypes = ["string", "number", "boolean"];
22-
function encrypt(data, salt) {
19+
const encrypt = (data, salt) => {
2320
const encryptedChars = [];
2421
for (let i = 0; i < data.length; i++) {
2522
const charCode = data.charCodeAt(i) + salt.charCodeAt(i % salt.length);
2623
encryptedChars.push(charCode);
2724
}
2825
return String.fromCharCode(...encryptedChars);
29-
}
30-
function decrypt(encrypted, salt) {
26+
};
27+
const decrypt = (encrypted, salt) => {
3128
const decryptedChars = [];
3229
for (let i = 0; i < encrypted.length; i++) {
3330
const charCode = encrypted.charCodeAt(i) - salt.charCodeAt(i % salt.length);
3431
decryptedChars.push(charCode);
3532
}
3633
return String.fromCharCode(...decryptedChars);
37-
}
34+
};
3835
const CreateCrashReport = (action, data, error, salt) => {
3936
console.log("[JaylyDB] Failed to " + action + " JSON data.", "\nVersion: " + version, "\nData: " + data, "\nSalt: " + salt, "\nError: " + error.message, "\n" + error.stack);
4037
throw new Error(`Failed to ${action} data. Please check content log file for more info.\n`);
@@ -134,14 +131,11 @@ class JaylyDB {
134131
* @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
135132
*/
136133
get(key, reloadCache = false) {
137-
if (!reloadCache && this.displayDataCache.has(key)) {
138-
const displayData = this.displayDataCache.get(key);
139-
return displayData[key];
140-
}
134+
if (!reloadCache && this.displayDataCache.has(key))
135+
return this.displayDataCache.get(key);
141136
const participant = this.participants.get(key);
142-
if (!participant) {
137+
if (!participant)
143138
return undefined;
144-
}
145139
const displayName = participant.displayName;
146140
const displayData = DisplayName.parse(displayName, this.salt);
147141
this.displayDataCache.set(key, displayData[key]);

scripts/jaylydb/index.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Author: Jayly <https://github.com/JaylyDev>
33
// Project: https://github.com/JaylyDev/ScriptAPI
44
import { ScoreboardIdentity, ScoreboardIdentityType, ScoreboardObjective, world } from "@minecraft/server";
5-
const version = "1.0.4";
5+
const version = "1.0.5";
66
const str = () => ('00000000000000000' + (Math.random() * 0xffffffffffffffff).toString(16)).slice(-16);
77
/**
88
* A rough mechanism for create a random uuid. Not as secure as uuid without as much of a guarantee of uniqueness,
@@ -17,23 +17,23 @@ const uuid = () => {
1717

1818
const allowedTypes = ["string", "number", "boolean"];
1919

20-
function encrypt(data: string, salt: string): string {
20+
const encrypt = (data: string, salt: string): string => {
2121
const encryptedChars: number[] = [];
2222
for (let i = 0; i < data.length; i++) {
2323
const charCode = data.charCodeAt(i) + salt.charCodeAt(i % salt.length);
2424
encryptedChars.push(charCode);
2525
}
2626
return String.fromCharCode(...encryptedChars);
27-
}
27+
};
2828

29-
function decrypt(encrypted: string, salt: string): string {
29+
const decrypt = (encrypted: string, salt: string): string => {
3030
const decryptedChars: number[] = [];
3131
for (let i = 0; i < encrypted.length; i++) {
3232
const charCode = encrypted.charCodeAt(i) - salt.charCodeAt(i % salt.length);
3333
decryptedChars.push(charCode);
3434
}
3535
return String.fromCharCode(...decryptedChars);
36-
}
36+
};
3737

3838
const CreateCrashReport = (action: "save" | "load", data: string, error: Error, salt?: string): never => {
3939
console.log(
@@ -45,6 +45,7 @@ const CreateCrashReport = (action: "save" | "load", data: string, error: Error,
4545
);
4646
throw new Error(`Failed to ${action} data. Please check content log file for more info.\n`);
4747
};
48+
4849
/**
4950
* Parse and stringify scoreboard display name
5051
* @beta
@@ -143,15 +144,9 @@ class JaylyDB implements Map<string, string | number | boolean> {
143144
* @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
144145
*/
145146
get(key: string, reloadCache: boolean = false): string | number | boolean | undefined {
146-
if (!reloadCache && this.displayDataCache.has(key)) {
147-
const displayData = this.displayDataCache.get(key)!;
148-
return displayData[key];
149-
}
150-
147+
if (!reloadCache && this.displayDataCache.has(key)) return this.displayDataCache.get(key)!;
151148
const participant = this.participants.get(key);
152-
if (!participant) {
153-
return undefined;
154-
}
149+
if (!participant) return undefined;
155150

156151
const displayName = participant.displayName;
157152
const displayData = DisplayName.parse(displayName, this.salt);

scripts/jaylydb/tests.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { world } from "@minecraft/server";
22
import { JaylyDB } from "./index.js";
3+
import { AssertionError, assert } from "assert/index";
34
/**
45
* @param {number} length
56
*/
@@ -77,3 +78,18 @@ world.afterEvents.worldInitialize.subscribe(() => {
7778
benchmark(db_encrypted, 100, bytes);
7879
}
7980
});
81+
function generateRandomString(length) {
82+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
83+
let result = '';
84+
85+
for (let i = 0; i < length; i++) {
86+
const randomIndex = Math.floor(Math.random() * characters.length);
87+
result += characters.charAt(randomIndex);
88+
}
89+
90+
return result;
91+
}
92+
const datab = new JaylyDB(generateRandomString(10));
93+
const expected = "test41";
94+
datab.set("test1", expected);
95+
assert(datab.get("test1") === expected, new AssertionError({ actual: datab.get("test1"), operator: "!=", expected }));

scripts/minecraft-language/index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Script example for ScriptAPI
2-
// Author: bot174 <https://github.com/bot174>
3-
// Project: https://github.com/JaylyDev/ScriptAPI
41
export const languageKeys = [
52
"accessibility.disableTTS",
63
"accessibility.enableTTS",

scripts/simulated-player/index.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Script example for ScriptAPI
2-
// Author: Jayly <https://github.com/JaylyDev>
3-
// Project: https://github.com/JaylyDev/ScriptAPI
41
import * as Minecraft from "@minecraft/server";
52
/**
63
* A simulated player can be used to represent

0 commit comments

Comments
 (0)