refactor: move brother_node development artifact to dev/test-nodes subdirectory
Development Artifact Cleanup: ✅ BROTHER_NODE REORGANIZATION: Moved development test node to appropriate location - dev/test-nodes/brother_node/: Moved from root directory for better organization - Contains development configuration, test logs, and test chain data - No impact on production systems - purely development/testing artifact ✅ DEVELOPMENT ARTIFACTS IDENTIFIED: - Chain ID: aitbc-brother-chain (test/development chain) - Ports: 8010 (P2P) and 8011 (RPC) - different from production - Environment: .env file with test configuration - Logs: rpc.log and node.log from development testing session (March 15, 2026) ✅ ROOT DIRECTORY CLEANUP: Removed development clutter from production directory - brother_node/ moved to dev/test-nodes/brother_node/ - Root directory now contains only production-ready components - Development artifacts properly organized in dev/ subdirectory DIRECTORY STRUCTURE IMPROVEMENT: 📁 dev/test-nodes/: Development and testing node configurations 🏗️ Root Directory: Clean production structure with only essential components 🧪 Development Isolation: Test environments separated from production BENEFITS: ✅ Clean Production Directory: No development artifacts in root ✅ Better Organization: Development nodes grouped in dev/ subdirectory ✅ Clear Separation: Production vs development environments clearly distinguished ✅ Maintainability: Easier to identify and manage development components RESULT: Successfully moved brother_node development artifact to dev/test-nodes/ subdirectory, cleaning up the root directory while preserving development testing environment for future use.
This commit is contained in:
400
dev/env/node_modules/@streamparser/json/dist/deno/tokenparser.ts
generated
vendored
Executable file
400
dev/env/node_modules/@streamparser/json/dist/deno/tokenparser.ts
generated
vendored
Executable file
@@ -0,0 +1,400 @@
|
||||
import { charset } from "./utils/utf-8.ts";
|
||||
import TokenType from "./utils/types/tokenType.ts";
|
||||
import type {
|
||||
JsonPrimitive,
|
||||
JsonKey,
|
||||
JsonObject,
|
||||
JsonArray,
|
||||
JsonStruct,
|
||||
} from "./utils/types/jsonTypes.ts";
|
||||
import {
|
||||
type StackElement,
|
||||
TokenParserMode,
|
||||
} from "./utils/types/stackElement.ts";
|
||||
import type { ParsedTokenInfo } from "./utils/types/parsedTokenInfo.ts";
|
||||
import type { ParsedElementInfo } from "./utils/types/parsedElementInfo.ts";
|
||||
|
||||
// Parser States
|
||||
const enum TokenParserState {
|
||||
VALUE,
|
||||
KEY,
|
||||
COLON,
|
||||
COMMA,
|
||||
ENDED,
|
||||
ERROR,
|
||||
SEPARATOR,
|
||||
}
|
||||
|
||||
function TokenParserStateToString(state: TokenParserState): string {
|
||||
return ["VALUE", "KEY", "COLON", "COMMA", "ENDED", "ERROR", "SEPARATOR"][
|
||||
state
|
||||
];
|
||||
}
|
||||
|
||||
export interface TokenParserOptions {
|
||||
paths?: string[];
|
||||
keepStack?: boolean;
|
||||
separator?: string;
|
||||
emitPartialValues?: boolean;
|
||||
}
|
||||
|
||||
const defaultOpts: TokenParserOptions = {
|
||||
paths: undefined,
|
||||
keepStack: true,
|
||||
separator: undefined,
|
||||
emitPartialValues: false,
|
||||
};
|
||||
|
||||
export class TokenParserError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
// Typescript is broken. This is a workaround
|
||||
Object.setPrototypeOf(this, TokenParserError.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export default class TokenParser {
|
||||
private readonly paths?: (string[] | undefined)[];
|
||||
private readonly keepStack: boolean;
|
||||
private readonly separator?: string;
|
||||
private state: TokenParserState = TokenParserState.VALUE;
|
||||
private mode: TokenParserMode | undefined = undefined;
|
||||
private key: JsonKey = undefined;
|
||||
private value: JsonStruct | undefined = undefined;
|
||||
private stack: StackElement[] = [];
|
||||
|
||||
constructor(opts?: TokenParserOptions) {
|
||||
opts = { ...defaultOpts, ...opts };
|
||||
|
||||
if (opts.paths) {
|
||||
this.paths = opts.paths.map((path) => {
|
||||
if (path === undefined || path === "$*") return undefined;
|
||||
|
||||
if (!path.startsWith("$"))
|
||||
throw new TokenParserError(
|
||||
`Invalid selector "${path}". Should start with "$".`,
|
||||
);
|
||||
const pathParts = path.split(".").slice(1);
|
||||
if (pathParts.includes(""))
|
||||
throw new TokenParserError(
|
||||
`Invalid selector "${path}". ".." syntax not supported.`,
|
||||
);
|
||||
return pathParts;
|
||||
});
|
||||
}
|
||||
|
||||
this.keepStack = opts.keepStack || false;
|
||||
this.separator = opts.separator;
|
||||
if (!opts.emitPartialValues) {
|
||||
this.emitPartial = () => {};
|
||||
}
|
||||
}
|
||||
|
||||
private shouldEmit(): boolean {
|
||||
if (!this.paths) return true;
|
||||
|
||||
return this.paths.some((path) => {
|
||||
if (path === undefined) return true;
|
||||
if (path.length !== this.stack.length) return false;
|
||||
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
const selector = path[i];
|
||||
const key = this.stack[i + 1].key;
|
||||
if (selector === "*") continue;
|
||||
if (selector !== key?.toString()) return false;
|
||||
}
|
||||
|
||||
const selector = path[path.length - 1];
|
||||
if (selector === "*") return true;
|
||||
return selector === this.key?.toString();
|
||||
});
|
||||
}
|
||||
|
||||
private push(): void {
|
||||
this.stack.push({
|
||||
key: this.key,
|
||||
value: this.value as JsonStruct,
|
||||
mode: this.mode,
|
||||
emit: this.shouldEmit(),
|
||||
});
|
||||
}
|
||||
|
||||
private pop(): void {
|
||||
const value = this.value;
|
||||
|
||||
let emit;
|
||||
({
|
||||
key: this.key,
|
||||
value: this.value,
|
||||
mode: this.mode,
|
||||
emit,
|
||||
} = this.stack.pop() as StackElement);
|
||||
|
||||
this.state =
|
||||
this.mode !== undefined ? TokenParserState.COMMA : TokenParserState.VALUE;
|
||||
|
||||
this.emit(value as JsonPrimitive | JsonStruct, emit);
|
||||
}
|
||||
|
||||
private emit(value: JsonPrimitive | JsonStruct, emit: boolean): void {
|
||||
if (
|
||||
!this.keepStack &&
|
||||
this.value &&
|
||||
this.stack.every((item) => !item.emit)
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
delete (this.value as JsonStruct as any)[this.key as string | number];
|
||||
}
|
||||
|
||||
if (emit) {
|
||||
this.onValue({
|
||||
value: value,
|
||||
key: this.key,
|
||||
parent: this.value,
|
||||
stack: this.stack,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.stack.length === 0) {
|
||||
if (this.separator) {
|
||||
this.state = TokenParserState.SEPARATOR;
|
||||
} else if (this.separator === undefined) {
|
||||
this.end();
|
||||
}
|
||||
// else if separator === '', expect next JSON object.
|
||||
}
|
||||
}
|
||||
|
||||
private emitPartial(value?: JsonPrimitive): void {
|
||||
if (!this.shouldEmit()) return;
|
||||
|
||||
if (this.state === TokenParserState.KEY) {
|
||||
this.onValue({
|
||||
value: undefined,
|
||||
key: value as JsonKey,
|
||||
parent: this.value,
|
||||
stack: this.stack,
|
||||
partial: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.onValue({
|
||||
value: value,
|
||||
key: this.key,
|
||||
parent: this.value,
|
||||
stack: this.stack,
|
||||
partial: true,
|
||||
});
|
||||
}
|
||||
|
||||
public get isEnded(): boolean {
|
||||
return this.state === TokenParserState.ENDED;
|
||||
}
|
||||
|
||||
public write({
|
||||
token,
|
||||
value,
|
||||
partial,
|
||||
}: Omit<ParsedTokenInfo, "offset">): void {
|
||||
try {
|
||||
if (partial) {
|
||||
this.emitPartial(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.state === TokenParserState.VALUE) {
|
||||
if (
|
||||
token === TokenType.STRING ||
|
||||
token === TokenType.NUMBER ||
|
||||
token === TokenType.TRUE ||
|
||||
token === TokenType.FALSE ||
|
||||
token === TokenType.NULL
|
||||
) {
|
||||
if (this.mode === TokenParserMode.OBJECT) {
|
||||
(this.value as JsonObject)[this.key as string] = value;
|
||||
this.state = TokenParserState.COMMA;
|
||||
} else if (this.mode === TokenParserMode.ARRAY) {
|
||||
(this.value as JsonArray).push(value);
|
||||
this.state = TokenParserState.COMMA;
|
||||
}
|
||||
|
||||
this.emit(value, this.shouldEmit());
|
||||
return;
|
||||
}
|
||||
|
||||
if (token === TokenType.LEFT_BRACE) {
|
||||
this.push();
|
||||
if (this.mode === TokenParserMode.OBJECT) {
|
||||
this.value = (this.value as JsonObject)[this.key as string] = {};
|
||||
} else if (this.mode === TokenParserMode.ARRAY) {
|
||||
const val = {};
|
||||
(this.value as JsonArray).push(val);
|
||||
this.value = val;
|
||||
} else {
|
||||
this.value = {};
|
||||
}
|
||||
this.mode = TokenParserMode.OBJECT;
|
||||
this.state = TokenParserState.KEY;
|
||||
this.key = undefined;
|
||||
this.emitPartial();
|
||||
return;
|
||||
}
|
||||
|
||||
if (token === TokenType.LEFT_BRACKET) {
|
||||
this.push();
|
||||
if (this.mode === TokenParserMode.OBJECT) {
|
||||
this.value = (this.value as JsonObject)[this.key as string] = [];
|
||||
} else if (this.mode === TokenParserMode.ARRAY) {
|
||||
const val: JsonArray = [];
|
||||
(this.value as JsonArray).push(val);
|
||||
this.value = val;
|
||||
} else {
|
||||
this.value = [];
|
||||
}
|
||||
this.mode = TokenParserMode.ARRAY;
|
||||
this.state = TokenParserState.VALUE;
|
||||
this.key = 0;
|
||||
this.emitPartial();
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this.mode === TokenParserMode.ARRAY &&
|
||||
token === TokenType.RIGHT_BRACKET &&
|
||||
(this.value as JsonArray).length === 0
|
||||
) {
|
||||
this.pop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state === TokenParserState.KEY) {
|
||||
if (token === TokenType.STRING) {
|
||||
this.key = value as string;
|
||||
this.state = TokenParserState.COLON;
|
||||
this.emitPartial();
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
token === TokenType.RIGHT_BRACE &&
|
||||
Object.keys(this.value as JsonObject).length === 0
|
||||
) {
|
||||
this.pop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state === TokenParserState.COLON) {
|
||||
if (token === TokenType.COLON) {
|
||||
this.state = TokenParserState.VALUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state === TokenParserState.COMMA) {
|
||||
if (token === TokenType.COMMA) {
|
||||
if (this.mode === TokenParserMode.ARRAY) {
|
||||
this.state = TokenParserState.VALUE;
|
||||
(this.key as number) += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (this.mode === TokenParserMode.OBJECT) {
|
||||
this.state = TokenParserState.KEY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
(token === TokenType.RIGHT_BRACE &&
|
||||
this.mode === TokenParserMode.OBJECT) ||
|
||||
(token === TokenType.RIGHT_BRACKET &&
|
||||
this.mode === TokenParserMode.ARRAY)
|
||||
) {
|
||||
this.pop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state === TokenParserState.SEPARATOR) {
|
||||
if (token === TokenType.SEPARATOR && value === this.separator) {
|
||||
this.state = TokenParserState.VALUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Edge case in which the separator is just whitespace and it's found in the middle of the JSON
|
||||
if (
|
||||
token === TokenType.SEPARATOR &&
|
||||
this.state !== TokenParserState.SEPARATOR &&
|
||||
Array.from(value as string)
|
||||
.map((n) => n.charCodeAt(0))
|
||||
.every(
|
||||
(n) =>
|
||||
n === charset.SPACE ||
|
||||
n === charset.NEWLINE ||
|
||||
n === charset.CARRIAGE_RETURN ||
|
||||
n === charset.TAB,
|
||||
)
|
||||
) {
|
||||
// whitespace
|
||||
return;
|
||||
}
|
||||
|
||||
throw new TokenParserError(
|
||||
`Unexpected ${TokenType[token]} (${JSON.stringify(
|
||||
value,
|
||||
)}) in state ${TokenParserStateToString(this.state)}`,
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
this.error(err as Error);
|
||||
}
|
||||
}
|
||||
|
||||
public error(err: Error): void {
|
||||
if (this.state !== TokenParserState.ENDED) {
|
||||
this.state = TokenParserState.ERROR;
|
||||
}
|
||||
|
||||
this.onError(err);
|
||||
}
|
||||
|
||||
public end(): void {
|
||||
if (
|
||||
(this.state !== TokenParserState.VALUE &&
|
||||
this.state !== TokenParserState.SEPARATOR) ||
|
||||
this.stack.length > 0
|
||||
) {
|
||||
this.error(
|
||||
new Error(
|
||||
`Parser ended in mid-parsing (state: ${TokenParserStateToString(
|
||||
this.state,
|
||||
)}). Either not all the data was received or the data was invalid.`,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
this.state = TokenParserState.ENDED;
|
||||
this.onEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
||||
public onValue(parsedElementInfo: ParsedElementInfo): void {
|
||||
// Override me
|
||||
throw new TokenParserError(
|
||||
'Can\'t emit data before the "onValue" callback has been set up.',
|
||||
);
|
||||
}
|
||||
|
||||
public onError(err: Error): void {
|
||||
// Override me
|
||||
throw err;
|
||||
}
|
||||
|
||||
public onEnd(): void {
|
||||
// Override me
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user