blacksmithgu / datacore

Work-in-progress successor to Dataview with a focus on UX and speed.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

question about codeblocks and codeblock rendering

GamerGirlandCo opened this issue · comments

roadmap says:

React-based Views: Javascript swaps to using React for views, which eliminates the "flickering" during re-renders, and also allows for access to Datacore visual components.

does this mean jsx syntax will be supported in datacore-js codeblocks? if not, should there be helper functions implemented to render out views from pure js code in api/local-api.ts ?

So I had an earlier pass which supported full JSX. The problem is that this requires including the entirety of babel as a dependency in order to transpile JSX -> plain JS, which increases the size of the Datacore binary by 12x (~400kb -> 6mb). That was... not good.

It's possible to use React without touching JSX at all which is what I am currently aiming for... maybe using babel can be opt-in via an addon plugin.

how will a query string "translate" to a view (i.e., table, card, etc)?
i remember that in Dataview there were functions like createTaskView, createTableView, etc. to return a jsx component to pass to a MarkdownPostProcessorContext to be rendered. however, i've noticed that the view components require more than just a simple query AST to be rendered:

export interface TableProps<T> {
/** Actual data rows to render in the table. */
rows: T[];
/** Initial columns for the table. */
initialColumns?: TableColumn<T>[];
/** Controlled prop for setting the current table columns. */
columns?: TableColumn<T>[];
/** Whether the table can be sorted. */
sortable?: boolean;
/** Initial sorts for the table. */
initialSortOn?: SortOn[];
/** Controlled prop for setting the sort. */
sortOn?: SortOn[];
/**
* If a boolean, enables/disables paging with the default configuration. If a number, paging will be
* enabled with the given number of entries per page.
*/
paging?: number | boolean;
/** The initial page of the table. */
initialPage?: number;
/** Controlled prop for setting the page of the table. */
page?: number;
/** If set, state updates will go through this function, which can choose which events to listen to. */
onUpdate?: TableActionHandler;
}

what am i supposed to do with this interface? i've been trying to figure out how to create the components to be rendered in codeblocks (for testing/tinkering purposes)

The translation later isn't present yet. Datacore is going to use plain YAML for it's codeblocks (instead of a query language), so the flow will be something like this. You start with a codeblock describing the view:

table:
  source: "@page and #game and rating > 7"
  columns: ["$link", "rating"]
  initial-sort: rating DESC

This is parsed and converted into the TableProps and then rendered as a react component.

I'm planning on adding some initial logic for this, this week to demonstrate.

So I had an earlier pass which supported full JSX. The problem is that this requires including the entirety of babel as a dependency in order to transpile JSX -> plain JS, which increases the size of the Datacore binary by 12x (~400kb -> 6mb). That was... not good.

An alternative to babel is sucrase. It's smaller and faster than babel because what it aims to do is a bit simpler. It's not trying to convert every modern JavaScript feature to something that decade-old browsers can understand. I've been using it to strip TypeScript type annotations and convert ES Module syntax to CommonJS syntax for my Dataview scripts.

Very interesting! I will give this library a try instead. If it could also serve as a preprocessor to support typescript that would be great!

I tried sucrase and the binary bundled with everything installed and not minified is about 1.4mb (instead of 5.4mb). That is still a bit meaty, but I think it's acceptable enough since being able to natively use TypeScript and JSX is great for coding UX!

I'm just thinking loud:
I wonder if size could be reduced even further by using a AST builder that's implemented in wasm. (considering wasm is actually supported in obsidian)

I'll look into that..

edit: apparently obsidian is actually using wasm so.. it is doable.
edit2: it's also using hard coded .node files so.. even native modules outside wasm should be possible.

I haven't personally bundled things using WASM but if it's possible to bundle sucrase as a compressed WASM library that seems appealing.

apparently self-hosted-livesync is bundling a wasm module for fast file hashing.

Closing this since we've adopted sucrase for JSX/TSX support.