Archived
1
0
Fork 0

refac: remove async

This commit is contained in:
Dmitriy Pleshevskiy 2022-03-18 22:00:44 +03:00
parent f577128923
commit cc9a67d055
7 changed files with 48 additions and 51 deletions

47
lib/nodes.d.ts vendored
View file

@ -1,29 +1,32 @@
import { Nil, Nilable } from "./lang.js"; import { Nil, Nilable } from "./lang.js";
export declare type AnyNode = AnySyncNode | AnyAsyncNode; export declare type AnyNode = TextNode | Elem | Frag | Nil | false;
export declare type AnyAsyncNode = Promise<AnySyncNode>;
export declare type AnySyncNode = TextNode | Elem | Frag | Nil | false; export declare class TextNode extends String {}
export declare class TextNode extends String {
}
export declare function F(...children: AnyNode[]): Frag; export declare function F(...children: AnyNode[]): Frag;
export declare class Frag { export declare class Frag {
#private; #private;
constructor(); constructor();
get children(): Nilable<AnyNode[]>; get children(): Nilable<AnyNode[]>;
withText(text: string): this; withText(text: string): this;
addText(text: string): void; addText(text: string): void;
withChildren(nodes: AnyNode[]): this; withChildren(nodes: AnyNode[]): this;
withChild(node: AnyNode): this; withChild(node: AnyNode): this;
addChild(node: AnyNode): void; addChild(node: AnyNode): void;
} }
export declare function E(tagName: string, attrs: ElemAttrs, ...children: AnyNode[]): Elem; export declare function E(
tagName: string,
attrs: ElemAttrs,
...children: AnyNode[]
): Elem;
export declare type ElemAttrs = Record<string, unknown>; export declare type ElemAttrs = Record<string, unknown>;
export declare class Elem extends Frag { export declare class Elem extends Frag {
#private; #private;
constructor(tagName: string); constructor(tagName: string);
get tagName(): string; get tagName(): string;
get attrs(): Record<string, unknown>; get attrs(): Record<string, unknown>;
withAttrs(attrs: Record<string, unknown>): Elem; withAttrs(attrs: Record<string, unknown>): Elem;
withAttr(name: string, value: unknown): Elem; withAttr(name: string, value: unknown): Elem;
addAttr(name: string, value: unknown): void; addAttr(name: string, value: unknown): void;
addChild(node: AnySyncNode): void; addChild(node: AnyNode): void;
} }

2
lib/str.d.ts vendored
View file

@ -1,5 +1,5 @@
import { Renderer } from "./types.js"; import { Renderer } from "./types.js";
import { Elem } from "./nodes.js"; import { Elem } from "./nodes.js";
export declare class StrRenderer implements Renderer<string> { export declare class StrRenderer implements Renderer<string> {
render(node: Elem | Promise<Elem>): Promise<string>; render(node: Elem): string;
} }

View file

@ -1,25 +1,24 @@
import { isBool, isNil } from "./lang.mjs"; import { isBool, isNil } from "./lang.mjs";
import { Elem, TextNode } from "./nodes.mjs"; import { Elem, TextNode } from "./nodes.mjs";
export class StrRenderer { export class StrRenderer {
async render(node) { render(node) {
return encodeNode(await node); return encodeNode(node);
} }
} }
async function encodeAnyNode(node) { function encodeAnyNode(node) {
const syncNode = await node; return !node
return !syncNode
? null ? null
: syncNode instanceof TextNode : node instanceof TextNode
? encodeTextNode(syncNode) ? encodeTextNode(node)
: encodeNode(syncNode); : encodeNode(node);
} }
function encodeTextNode(node) { function encodeTextNode(node) {
return String(node); return String(node);
} }
async function encodeNode(node) { function encodeNode(node) {
const encodedChildren = isNil(node.children) const encodedChildren = isNil(node.children)
? undefined ? undefined
: await Promise.all(node.children.map(encodeAnyNode)).then((children) => children.filter((c) => Boolean(c))); : node.children.map(encodeAnyNode).filter((c) => Boolean(c));
return node instanceof Elem return node instanceof Elem
? encodeHtmlElement(node.tagName, node.attrs, encodedChildren) ? encodeHtmlElement(node.tagName, node.attrs, encodedChildren)
: encodeHtmlFragment(encodedChildren); : encodeHtmlFragment(encodedChildren);

2
lib/types.d.ts vendored
View file

@ -1,4 +1,4 @@
import { Elem } from "./nodes.js"; import { Elem } from "./nodes.js";
export interface Renderer<T> { export interface Renderer<T> {
render(node: Elem | Promise<Elem>): Promise<T>; render(node: Elem): T;
} }

View file

@ -1,8 +1,6 @@
import { isNil, Nil, Nilable } from "./lang.mjs"; import { isNil, Nil, Nilable } from "./lang.mjs";
export type AnyNode = AnySyncNode | AnyAsyncNode; export type AnyNode = TextNode | Elem | Frag | Nil | false;
export type AnyAsyncNode = Promise<AnySyncNode>;
export type AnySyncNode = TextNode | Elem | Frag | Nil | false;
export class TextNode extends String {} export class TextNode extends String {}
@ -90,7 +88,7 @@ export class Elem extends Frag {
this.#attrs[name] = value; this.#attrs[name] = value;
} }
addChild(node: AnySyncNode): void { addChild(node: AnyNode): void {
if (this.#isSelfClosed) if (this.#isSelfClosed)
throw new Error("You cannot add child to self closed element"); throw new Error("You cannot add child to self closed element");
super.addChild(node); super.addChild(node);

View file

@ -3,30 +3,27 @@ import { isBool, isNil, Nullable } from "./lang.mjs";
import { AnyNode, Elem, Frag, TextNode } from "./nodes.mjs"; import { AnyNode, Elem, Frag, TextNode } from "./nodes.mjs";
export class StrRenderer implements Renderer<string> { export class StrRenderer implements Renderer<string> {
async render(node: Elem | Promise<Elem>): Promise<string> { render(node: Elem): string {
return encodeNode(await node); return encodeNode(node);
} }
} }
async function encodeAnyNode(node: AnyNode): Promise<Nullable<string>> { function encodeAnyNode(node: AnyNode): Nullable<string> {
const syncNode = await node; return !node
return !syncNode
? null ? null
: syncNode instanceof TextNode : node instanceof TextNode
? encodeTextNode(syncNode) ? encodeTextNode(node)
: encodeNode(syncNode); : encodeNode(node);
} }
function encodeTextNode(node: TextNode): string { function encodeTextNode(node: TextNode): string {
return String(node); return String(node);
} }
async function encodeNode(node: Elem | Frag): Promise<string> { function encodeNode(node: Elem | Frag): string {
const encodedChildren = isNil(node.children) const encodedChildren = isNil(node.children)
? undefined ? undefined
: await Promise.all(node.children.map(encodeAnyNode)).then((children) => : node.children.map(encodeAnyNode).filter((c): c is string => Boolean(c));
children.filter((c): c is string => Boolean(c))
);
return node instanceof Elem return node instanceof Elem
? encodeHtmlElement(node.tagName, node.attrs, encodedChildren) ? encodeHtmlElement(node.tagName, node.attrs, encodedChildren)
: encodeHtmlFragment(encodedChildren); : encodeHtmlFragment(encodedChildren);

View file

@ -1,5 +1,5 @@
import { Elem } from "./nodes.mjs"; import { Elem } from "./nodes.mjs";
export interface Renderer<T> { export interface Renderer<T> {
render(node: Elem | Promise<Elem>): Promise<T>; render(node: Elem): T;
} }