From 2ff6673be160319fb6710a4805a11a11ed7c7022 Mon Sep 17 00:00:00 2001 From: lete114 Date: Fri, 19 Jun 2026 22:54:27 +0800 Subject: [PATCH] fix: resolve review issues before v1.0.0 release - fix(ipc): strict c param check === '1' - fix(protocol): add sourceType overload to once() - fix(rpc): reject unknown response format - fix(experience): reset #xp in setLevel() - fix(discover): send {} when meta is undefined - fix(chunker): validate compressed flag consistency - refactor(utils): rename getCubeRange.ts -> range.ts - refactor(utils): lowercase experience.ts filename - docs(runtime): fix README color -> Color --- packages/discover/src/discover.ts | 6 ++---- packages/ipc/src/chunk.ts | 4 ++++ packages/ipc/src/ipc.ts | 2 +- packages/protocol/src/protocol.ts | 7 ++++++- packages/rpc/src/rpc.ts | 14 +++++++++++--- packages/runtime/README.md | 2 +- .../utils/src/{Experience.ts => experience.ts} | 1 + packages/utils/src/index.ts | 6 +++--- packages/utils/src/{getCubeRange.ts => range.ts} | 12 ------------ 9 files changed, 29 insertions(+), 25 deletions(-) rename packages/utils/src/{Experience.ts => experience.ts} (99%) rename packages/utils/src/{getCubeRange.ts => range.ts} (71%) diff --git a/packages/discover/src/discover.ts b/packages/discover/src/discover.ts index d679409..4edd6da 100644 --- a/packages/discover/src/discover.ts +++ b/packages/discover/src/discover.ts @@ -86,8 +86,6 @@ export class Discover { * @returns An unsubscribe function to deregister the service */ register>(type: string, meta?: M): () => void { - const _meta = meta ?? {} - const n = this.#nextInstanceIds.get(type) ?? 1 this.#nextInstanceIds.set(type, n + 1) @@ -95,7 +93,7 @@ export class Discover { ? `${type}.discover` : `${type.replace(/^([^.]+)/, `$1-${n}`)}.discover` - const body = JSON.stringify({ meta: _meta }) + const body = meta !== undefined ? JSON.stringify({ meta }) : '{}' const post = (): void => { const nonce = unique() @@ -110,7 +108,7 @@ export class Discover { const timer = system.runInterval(post, ms2ticks(this.#options.heartbeatInterval)) - const registration: LocalRegistration = { fullname: hostname, meta: _meta, timer } + const registration: LocalRegistration = { fullname: hostname, meta, timer } this.#localServices.set(hostname, registration) return () => { diff --git a/packages/ipc/src/chunk.ts b/packages/ipc/src/chunk.ts index 3304aa1..dff5c84 100644 --- a/packages/ipc/src/chunk.ts +++ b/packages/ipc/src/chunk.ts @@ -83,6 +83,10 @@ export class Chunker { } this.#buffer.set(id, pending) } + else if (pending.compressed !== compressed) { + this.#buffer.delete(id) + return { done: false } + } if (pending.fragments[seq] !== undefined) { return { done: false } diff --git a/packages/ipc/src/ipc.ts b/packages/ipc/src/ipc.ts index 65b831a..d84174f 100644 --- a/packages/ipc/src/ipc.ts +++ b/packages/ipc/src/ipc.ts @@ -272,7 +272,7 @@ export class IPC { const seq = url.searchParams.get('seq') const total = url.searchParams.get('total') - const compressed = url.searchParams.get('c') !== null + const compressed = url.searchParams.get('c') === '1' if (seq !== null && total !== null) { this.#handleChunk(id, channel, Number(seq), Number(total), payload, compressed) diff --git a/packages/protocol/src/protocol.ts b/packages/protocol/src/protocol.ts index 7d45d23..c960adb 100644 --- a/packages/protocol/src/protocol.ts +++ b/packages/protocol/src/protocol.ts @@ -103,9 +103,14 @@ export class Protocol { } } - once(handler: (event: BedrockReceiveEvent) => void): () => void { + once(handler: (event: BedrockReceiveEvent) => void): () => void + once(handler: (event: BedrockReceiveEvent) => void, options: { sourceType?: ScriptEventSource }): () => void + once(handler: (event: BedrockReceiveEvent) => void, options?: { sourceType?: ScriptEventSource }): () => void { let off: () => void const wrapped = (event: BedrockReceiveEvent): void => { + if (options?.sourceType && event.sourceType !== options.sourceType) { + return + } off() handler(event) } diff --git a/packages/rpc/src/rpc.ts b/packages/rpc/src/rpc.ts index cc1ed53..e104958 100644 --- a/packages/rpc/src/rpc.ts +++ b/packages/rpc/src/rpc.ts @@ -146,11 +146,19 @@ export class RPC { try { const parsed = JSON.parse(body) - if (parsed && typeof parsed === 'object' && 'error' in parsed) { - pending.reject(new Error(parsed.error as string)) + if (parsed && typeof parsed === 'object') { + if ('error' in parsed) { + pending.reject(new Error(parsed.error as string)) + } + else if ('data' in parsed) { + pending.resolve(parsed.data) + } + else { + pending.reject(new Error('RPC: invalid response format — expected {data} or {error}')) + } } else { - pending.resolve(parsed && 'data' in parsed ? parsed.data : undefined) + pending.reject(new Error('RPC: invalid response body')) } } catch { diff --git a/packages/runtime/README.md b/packages/runtime/README.md index 36d73e2..e1dbdf6 100644 --- a/packages/runtime/README.md +++ b/packages/runtime/README.md @@ -24,7 +24,7 @@ npm install @mcbe-mods/runtime | `@mcbe-mods/log` | `Log` | `LogLevel`, `LogOptions` | | `@mcbe-mods/protocol` | `Protocol` | `BedrockReceiveEvent`, `ProtocolCipher`, `ProtocolOptions` | | `@mcbe-mods/rpc` | `RPC` | `RPCOptions` | -| `@mcbe-mods/utils` | `Base64`, `color`, `unique`, `ms2ticks`, … | (all types included) | +| `@mcbe-mods/utils` | `Base64`, `Color`, `unique`, `ms2ticks`, … | (all types included) | ```ts import { Base64, Cipher, Discover, IPC, Log, Protocol, RPC } from '@mcbe-mods/runtime' diff --git a/packages/utils/src/Experience.ts b/packages/utils/src/experience.ts similarity index 99% rename from packages/utils/src/Experience.ts rename to packages/utils/src/experience.ts index 07b9584..e43bd3f 100644 --- a/packages/utils/src/Experience.ts +++ b/packages/utils/src/experience.ts @@ -105,6 +105,7 @@ export class Experience { * @returns {this} self */ setLevel(level: number): this { + this.#xp = 0 this.#level = 0 this.addLevel(level) return this diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index f0db322..3fa0334 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,12 +1,12 @@ export { Base64 } from './base64' export { Color } from './color' export type { StyleId, Stylizer } from './color' -export { Experience } from './Experience' -export { getCubeRange, getSphereRange } from './getCubeRange' -export type { Location } from './getCubeRange' +export { Experience } from './experience' export { getRandomProbability } from './getRandomProbability' export { getRandomRangeValue } from './getRandomRangeValue' export { ms2ticks } from './ms2ticks' +export { getCubeRange, getSphereRange } from './range' +export type { Location } from './range' export { splitGroups } from './splitGroups' export { utf8Decode, utf8Encode } from './textCodec' export { unique } from './unique' diff --git a/packages/utils/src/getCubeRange.ts b/packages/utils/src/range.ts similarity index 71% rename from packages/utils/src/getCubeRange.ts rename to packages/utils/src/range.ts index 155007f..c684598 100644 --- a/packages/utils/src/getCubeRange.ts +++ b/packages/utils/src/range.ts @@ -4,12 +4,6 @@ export interface Location { z: number } -/** - * With {@link location} as the center, get all coordinates within a cube of side length `(2*radius+1)`. - * @param location - Center position - * @param radius - Half side length (default 1) - * @returns Array of positions within the cube - */ export function getCubeRange(location: Location, radius: number = 1): Location[] { const centerX = location.x const centerY = location.y @@ -27,12 +21,6 @@ export function getCubeRange(location: Location, radius: number = 1): Location[] return positions } -/** - * With {@link location} as the center, get all coordinates within a sphere of radius {@link radius}. - * @param location - Center position - * @param radius - Sphere radius (default 1) - * @returns Array of positions within the sphere - */ export function getSphereRange(location: Location, radius: number = 1): Location[] { const centerX = location.x const centerY = location.y