Skip to content

Commit

Permalink
Merge pull request #253 from danielo515/feat/async-advanced-fields
Browse files Browse the repository at this point in the history
Feat/async-advanced-fields
  • Loading branch information
danielo515 authored May 10, 2024
2 parents 2748852 + 62581b6 commit d2b020a
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 182 deletions.
82 changes: 41 additions & 41 deletions esbuild.config.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import esbuild from "esbuild";
import process from "process";
import builtins from "builtin-modules";
import esbuild from "esbuild";
import esbuildSvelte from "esbuild-svelte";
import fs from "node:fs";
import process from "process";
import sveltePreprocess from "svelte-preprocess";
import fs from 'node:fs';

const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
Expand All @@ -14,46 +14,46 @@ if you want to view the source, please visit the github repository of this plugi
const prod = process.argv[2] === "production";

const context = await esbuild.context({
banner: {
js: banner,
},
entryPoints: ["src/main.ts"],
bundle: true,
metafile: true,
plugins: [
esbuildSvelte({
compilerOptions: { css: "injected" },
preprocess: sveltePreprocess(),
}),
],
external: [
"obsidian",
"electron",
"@codemirror/autocomplete",
"@codemirror/collab",
"@codemirror/commands",
"@codemirror/language",
"@codemirror/lint",
"@codemirror/search",
"@codemirror/state",
"@codemirror/view",
"@lezer/common",
"@lezer/highlight",
"@lezer/lr",
...builtins,
],
format: "cjs",
target: "es2018",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
outfile: "main.js",
banner: {
js: banner,
},
entryPoints: ["src/main.ts"],
bundle: true,
metafile: true,
plugins: [
esbuildSvelte({
compilerOptions: { css: "injected" },
preprocess: sveltePreprocess(),
}),
],
external: [
"obsidian",
"electron",
"@codemirror/autocomplete",
"@codemirror/collab",
"@codemirror/commands",
"@codemirror/language",
"@codemirror/lint",
"@codemirror/search",
"@codemirror/state",
"@codemirror/view",
"@lezer/common",
"@lezer/highlight",
"@lezer/lr",
...builtins,
],
format: "cjs",
target: "es2019",
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
outfile: "main.js",
});

if (prod) {
const result = await context.rebuild();
fs.writeFileSync('meta.json', JSON.stringify(result.metafile))
process.exit(0);
const result = await context.rebuild();
fs.writeFileSync("meta.json", JSON.stringify(result.metafile));
process.exit(0);
} else {
await context.watch();
await context.watch();
}
4 changes: 2 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"author": "Danielo Rodriguez",
"authorUrl": "https://danielo.es",
"fundingUrl": "https://www.buymeacoffee.com/danielo515",
"helpUrl": "https://danielorodriguez.com/obsidian-modal-form/",
"helpUrl": "https://danielorodriguez.com/obsidian-modal-form/",
"isDesktopOnly": false,
"version": "1.40.4"
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 19 additions & 15 deletions src/FormModal.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { App, Modal, Platform, Setting, sanitizeHTMLToDom } from "obsidian";
import { E, absurd, parseFunctionBody, pipe, throttle } from "@std";
import * as R from "fp-ts/Record";
import MultiSelect from "./views/components/MultiSelect.svelte";
import * as TE from "fp-ts/TaskEither";
import { App, Modal, Platform, Setting, sanitizeHTMLToDom } from "obsidian";
import { SvelteComponent } from "svelte";
import { Writable } from "svelte/store";
import FormResult, { type ModalFormData } from "./core/FormResult";
import { formDataFromFormDefaults } from "./core/formDataFromFormDefaults";
import { get_tfiles_from_folder } from "./utils/files";
import type { FormDefinition, FormOptions } from "./core/formDefinition";
import { FieldValue, FormEngine, makeFormEngine } from "./store/formStore";
import { FileSuggest } from "./suggesters/suggestFile";
import { FolderSuggest } from "./suggesters/suggestFolder";
import { DataviewSuggest } from "./suggesters/suggestFromDataview";
import { SvelteComponent } from "svelte";
import { E, parseFunctionBody, pipe, throttle, absurd } from "@std";
import { log_error, log_notice } from "./utils/Log";
import { FieldValue, FormEngine, makeFormEngine } from "./store/formStore";
import { Writable } from "svelte/store";
import { FolderSuggest } from "./suggesters/suggestFolder";
import { get_tfiles_from_folder } from "./utils/files";
import MultiSelect from "./views/components/MultiSelect.svelte";
import { MultiSelectModel, MultiSelectTags } from "./views/components/MultiSelectModel";

export type SubmitFn = (formResult: FormResult) => void;
Expand Down Expand Up @@ -190,10 +191,12 @@ export class FormModal extends Modal {
values: fieldStore.value as Writable<string[]>,
setting: fieldBase,
errors: fieldStore.errors,
model: MultiSelectTags(
fieldInput,
this.app,
fieldStore.value as Writable<string[]>,
model: Promise.resolve(
MultiSelectTags(
fieldInput,
this.app,
fieldStore.value as Writable<string[]>,
),
),
},
}),
Expand Down Expand Up @@ -257,21 +260,22 @@ export class FormModal extends Modal {
const sub = this.formEngine.subscribe((form) => {
pipe(
functionParsed,
E.chainW((fn) =>
TE.fromEither,
TE.chainW((fn) =>
pipe(
form.fields,
R.filterMap((field) => field.value),
fn,
),
),
E.match(
TE.match(
(error) => {
console.error(error);
notifyError("Error in document block")(String(error));
},
(newText) => domNode.setText(sanitizeHTMLToDom(newText)),
),
);
)();
});
return this.subscriptions.push(sub);
}
Expand Down
33 changes: 25 additions & 8 deletions src/std/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as TE from "fp-ts/TaskEither";
import { array, boolean, number, object, string } from "valibot";
import { E, parseFunctionBody, pipe, trySchemas } from "./index";
import { string, number, array, boolean, object } from "valibot";

describe("trySchemas", () => {
const schema1 = object({
Expand Down Expand Up @@ -121,21 +122,37 @@ describe("parseFunctionBody", () => {
);
});
it("should fail to parse a function body when it is incorrect", () => {
const input = "{ return x + 1; ";
const input = "% return x + 1; ";
const result = parseFunctionBody(input);
expect(result).toEqual(E.left(new SyntaxError("Unexpected token ')'")));
expect(result).toEqual(E.left(new SyntaxError("Unexpected token '%'")));
});
it("should parse a function body with arguments and be able to execute it", () => {
it("should parse a function body with arguments and be able to execute it", (done) => {
const input = "return x + 1;";
const result = parseFunctionBody<[number], number>(input, "x");
pipe(
const fn = pipe(
result,
E.match(
() => fail("Expected a right"),
(result) => {
expect(result(1)).toEqual(E.right(2));
() => {
throw new Error("Expected a right");
},
(parsedFn) => {
console.log(parsedFn.toString());
return pipe(
parsedFn(1),
TE.match(
(error) => {
console.error({ error });
throw new Error("Expected a right");
},
(result) => {
console.log({ result });
return expect(result).toEqual(2);
},
),
);
},
),
);
fn().then(done, done);
});
});
57 changes: 30 additions & 27 deletions src/std/index.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
import { pipe as p, flow as f, absurd as _absurd } from "fp-ts/function";
import {
partitionMap,
findFirst,
findFirstMap,
partition,
map as mapArr,
filter,
compact,
filter,
filterMap,
findFirst,
findFirstMap,
flatten,
map as mapArr,
partition,
partitionMap,
} from "fp-ts/Array";
import * as _O from "fp-ts/Option";
import {
Either,
ap,
bimap,
chainW,
flap,
flatMap,
fromNullable,
getOrElse,
isLeft,
isRight,
tryCatchK,
map,
getOrElse,
fromNullable,
right,
left,
map,
mapLeft,
Either,
bimap,
tryCatch,
flatMap,
ap,
flap,
chainW,
match,
right,
tryCatch,
tryCatchK,
} from "fp-ts/Either";
export type Option<T> = _O.Option<T>;
import { BaseSchema, Output, ValiError, parse as parseV } from "valibot";
import { Semigroup, concatAll } from "fp-ts/Semigroup";
import { NonEmptyArray, concatAll as concatAllNea } from "fp-ts/NonEmptyArray";
export type { NonEmptyArray } from "fp-ts/NonEmptyArray";
import * as _O from "fp-ts/Option";
import { Semigroup, concatAll } from "fp-ts/Semigroup";
import * as TE from "fp-ts/TaskEither";
import { absurd as _absurd, flow as f, pipe as p } from "fp-ts/function";
import { BaseSchema, Output, ValiError, parse as parseV } from "valibot";
export type Option<T> = _O.Option<T>;
export type { Either, Left, Right } from "fp-ts/Either";
export type { NonEmptyArray } from "fp-ts/NonEmptyArray";
export const flow = f;
export const pipe = p;
export const absurd = _absurd;
Expand Down Expand Up @@ -170,10 +171,12 @@ export function ensureError(e: unknown): Error {
return e instanceof Error ? e : new Error(String(e));
}

// There is no way to access the constructor of an async function than the prototype chain
const AsyncFunction = new Function("return async () => {}")().constructor;
/**
* Creates a function from a string that is supposed to be a function body.
* It ensures the "use strict" directive is present and returns the function.
* Because the parsing can fail, it returns an Either.
* Because the parsing can fail, it returns an TaskEither.
* The reason why the type arguments are reversed is because
* we often know what the function input types should be, but
* we can't trust the function body to return the correct type, so by default1t it will be unknown
Expand All @@ -183,8 +186,8 @@ export function parseFunctionBody<Args extends unknown[], T>(body: string, ...ar
const fnBody = `"use strict";
${body}`;
try {
const fn = new Function(...args, fnBody) as (...args: Args) => T;
return right(tryCatchK(fn, ensureError));
const fn = AsyncFunction(...args, fnBody) as (...args: Args) => Promise<T>;
return right(TE.tryCatchK(fn, ensureError));
} catch (e) {
return left(ensureError(e));
}
Expand Down
Loading

0 comments on commit d2b020a

Please sign in to comment.