Initial commit: New MoreminiMore website with fresh design

This commit is contained in:
MoreminiMore
2026-04-22 01:59:05 +07:00
commit 76409638cc
14010 changed files with 2052041 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
export { readJsonObject } from "./json/decode.js";
export { writeJsonObject } from "./json/encode.js";
export { readProtobufMessage } from "./protobuf/decode.js";
export { writeProtobufMessage } from "./protobuf/encode.js";

View File

@@ -0,0 +1,4 @@
export { readJsonObject } from "./json/decode.js";
export { writeJsonObject } from "./json/encode.js";
export { readProtobufMessage } from "./protobuf/decode.js";
export { writeProtobufMessage } from "./protobuf/encode.js";

View File

@@ -0,0 +1,13 @@
export type Value = Obj | Array<Value> | string | number | true | false | null;
export type Obj = {
[key: string]: Value | undefined;
};
export type ObjectFun<T> = (obj: Obj) => T;
export declare function string(value: Value | undefined): string;
export declare function stringOpt(value: Value | undefined): string | undefined;
export declare function number(value: Value | undefined): number;
export declare function boolean(value: Value | undefined): boolean;
export declare function array(value: Value | undefined): Array<Value>;
export declare function object(value: Value | undefined): Obj;
export declare function arrayObjectsMap<T>(value: Value | undefined, fun: ObjectFun<T>): Array<T>;
export declare function readJsonObject<T>(value: unknown, fun: ObjectFun<T>): T;

View File

@@ -0,0 +1,59 @@
import { ProtoError } from "../../errors.js";
export function string(value) {
if (typeof value === "string") {
return value;
}
throw typeError(value, "string");
}
export function stringOpt(value) {
if (value === null || value === undefined) {
return undefined;
}
else if (typeof value === "string") {
return value;
}
throw typeError(value, "string or null");
}
export function number(value) {
if (typeof value === "number") {
return value;
}
throw typeError(value, "number");
}
export function boolean(value) {
if (typeof value === "boolean") {
return value;
}
throw typeError(value, "boolean");
}
export function array(value) {
if (Array.isArray(value)) {
return value;
}
throw typeError(value, "array");
}
export function object(value) {
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
return value;
}
throw typeError(value, "object");
}
export function arrayObjectsMap(value, fun) {
return array(value).map((elemValue) => fun(object(elemValue)));
}
function typeError(value, expected) {
if (value === undefined) {
return new ProtoError(`Expected ${expected}, but the property was missing`);
}
let received = typeof value;
if (value === null) {
received = "null";
}
else if (Array.isArray(value)) {
received = "array";
}
return new ProtoError(`Expected ${expected}, received ${received}`);
}
export function readJsonObject(value, fun) {
return fun(object(value));
}

View File

@@ -0,0 +1,14 @@
export type ObjectFun<T> = (w: ObjectWriter, value: T) => void;
export declare class ObjectWriter {
#private;
constructor(output: Array<string>);
begin(): void;
end(): void;
string(name: string, value: string): void;
stringRaw(name: string, value: string): void;
number(name: string, value: number): void;
boolean(name: string, value: boolean): void;
object<T>(name: string, value: T, valueFun: ObjectFun<T>): void;
arrayObjects<T>(name: string, values: Array<T>, valueFun: ObjectFun<T>): void;
}
export declare function writeJsonObject<T>(value: T, fun: ObjectFun<T>): string;

View File

@@ -0,0 +1,72 @@
export class ObjectWriter {
#output;
#isFirst;
constructor(output) {
this.#output = output;
this.#isFirst = false;
}
begin() {
this.#output.push('{');
this.#isFirst = true;
}
end() {
this.#output.push('}');
this.#isFirst = false;
}
#key(name) {
if (this.#isFirst) {
this.#output.push('"');
this.#isFirst = false;
}
else {
this.#output.push(',"');
}
this.#output.push(name);
this.#output.push('":');
}
string(name, value) {
this.#key(name);
this.#output.push(JSON.stringify(value));
}
stringRaw(name, value) {
this.#key(name);
this.#output.push('"');
this.#output.push(value);
this.#output.push('"');
}
number(name, value) {
this.#key(name);
this.#output.push("" + value);
}
boolean(name, value) {
this.#key(name);
this.#output.push(value ? "true" : "false");
}
object(name, value, valueFun) {
this.#key(name);
this.begin();
valueFun(this, value);
this.end();
}
arrayObjects(name, values, valueFun) {
this.#key(name);
this.#output.push('[');
for (let i = 0; i < values.length; ++i) {
if (i !== 0) {
this.#output.push(',');
}
this.begin();
valueFun(this, values[i]);
this.end();
}
this.#output.push(']');
}
}
export function writeJsonObject(value, fun) {
const output = [];
const writer = new ObjectWriter(output);
writer.begin();
fun(writer, value);
writer.end();
return output.join("");
}

View File

@@ -0,0 +1,32 @@
export interface MessageDef<T> {
default(): T;
[tag: number]: (r: FieldReader, msg: T) => T | void;
}
declare class MessageReader {
#private;
constructor(array: Uint8Array);
varint(): number;
varintBig(): bigint;
bytes(length: number): Uint8Array;
double(): number;
skipVarint(): void;
skip(count: number): void;
eof(): boolean;
}
export declare class FieldReader {
#private;
constructor(reader: MessageReader);
setup(wireType: number): void;
bytes(): Uint8Array;
string(): string;
message<T>(def: MessageDef<T>): T;
int32(): number;
uint32(): number;
bool(): boolean;
uint64(): bigint;
sint64(): bigint;
double(): number;
maybeSkip(): void;
}
export declare function readProtobufMessage<T>(data: Uint8Array, def: MessageDef<T>): T;
export {};

View File

@@ -0,0 +1,150 @@
import { ProtoError } from "../../errors.js";
import { VARINT, FIXED_64, LENGTH_DELIMITED, FIXED_32 } from "./util.js";
class MessageReader {
#array;
#view;
#pos;
constructor(array) {
this.#array = array;
this.#view = new DataView(array.buffer, array.byteOffset, array.byteLength);
this.#pos = 0;
}
varint() {
let value = 0;
for (let shift = 0;; shift += 7) {
const byte = this.#array[this.#pos++];
value |= (byte & 0x7f) << shift;
if (!(byte & 0x80)) {
break;
}
}
return value;
}
varintBig() {
let value = 0n;
for (let shift = 0n;; shift += 7n) {
const byte = this.#array[this.#pos++];
value |= BigInt(byte & 0x7f) << shift;
if (!(byte & 0x80)) {
break;
}
}
return value;
}
bytes(length) {
const array = new Uint8Array(this.#array.buffer, this.#array.byteOffset + this.#pos, length);
this.#pos += length;
return array;
}
double() {
const value = this.#view.getFloat64(this.#pos, true);
this.#pos += 8;
return value;
}
skipVarint() {
for (;;) {
const byte = this.#array[this.#pos++];
if (!(byte & 0x80)) {
break;
}
}
}
skip(count) {
this.#pos += count;
}
eof() {
return this.#pos >= this.#array.byteLength;
}
}
export class FieldReader {
#reader;
#wireType;
constructor(reader) {
this.#reader = reader;
this.#wireType = -1;
}
setup(wireType) {
this.#wireType = wireType;
}
#expect(expectedWireType) {
if (this.#wireType !== expectedWireType) {
throw new ProtoError(`Expected wire type ${expectedWireType}, got ${this.#wireType}`);
}
this.#wireType = -1;
}
bytes() {
this.#expect(LENGTH_DELIMITED);
const length = this.#reader.varint();
return this.#reader.bytes(length);
}
string() {
return new TextDecoder().decode(this.bytes());
}
message(def) {
return readProtobufMessage(this.bytes(), def);
}
int32() {
this.#expect(VARINT);
return this.#reader.varint();
}
uint32() {
return this.int32();
}
bool() {
return this.int32() !== 0;
}
uint64() {
this.#expect(VARINT);
return this.#reader.varintBig();
}
sint64() {
const value = this.uint64();
return (value >> 1n) ^ (-(value & 1n));
}
double() {
this.#expect(FIXED_64);
return this.#reader.double();
}
maybeSkip() {
if (this.#wireType < 0) {
return;
}
else if (this.#wireType === VARINT) {
this.#reader.skipVarint();
}
else if (this.#wireType === FIXED_64) {
this.#reader.skip(8);
}
else if (this.#wireType === LENGTH_DELIMITED) {
const length = this.#reader.varint();
this.#reader.skip(length);
}
else if (this.#wireType === FIXED_32) {
this.#reader.skip(4);
}
else {
throw new ProtoError(`Unexpected wire type ${this.#wireType}`);
}
this.#wireType = -1;
}
}
export function readProtobufMessage(data, def) {
const msgReader = new MessageReader(data);
const fieldReader = new FieldReader(msgReader);
let value = def.default();
while (!msgReader.eof()) {
const key = msgReader.varint();
const tag = key >> 3;
const wireType = key & 0x7;
fieldReader.setup(wireType);
const tagFun = def[tag];
if (tagFun !== undefined) {
const returnedValue = tagFun(fieldReader, value);
if (returnedValue !== undefined) {
value = returnedValue;
}
}
fieldReader.maybeSkip();
}
return value;
}

View File

@@ -0,0 +1,15 @@
export type MessageFun<T> = (w: MessageWriter, msg: T) => void;
export declare class MessageWriter {
#private;
constructor();
bytes(tag: number, value: Uint8Array): void;
string(tag: number, value: string): void;
message<T>(tag: number, value: T, fun: MessageFun<T>): void;
int32(tag: number, value: number): void;
uint32(tag: number, value: number): void;
bool(tag: number, value: boolean): void;
sint64(tag: number, value: bigint): void;
double(tag: number, value: number): void;
data(): Uint8Array;
}
export declare function writeProtobufMessage<T>(value: T, fun: MessageFun<T>): Uint8Array;

View File

@@ -0,0 +1,95 @@
import { VARINT, FIXED_64, LENGTH_DELIMITED } from "./util.js";
export class MessageWriter {
#buf;
#array;
#view;
#pos;
constructor() {
this.#buf = new ArrayBuffer(256);
this.#array = new Uint8Array(this.#buf);
this.#view = new DataView(this.#buf);
this.#pos = 0;
}
#ensure(extra) {
if (this.#pos + extra <= this.#buf.byteLength) {
return;
}
let newCap = this.#buf.byteLength;
while (newCap < this.#pos + extra) {
newCap *= 2;
}
const newBuf = new ArrayBuffer(newCap);
const newArray = new Uint8Array(newBuf);
const newView = new DataView(newBuf);
newArray.set(new Uint8Array(this.#buf, 0, this.#pos));
this.#buf = newBuf;
this.#array = newArray;
this.#view = newView;
}
#varint(value) {
this.#ensure(5);
value = 0 | value;
do {
let byte = value & 0x7f;
value >>>= 7;
byte |= (value ? 0x80 : 0);
this.#array[this.#pos++] = byte;
} while (value);
}
#varintBig(value) {
this.#ensure(10);
value = value & 0xffffffffffffffffn;
do {
let byte = Number(value & 0x7fn);
value >>= 7n;
byte |= (value ? 0x80 : 0);
this.#array[this.#pos++] = byte;
} while (value);
}
#tag(tag, wireType) {
this.#varint((tag << 3) | wireType);
}
bytes(tag, value) {
this.#tag(tag, LENGTH_DELIMITED);
this.#varint(value.byteLength);
this.#ensure(value.byteLength);
this.#array.set(value, this.#pos);
this.#pos += value.byteLength;
}
string(tag, value) {
this.bytes(tag, new TextEncoder().encode(value));
}
message(tag, value, fun) {
const writer = new MessageWriter();
fun(writer, value);
this.bytes(tag, writer.data());
}
int32(tag, value) {
this.#tag(tag, VARINT);
this.#varint(value);
}
uint32(tag, value) {
this.int32(tag, value);
}
bool(tag, value) {
this.int32(tag, value ? 1 : 0);
}
sint64(tag, value) {
this.#tag(tag, VARINT);
this.#varintBig((value << 1n) ^ (value >> 63n));
}
double(tag, value) {
this.#tag(tag, FIXED_64);
this.#ensure(8);
this.#view.setFloat64(this.#pos, value, true);
this.#pos += 8;
}
data() {
return new Uint8Array(this.#buf, 0, this.#pos);
}
}
export function writeProtobufMessage(value, fun) {
const w = new MessageWriter();
fun(w, value);
return w.data();
}

View File

@@ -0,0 +1,7 @@
export type WireType = 0 | 1 | 2 | 3 | 4 | 5;
export declare const VARINT: WireType;
export declare const FIXED_64: WireType;
export declare const LENGTH_DELIMITED: WireType;
export declare const GROUP_START: WireType;
export declare const GROUP_END: WireType;
export declare const FIXED_32: WireType;

View File

@@ -0,0 +1,6 @@
export const VARINT = 0;
export const FIXED_64 = 1;
export const LENGTH_DELIMITED = 2;
export const GROUP_START = 3;
export const GROUP_END = 4;
export const FIXED_32 = 5;