summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2023-08-11 21:40:54 +0530
committerAkshay Nair <phenax5@gmail.com>2023-08-11 21:50:20 +0530
commit845d503bb16cb5046a4fec6d046b7b527a080187 (patch)
treea9f8fdf4510ad4d61e8d105065be9071946e2bdf
parent5a9942fde65787b35d4eb8e3441af6fe68819612 (diff)
downloadcss-everything-845d503bb16cb5046a4fec6d046b7b527a080187.tar.gz
css-everything-845d503bb16cb5046a4fec6d046b7b527a080187.zip
chore: adds prettier
-rw-r--r--.editorconfig7
-rw-r--r--.prettierrc5
-rw-r--r--TODO.norg4
-rw-r--r--examples/counter/index.html6
-rw-r--r--examples/counter/style.css6
-rw-r--r--examples/form/index.html6
-rw-r--r--examples/form/signup.css42
-rw-r--r--examples/form/style.css24
-rw-r--r--examples/todo-list/style.css9
-rw-r--r--package.json4
-rw-r--r--src/eval.ts22
-rw-r--r--src/index.ts43
-rw-r--r--src/parser.ts11
-rw-r--r--src/utils/adt.ts17
-rw-r--r--src/utils/parser-comb.ts171
-rw-r--r--src/utils/result.ts18
-rw-r--r--tests/eval.spec.ts44
-rw-r--r--tests/parser.spec.ts2
-rw-r--r--yarn.lock5
19 files changed, 264 insertions, 182 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..346ac31
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,7 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true \ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..e6e4310
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,5 @@
+semi: false
+singleQuote: true
+bracketSpacing: true
+arrowParens: avoid
+printWidth: 80 \ No newline at end of file
diff --git a/TODO.norg b/TODO.norg
index 90a13d5..c4c1756 100644
--- a/TODO.norg
+++ b/TODO.norg
@@ -7,6 +7,8 @@
- (x) Specify node type - `button(id)` or `button#id`
- (x) attributes
- (x) `--cssx-text` (and maybe `--cssx-html`?)
+ - ( ) Evaluate `calc`
+ - ( ) Additional events
+ - ( ) Proper dom tests
- ( ) Improve error messages
- - ( ) Evaluate `calc`?
- ( ) `list` & `tuple` data structures?
diff --git a/examples/counter/index.html b/examples/counter/index.html
index 158ee16..9aa89d2 100644
--- a/examples/counter/index.html
+++ b/examples/counter/index.html
@@ -1,9 +1,9 @@
-<!DOCTYPE html>
+<!doctype html>
<html lang="en">
<head>
<title>Counter example</title>
- <meta charset="UTF-8">
- <link href="./style.css" rel="stylesheet">
+ <meta charset="UTF-8" />
+ <link href="./style.css" rel="stylesheet" />
</head>
<body>
<script async defer src="../../dist/index.js"></script>
diff --git a/examples/counter/style.css b/examples/counter/style.css
index 9cf50e0..b60785f 100644
--- a/examples/counter/style.css
+++ b/examples/counter/style.css
@@ -1,6 +1,6 @@
body {
--cssx-children: container todo-container;
- --cssx-on-load: js(console.log("what have we done?!"));
+ --cssx-on-load: js(console.log('what have we done?!'));
}
#container {
@@ -11,7 +11,7 @@ body {
#counter {
}
#counter::before {
- content: "Count: " var(--count);
+ content: 'Count: ' var(--count);
}
#btn-increment {
@@ -22,5 +22,5 @@ body {
--cssx-on-click: update(container, --count, calc(var(--count) + 1));
}
#btn-increment::after {
- content: "Increment";
+ content: 'Increment';
}
diff --git a/examples/form/index.html b/examples/form/index.html
index 1d55241..618b21b 100644
--- a/examples/form/index.html
+++ b/examples/form/index.html
@@ -1,9 +1,9 @@
-<!DOCTYPE html>
+<!doctype html>
<html lang="en">
<head>
<title>Register to this awesome website</title>
- <meta charset="UTF-8">
- <link href="./style.css" rel="stylesheet">
+ <meta charset="UTF-8" />
+ <link href="./style.css" rel="stylesheet" />
</head>
<body>
<script async defer src="../../dist/index.js"></script>
diff --git a/examples/form/signup.css b/examples/form/signup.css
index 96b9ac1..1a5f3ff 100644
--- a/examples/form/signup.css
+++ b/examples/form/signup.css
@@ -1,11 +1,10 @@
-
#signup-page-content {
border: 1px solid #888;
padding: 1rem;
max-width: 700px;
margin: 1rem auto;
- --cssx-disgustingly-set-innerhtml: <h1 class="form-title">Sign-<b>Up</b></h1>;
+ --cssx-disgustingly-set-innerhtml: "<h1 class= 'form-title'>Sign-<b>Up</b></h1>";
--cssx-children: form#form;
--count: '0';
@@ -19,29 +18,26 @@
color: gray;
}
.form-title b {
- font-weight: bold; color: black;
+ font-weight: bold;
+ color: black;
}
#form {
display: block;
- --cssx-on-submit:
- prevent-default()
- add-class(form, 'submitting')
- request('/examples/')
- remove-class(form, 'submitting')
- add-class(form, 'submitted')
- ;
+ --cssx-on-submit: prevent-default() add-class(form, 'submitting')
+ request('/examples/') remove-class(form, 'submitting')
+ add-class(form, 'submitted');
--cssx-children: input#input-email input#input-password actions #message;
}
#form.submitted #message::after {
display: block;
- content: "Form submitted successfully";
+ content: 'Form submitted successfully';
}
#form.submitting #submit-btn {
pointer-events: none;
- opacity: .5;
+ opacity: 0.5;
}
#form input {
@@ -52,21 +48,18 @@
}
#input-email {
- --cssx-on-mount:
- set-attr('type', 'email')
- set-attr('name', 'email')
+ --cssx-on-mount: set-attr('type', 'email') set-attr('name', 'email')
set-attr('required', 'true')
- set-attr('placeholder', 'Email. Eg:- mail@postbox.com')
- ;
+ set-attr('placeholder', 'Email. Eg:- mail@postbox.com');
}
#input-password {
- --cssx-on-mount:
- set-attr('type', 'password')
- set-attr('name', 'password')
+ --cssx-on-mount: set-attr('type', 'password') set-attr('name', 'password')
set-attr('required', 'true')
- set-attr('placeholder', 'Password. Eg:- password, password1, password2, password123')
- ;
+ set-attr(
+ 'placeholder',
+ 'Password. Eg:- password, password1, password2, password123'
+ );
}
#actions {
@@ -79,5 +72,6 @@
padding: 0.4rem 0.7rem;
--cssx-on-mount: set-attr('type', 'submit');
}
-#submit-btn::after { content: "Sign-Up"; }
-
+#submit-btn::after {
+ content: 'Sign-Up';
+}
diff --git a/examples/form/style.css b/examples/form/style.css
index b79f265..113ab81 100644
--- a/examples/form/style.css
+++ b/examples/form/style.css
@@ -8,22 +8,25 @@ body * {
#signup-btn {
display: inline-block;
background: #5180e9;
- color: #000;
+ color: #fff;
+ border: none;
+ outline: none;
padding: 0.5rem 1rem;
cursor: pointer;
--cssx-on-mount: set-attr('type', 'button');
- --cssx-on-click:
- add-class(signup-page, 'loading')
- add-class(signup-btn, 'loading')
- delay(0.5s)
+ --cssx-on-click: add-class(signup-page, 'loading')
+ add-class(signup-btn, 'loading') delay(0.5s)
load-cssx(signup-page-content, './signup.css')
- remove-class(signup-page, 'loading')
- remove-class(signup-btn, 'loading')
- ;
+ remove-class(signup-page, 'loading') remove-class(signup-btn, 'loading');
+}
+#signup-btn::after {
+ content: 'Register now to start your free trail for $99';
+}
+#signup-btn:hover {
+ opacity: 0.8;
}
-#signup-btn::after { content: "Register now to start your free trail for $99"; }
#signup-btn.loading {
pointer-events: none;
opacity: 0.4;
@@ -33,6 +36,5 @@ body * {
--cssx-children: signup-page-content;
}
#signup-page.loading::after {
- content: "Loading...";
+ content: 'Loading...';
}
-
diff --git a/examples/todo-list/style.css b/examples/todo-list/style.css
index aeffde5..7533210 100644
--- a/examples/todo-list/style.css
+++ b/examples/todo-list/style.css
@@ -15,14 +15,11 @@ body {
--cssx-on-click: update(
todo-container,
--todo-list,
- list-append(
- var(--todo-list),
- tuple(get-attr(input-field, value), false)
- )
+ list-append(var(--todo-list), tuple(get-attr(input-field, value), false))
);
}
#submit-btn::after {
- content: "Submit";
+ content: 'Submit';
}
#todo-list {
@@ -30,9 +27,7 @@ body {
}
#todo-item {
-
}
#todo-item::after {
content: var(--todo-item);
}
-
diff --git a/package.json b/package.json
index bcb7de9..e72b517 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"scripts": {
"build": "node esbuild.js",
"serve": "serve -p 3000 .",
+ "format": "prettier --write ./{src,tests}/**/*.ts ./examples/**/*.{html,css}",
"test": "jest"
},
"devDependencies": {
@@ -15,10 +16,11 @@
"esbuild": "^0.18.17",
"jest": "^29.6.2",
"jest-environment-jsdom": "^29.6.2",
+ "prettier": "^3.0.1",
"serve": "^14.2.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
},
"dependencies": {}
-}
+} \ No newline at end of file
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<void>
withEvent(fn: (e: any) => void): Promise<void>
getFormData(): Promise<FormData | undefined>
- sendRequest(_: { method: string, url: string, data: FormData | undefined }): Promise<void>
+ sendRequest(_: {
+ method: string
+ url: string
+ data: FormData | undefined
+ }): Promise<void>
// calculate ??
}
@@ -20,19 +24,19 @@ type EvalValue = string | undefined | void
export const evalExpr = async (
expr: Expr,
- actions: EvalActions
+ actions: EvalActions,
): Promise<EvalValue> =>
match<Promise<EvalValue>, Expr>(expr, {
Call: async ({ name, args }) => getFunctions(name, args, actions),
- LiteralString: async (s) => s,
+ LiteralString: async s => s,
LiteralNumber: async ({ value, unit }) =>
matchString<number, CSSUnit>(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<Expr>()
@@ -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<Expr> = P.map(
@@ -41,14 +41,15 @@ const stringLiteralParser: P.Parser<Expr> = 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<Expr> = 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<Expr> = 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, N> = T extends Tag<N, infer V> ? V : never
-export const match =
- <R, T extends Tag<string, any>>(tag: T, pattern: {
+export const match = <R, T extends Tag<string, any>>(
+ tag: T,
+ pattern: {
[key in T['tag'] | '_']?: (v: TagValue<T, key>) => 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 =
- <R, T extends string = string>(key: T, pattern: {
+export const matchString = <R, T extends string = string>(
+ 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<N, V> = { tag: N; value: V }
export type Enum<T> = { [N in keyof T]: Tag<N, T[N]> }[keyof T]
@@ -26,4 +30,3 @@ export const constructors = <T extends Tag<string, any>>(): {
},
},
) 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';
+import { match } from './adt'
+import { Result, mapResult, chainResult } from './result'
-export type ParseResult<T> = Result<{ value: T, input: string }, { error: string, input: string }>;
+export type ParseResult<T> = Result<
+ { value: T; input: string },
+ { error: string; input: string }
+>
-export type Parser<T> = (input: string) => ParseResult<T>;
+export type Parser<T> = (input: string) => ParseResult<T>
-export const regex = (re: RegExp): Parser<string> => 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 regex =
+ (re: RegExp): Parser<string> =>
+ 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<string> => 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 string =
+ (str: string): Parser<string> =>
+ 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 = <T>([parser, ...rest]: Array<Parser<T>>): Parser<T> => input => {
- if (rest.length === 0) return parser(input);
- const result = parser(input)
- return match(result, {
- Ok: () => result,
- Err: (_) => or(rest)(input),
- });
-}
+export const or =
+ <T>([parser, ...rest]: Array<Parser<T>>): Parser<T> =>
+ input => {
+ if (rest.length === 0) return parser(input)
+ const result = parser(input)
+ return match(result, {
+ Ok: () => result,
+ Err: _ => or(rest)(input),
+ })
+ }
-export const mapParseResult = <T, R>(parser: Parser<T>, fn: (_: { value: T, input: string }) => { value: R, input: string }): Parser<R> => input =>
- mapResult(parser(input), fn)
+export const mapParseResult =
+ <T, R>(
+ parser: Parser<T>,
+ fn: (_: { value: T; input: string }) => { value: R; input: string },
+ ): Parser<R> =>
+ input =>
+ mapResult(parser(input), fn)
export const map = <T, R>(parser: Parser<T>, fn: (_: T) => R): Parser<R> =>
- mapParseResult(parser, ({ value, ...rest }) => ({ ...rest, value: fn(value) }));
+ mapParseResult(parser, ({ value, ...rest }) => ({
+ ...rest,
+ value: fn(value),
+ }))
-export const zip2 = <A, B>(parserA: Parser<A>, parserB: Parser<B>): Parser<readonly [A, B]> => 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 zip2 =
+ <A, B>(parserA: Parser<A>, parserB: Parser<B>): Parser<readonly [A, B]> =>
+ 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 = <A>(parserPrefix: Parser<any>, parser: Parser<A>): Parser<A> =>
- map(zip2(parserPrefix, parser), ([_, a]) => a);
+export const prefixed = <A>(
+ parserPrefix: Parser<any>,
+ parser: Parser<A>,
+): Parser<A> => map(zip2(parserPrefix, parser), ([_, a]) => a)
-export const suffixed = <A>(parser: Parser<A>, parserSuffix: Parser<any>): Parser<A> =>
- map(zip2(parser, parserSuffix), ([a, _]) => a);
+export const suffixed = <A>(
+ parser: Parser<A>,
+ parserSuffix: Parser<any>,
+): Parser<A> => map(zip2(parser, parserSuffix), ([a, _]) => a)
-export const between = <A>(prefix: Parser<any>, parser: Parser<A>, suffix: Parser<any>): Parser<A> =>
- suffixed(prefixed(prefix, parser), suffix)
+export const between = <A>(
+ prefix: Parser<any>,
+ parser: Parser<A>,
+ suffix: Parser<any>,
+): Parser<A> => suffixed(prefixed(prefix, parser), suffix)
-export const many0 = <A>(parser: Parser<A>): Parser<Array<A>> => originalInput =>
- match(parser(originalInput), {
- Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input),
- Err: ({ input }) => Result.Ok({ value: [], input }),
- })
+export const many0 =
+ <A>(parser: Parser<A>): Parser<Array<A>> =>
+ originalInput =>
+ match(parser(originalInput), {
+ Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input),
+ Err: ({ input }) => Result.Ok({ value: [], input }),
+ })
-export const many1 = <A>(parser: Parser<A>): Parser<Array<A>> => originalInput =>
- match(parser(originalInput), {
- Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input),
- Err: err => Result.Err(err),
- })
+export const many1 =
+ <A>(parser: Parser<A>): Parser<Array<A>> =>
+ originalInput =>
+ match(parser(originalInput), {
+ Ok: ({ value, input }) => map(many0(parser), ls => [value, ...ls])(input),
+ Err: err => Result.Err(err),
+ })
-export const sepBy = <A>(parser: Parser<A>, sepP: Parser<any>): Parser<Array<A>> => 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 = <A>(parser: Parser<A>): Parser<undefined | A> => input => {
- const result = parser(input)
- return match(result, {
- Ok: _ => result,
- Err: _ => Result.Ok({ value: undefined, input })
- })
-}
+export const sepBy =
+ <A>(parser: Parser<A>, sepP: Parser<any>): Parser<Array<A>> =>
+ 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 =
+ <A>(parser: Parser<A>): Parser<undefined | A> =>
+ 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<V, E> = Enum<{ Ok: V, Err: E }>
+export type Result<V, E> = Enum<{ Ok: V; Err: E }>
export const Result = constructors<Result<any, any>>()
-export const mapResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => B): Result<B, E> =>
- chainResult(res, a => Result.Ok(fn(a)))
+export const mapResult = <A, B, E>(
+ res: Result<A, E>,
+ fn: (_: A) => B,
+): Result<B, E> => chainResult(res, a => Result.Ok(fn(a)))
-export const chainResult = <A, B, E>(res: Result<A, E>, fn: (_: A) => Result<B, E>): Result<B, E> =>
+export const chainResult = <A, B, E>(
+ res: Result<A, E>,
+ fn: (_: A) => Result<B, E>,
+): Result<B, E> =>
match(res, {
Ok: a => fn(a),
Err: e => Result.Err(e),
- });
-
+ })
diff --git a/tests/eval.spec.ts b/tests/eval.spec.ts
index 49ef4c4..2212ba4 100644
--- a/tests/eval.spec.ts
+++ b/tests/eval.spec.ts
@@ -14,40 +14,52 @@ describe('eval', () => {
}
it('should add classes', async () => {
- await evalExpr(Expr.Call({
- name: 'add-class',
- args: [ Expr.Identifier('element-id'), Expr.LiteralString('class-name') ],
- }), deps)
+ await evalExpr(
+ Expr.Call({
+ name: 'add-class',
+ args: [Expr.Identifier('element-id'), Expr.LiteralString('class-name')],
+ }),
+ deps,
+ )
expect(deps.addClass).toHaveBeenCalledTimes(1)
expect(deps.addClass).toHaveBeenCalledWith('element-id', 'class-name')
})
it('should remove classes', async () => {
- await evalExpr(Expr.Call({
- name: 'remove-class',
- args: [ Expr.Identifier('element-id'), Expr.LiteralString('class-name') ],
- }), deps)
+ await evalExpr(
+ Expr.Call({
+ name: 'remove-class',
+ args: [Expr.Identifier('element-id'), Expr.LiteralString('class-name')],
+ }),
+ deps,
+ )
expect(deps.removeClass).toHaveBeenCalledTimes(1)
expect(deps.removeClass).toHaveBeenCalledWith('element-id', 'class-name')
})
it('should add a delay', async () => {
- await evalExpr(Expr.Call({
- name: 'delay',
- args: [ Expr.LiteralString('200') ],
- }), deps)
+ await evalExpr(
+ Expr.Call({
+ name: 'delay',
+ args: [Expr.LiteralString('200')],
+ }),
+ deps,
+ )
expect(deps.delay).toHaveBeenCalledTimes(1)
expect(deps.delay).toHaveBeenCalledWith(200)
})
it('should get variable', async () => {
- await evalExpr(Expr.Call({
- name: 'var',
- args: [ Expr.LiteralString('--my-var'), Expr.LiteralString('def value') ],
- }), deps)
+ await evalExpr(
+ Expr.Call({
+ name: 'var',
+ args: [Expr.LiteralString('--my-var'), Expr.LiteralString('def value')],
+ }),
+ deps,
+ )
expect(deps.getVariable).toHaveBeenCalledTimes(1)
expect(deps.getVariable).toHaveBeenCalledWith('--my-var')
diff --git a/tests/parser.spec.ts b/tests/parser.spec.ts
index f2893b8..41fafa3 100644
--- a/tests/parser.spec.ts
+++ b/tests/parser.spec.ts
@@ -49,7 +49,7 @@ describe('parser', () => {
])
expect(parse(` 'hello world toodles \" nice double quote there' `)).toEqual(
- [Expr.LiteralString(`hello world toodles \" nice double quote there`)]
+ [Expr.LiteralString(`hello world toodles \" nice double quote there`)],
)
})
diff --git a/yarn.lock b/yarn.lock
index 9860a27..af9090f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2497,6 +2497,11 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"
+prettier@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.1.tgz#65271fc9320ce4913c57747a70ce635b30beaa40"
+ integrity sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==
+
pretty-format@^29.0.0, pretty-format@^29.6.2:
version "29.6.2"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47"