From 845d503bb16cb5046a4fec6d046b7b527a080187 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Fri, 11 Aug 2023 21:40:54 +0530 Subject: chore: adds prettier --- src/eval.ts | 22 ++++-- src/index.ts | 43 +++++----- src/parser.ts | 11 +-- src/utils/adt.ts | 17 ++-- src/utils/parser-comb.ts | 199 ++++++++++++++++++++++++++++------------------- src/utils/result.ts | 18 +++-- 6 files changed, 184 insertions(+), 126 deletions(-) (limited to 'src') diff --git a/src/eval.ts b/src/eval.ts index 191a76b..5e99282 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -12,7 +12,11 @@ export type EvalActions = { setAttribute(name: string, value: string): Promise withEvent(fn: (e: any) => void): Promise getFormData(): Promise - sendRequest(_: { method: string, url: string, data: FormData | undefined }): Promise + sendRequest(_: { + method: string + url: string + data: FormData | undefined + }): Promise // calculate ?? } @@ -20,19 +24,19 @@ type EvalValue = string | undefined | void export const evalExpr = async ( expr: Expr, - actions: EvalActions + actions: EvalActions, ): Promise => match, Expr>(expr, { Call: async ({ name, args }) => getFunctions(name, args, actions), - LiteralString: async (s) => s, + LiteralString: async s => s, LiteralNumber: async ({ value, unit }) => matchString(unit, { s: () => value * 1000, _: () => value, }).toString(), - Identifier: async (s) => s, - VarIdentifier: async (s) => s, - _: async (_) => undefined, + Identifier: async s => s, + VarIdentifier: async s => s, + _: async _ => undefined, }) const getFunctions = (name: string, args: Expr[], actions: EvalActions) => @@ -93,9 +97,11 @@ const getFunctions = (name: string, args: Expr[], actions: EvalActions) => }, 'prevent-default': async () => actions.withEvent(e => e.preventDefault()), - 'request': async () => { + request: async () => { const url = await evalExpr(args[0], actions) - const method = args[1] ? (await evalExpr(args[1], actions) ?? 'post') : 'post' + const method = args[1] + ? (await evalExpr(args[1], actions)) ?? 'post' + : 'post' if (url) { const data = await actions.getFormData() diff --git a/src/index.ts b/src/index.ts index b48b1d8..2d70c3f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ const EVENT_HANDLERS = { const PROPERTIES = [ '--cssx-children', '--cssx-text', - '--cssx-disgustingly-set-innerhtml' + '--cssx-disgustingly-set-innerhtml', ] const injectStyles = () => { @@ -25,7 +25,7 @@ const injectStyles = () => { const properties = [...PROPERTIES, ...Object.values(EVENT_HANDLERS)] $style.textContent = `.cssx-layer { - ${properties.map((p) => `${p}: ${UNSET_PROPERTY_VALUE};`).join(' ')} + ${properties.map(p => `${p}: ${UNSET_PROPERTY_VALUE};`).join(' ')} }` document.body.appendChild($style) @@ -45,8 +45,8 @@ const getEvalActions = ($element: Element, event: any): EvalActions => ({ addClass: async (id, cls) => document.getElementById(id)?.classList.add(cls), removeClass: async (id, cls) => document.getElementById(id)?.classList.remove(cls), - delay: (delay) => new Promise((res) => setTimeout(res, delay)), - jsEval: async (js) => (0, eval)(js), + delay: delay => new Promise(res => setTimeout(res, delay)), + jsEval: async js => (0, eval)(js), loadCssx: async (id, url) => new Promise((resolve, reject) => { const $link = Object.assign(document.createElement('link'), { @@ -66,7 +66,7 @@ const getEvalActions = ($element: Element, event: any): EvalActions => ({ } document.body.appendChild($link) }), - getVariable: async (varName) => getPropertyValue($element, varName), + getVariable: async varName => getPropertyValue($element, varName), updateVariable: async (targetId, varName, value) => { const $el = document.getElementById(targetId) if ($el) { @@ -76,15 +76,21 @@ const getEvalActions = ($element: Element, event: any): EvalActions => ({ setAttribute: async (name, value) => { $element.setAttribute(name, value) }, - withEvent: async (fn) => fn(event), - getFormData: async () => $element.nodeName === 'FORM' ? new FormData($element as HTMLFormElement) : undefined, + withEvent: async fn => fn(event), + getFormData: async () => + $element.nodeName === 'FORM' + ? new FormData($element as HTMLFormElement) + : undefined, sendRequest: async ({ url, method, data }) => { await fetch(url, { method, body: data }) // TODO: Handle response? }, }) -const handleEvents = async ($element: Element, isNewElement: boolean = false) => { +const handleEvents = async ( + $element: Element, + isNewElement: boolean = false, +) => { for (const [eventType, property] of Object.entries(EVENT_HANDLERS)) { const handlerExpr = getPropertyValue($element, property) @@ -106,17 +112,17 @@ const handleEvents = async ($element: Element, isNewElement: boolean = false) => } } -let nodeCount = 0 -const manageElement = async ($element: Element, isNewElement: boolean = false) => { - if (nodeCount++ > 100) return // NOTE: Temporary. To prevent infinite rec - +const manageElement = async ( + $element: Element, + isNewElement: boolean = false, +) => { await handleEvents($element, isNewElement) const text = getPropertyValue($element, '--cssx-text') if (text) $element.textContent = text const html = getPropertyValue($element, '--cssx-disgustingly-set-innerhtml') - if (html) $element.innerHTML = html + if (html) $element.innerHTML = html.replace(/(^'|")|('|"$)/g, '') const childrenIds = getChildrenIds($element) if (childrenIds.length > 0) { @@ -127,12 +133,13 @@ const manageElement = async ($element: Element, isNewElement: boolean = false) = $element.appendChild($childrenRoot) for (const childId of childrenIds) { - let isNewElement = false; const selector = childId.split('#') const [tag, id] = selector.length >= 2 ? selector : ['div', ...selector] - const $child = - $childrenRoot.querySelector(`:scope > #${id}`) ?? - (isNewElement = true, Object.assign(document.createElement(tag || 'div'), { id })) + let $child = $childrenRoot.querySelector(`:scope > #${id}`) + const isNewElement = !$child + if (!$child) { + $child = Object.assign(document.createElement(tag || 'div'), { id }) + } $childrenRoot.appendChild($child) await manageElement($child, isNewElement) } @@ -147,4 +154,4 @@ const render = async ({ root = document.body }: Options = {}) => { await manageElement(root) } -render() +render() \ No newline at end of file diff --git a/src/parser.ts b/src/parser.ts index 9cb0405..3279f57 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -8,7 +8,7 @@ export type Expr = Enum<{ Identifier: string VarIdentifier: string LiteralString: string - LiteralNumber: { value: number, unit: CSSUnit } + LiteralNumber: { value: number; unit: CSSUnit } }> export const Expr = constructors() @@ -31,9 +31,9 @@ const callExprParser = (input: string) => P.map( P.zip2( consumeWhitespace(identifierParser), - parens(consumeWhitespace(P.sepBy(exprParser, comma))) + parens(consumeWhitespace(P.sepBy(exprParser, comma))), ), - ([name, args]) => Expr.Call({ name, args }) + ([name, args]) => Expr.Call({ name, args }), )(input) const stringLiteralParser: P.Parser = P.map( @@ -41,14 +41,15 @@ const stringLiteralParser: P.Parser = P.map( P.between(singleQuote, P.regex(/^[^']*/), singleQuote), P.between(doubleQuote, P.regex(/^[^"]*/), doubleQuote), ]), - Expr.LiteralString + Expr.LiteralString, ) const numberParser = P.regex(/^[-+]?((\d*\.\d+)|\d+)/) const numberExprParser: P.Parser = P.map( P.zip2(numberParser, P.optional(P.regex(/^(s|ms)/i))), - ([value, unit]) => Expr.LiteralNumber({ value: Number(value), unit: (unit ?? '') as CSSUnit }), + ([value, unit]) => + Expr.LiteralNumber({ value: Number(value), unit: (unit ?? '') as CSSUnit }), ) const exprParser: P.Parser = P.or([ diff --git a/src/utils/adt.ts b/src/utils/adt.ts index 78ab667..45d9e50 100644 --- a/src/utils/adt.ts +++ b/src/utils/adt.ts @@ -1,14 +1,18 @@ type TagValue = T extends Tag ? V : never -export const match = - >(tag: T, pattern: { +export const match = >( + tag: T, + pattern: { [key in T['tag'] | '_']?: (v: TagValue) => R - }): R => ((pattern as any)[tag.tag] || (pattern._ as any))(tag.value) + }, +): R => ((pattern as any)[tag.tag] || (pattern._ as any))(tag.value) -export const matchString = - (key: T, pattern: { +export const matchString = ( + key: T, + pattern: { [key in T | '_']?: (key: key) => R - }): R => ((pattern as any)[key] || (pattern._ as any))(key) + }, +): R => ((pattern as any)[key] || (pattern._ as any))(key) type Tag = { tag: N; value: V } export type Enum = { [N in keyof T]: Tag }[keyof T] @@ -26,4 +30,3 @@ export const constructors = >(): { }, }, ) as any - diff --git a/src/utils/parser-comb.ts b/src/utils/parser-comb.ts index f682068..3f171b8 100644 --- a/src/utils/parser-comb.ts +++ b/src/utils/parser-comb.ts @@ -1,83 +1,120 @@ -import { match } from './adt'; -import { Result, mapResult, chainResult } from './result'; - -export type ParseResult = Result<{ value: T, input: string }, { error: string, input: string }>; - -export type Parser = (input: string) => ParseResult; - -export const regex = (re: RegExp): Parser => input => { - if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) - const res = input.match(re) - if (!res) return Result.Err({ error: 'fucked', input }); - return Result.Ok({ value: res[0], input: input.replace(re, '') }); -} - -export const string = (str: string): Parser => input => { - if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) - if (!input.startsWith(str)) return Result.Err({ error: 'fuckedstring', input }) - return Result.Ok({ value: str, input: input.slice(str.length) }); -} - -export const or = ([parser, ...rest]: Array>): Parser => input => { - if (rest.length === 0) return parser(input); - const result = parser(input) - return match(result, { - Ok: () => result, - Err: (_) => or(rest)(input), - }); -} - -export const mapParseResult = (parser: Parser, fn: (_: { value: T, input: string }) => { value: R, input: string }): Parser => input => - mapResult(parser(input), fn) +import { match } from './adt' +import { Result, mapResult, chainResult } from './result' + +export type ParseResult = Result< + { value: T; input: string }, + { error: string; input: string } +> + +export type Parser = (input: string) => ParseResult + +export const regex = + (re: RegExp): Parser => + input => { + if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) + const res = input.match(re) + if (!res) return Result.Err({ error: 'fucked', input }) + return Result.Ok({ value: res[0], input: input.replace(re, '') }) + } + +export const string = + (str: string): Parser => + input => { + if (input.length === 0) return Result.Err({ error: 'fuckedinput', input }) + if (!input.startsWith(str)) + return Result.Err({ error: 'fuckedstring', input }) + return Result.Ok({ value: str, input: input.slice(str.length) }) + } + +export const or = + ([parser, ...rest]: Array>): Parser => + input => { + if (rest.length === 0) return parser(input) + const result = parser(input) + return match(result, { + Ok: () => result, + Err: _ => or(rest)(input), + }) + } + +export const mapParseResult = + ( + parser: Parser, + fn: (_: { value: T; input: string }) => { value: R; input: string }, + ): Parser => + input => + mapResult(parser(input), fn) export const map = (parser: Parser, fn: (_: T) => R): Parser => - mapParseResult(parser, ({ value, ...rest }) => ({ ...rest, value: fn(value) })); - -export const zip2 = (parserA: Parser, parserB: Parser): Parser => input => { - // TODO: refactor please. shit code - const resa: Result<{ value: A, input: string }, { error: string, input: string }> = parserA(input); - return chainResult(resa, ({ value: a, input: inputB }) => { - const res: Result<{ value: readonly [A, B], input: string }, { error: string, input: string }> = - map(parserB, (b) => [a, b] as const)(inputB) - return res - }) -} - -export const prefixed = (parserPrefix: Parser, parser: Parser): Parser => - map(zip2(parserPrefix, parser), ([_, a]) => a); - -export const suffixed = (parser: Parser, parserSuffix: Parser): Parser => - map(zip2(parser, parserSuffix), ([a, _]) => a); - -export const between = (prefix: Parser, parser: Parser, suffix: Parser): Parser => - suffixed(prefixed(prefix, parser), suffix) - -export const many0 = (parser: Parser): Parser> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), - Err: ({ input }) => Result.Ok({ value: [], input }), - }) - -export const many1 = (parser: Parser): Parser> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), - Err: err => Result.Err(err), - }) - -export const sepBy = (parser: Parser, sepP: Parser): Parser> => originalInput => - match(parser(originalInput), { - Ok: ({ value, input }) => map( - many0(prefixed(sepP, parser)), - ls => [value, ...ls] - )(input), - Err: _ => Result.Ok({ value: [], input: originalInput }), - }) - -export const optional = (parser: Parser): Parser => input => { - const result = parser(input) - return match(result, { - Ok: _ => result, - Err: _ => Result.Ok({ value: undefined, input }) - }) -} - + mapParseResult(parser, ({ value, ...rest }) => ({ + ...rest, + value: fn(value), + })) + +export const zip2 = + (parserA: Parser, parserB: Parser): Parser => + input => { + // TODO: refactor please. shit code + const resa: Result< + { value: A; input: string }, + { error: string; input: string } + > = parserA(input) + return chainResult(resa, ({ value: a, input: inputB }) => { + const res: Result< + { value: readonly [A, B]; input: string }, + { error: string; input: string } + > = map(parserB, b => [a, b] as const)(inputB) + return res + }) + } + +export const prefixed = ( + parserPrefix: Parser, + parser: Parser, +): Parser => map(zip2(parserPrefix, parser), ([_, a]) => a) + +export const suffixed = ( + parser: Parser, + parserSuffix: Parser, +): Parser => map(zip2(parser, parserSuffix), ([a, _]) => a) + +export const between = ( + prefix: Parser, + parser: Parser, + suffix: Parser, +): Parser => suffixed(prefixed(prefix, parser), suffix) + +export const many0 = + (parser: Parser): Parser> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), + Err: ({ input }) => Result.Ok({ value: [], input }), + }) + +export const many1 = + (parser: Parser): Parser> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input), + Err: err => Result.Err(err), + }) + +export const sepBy = + (parser: Parser, sepP: Parser): Parser> => + originalInput => + match(parser(originalInput), { + Ok: ({ value, input }) => + map(many0(prefixed(sepP, parser)), ls => [value, ...ls])(input), + Err: _ => Result.Ok({ value: [], input: originalInput }), + }) + +export const optional = + (parser: Parser): Parser => + input => { + const result = parser(input) + return match(result, { + Ok: _ => result, + Err: _ => Result.Ok({ value: undefined, input }), + }) + } diff --git a/src/utils/result.ts b/src/utils/result.ts index c0120b8..39a7fe6 100644 --- a/src/utils/result.ts +++ b/src/utils/result.ts @@ -1,14 +1,18 @@ -import { Enum, constructors, match } from "./adt"; +import { Enum, constructors, match } from './adt' -export type Result = Enum<{ Ok: V, Err: E }> +export type Result = Enum<{ Ok: V; Err: E }> export const Result = constructors>() -export const mapResult = (res: Result, fn: (_: A) => B): Result => - chainResult(res, a => Result.Ok(fn(a))) +export const mapResult = ( + res: Result, + fn: (_: A) => B, +): Result => chainResult(res, a => Result.Ok(fn(a))) -export const chainResult = (res: Result, fn: (_: A) => Result): Result => +export const chainResult = ( + res: Result, + fn: (_: A) => Result, +): Result => match(res, { Ok: a => fn(a), Err: e => Result.Err(e), - }); - + }) -- cgit v1.3.1