diff --git a/examples/macros/components/covid19.tsx b/examples/macros/components/covid19.tsx
new file mode 100644
index 0000000000000..52fee2ff35269
--- /dev/null
+++ b/examples/macros/components/covid19.tsx
@@ -0,0 +1,33 @@
+import { fetchCSV } from "macro:fetchCSV";
+
+export const Covid19 = () => {
+ const rows = fetchCSV(
+ "https://covid19.who.int/WHO-COVID-19-global-data.csv",
+ {
+ last: 100,
+ columns: ["New_cases", "Date_reported", "Country"],
+ }
+ );
+
+ return (
+
+
Covid-19
+
last {rows.length} updates from the WHO
+
+
+
New Cases
+
Date
+
Country
+
+
+ {rows.map((row, index) => (
+
+
{row[0]}
+
{row[1]}
+
{row[2]}
+
+ ))}
+
+
+ );
+};
diff --git a/examples/macros/components/index.tsx b/examples/macros/components/index.tsx
index 6c3e39be70fa3..20e58b7b7a27c 100644
--- a/examples/macros/components/index.tsx
+++ b/examples/macros/components/index.tsx
@@ -5,6 +5,7 @@ import { IPAddresses } from "./example";
const Start = function () {
const root = document.createElement("div");
document.body.appendChild(root);
+
ReactDOM.render(, root);
};
diff --git a/examples/macros/fetchCSV.tsx b/examples/macros/fetchCSV.tsx
index 0709fd50053ab..b06b1e03ee12e 100644
--- a/examples/macros/fetchCSV.tsx
+++ b/examples/macros/fetchCSV.tsx
@@ -1,4 +1,12 @@
import Pappa from "papaparse";
+// Example usage:
+// const rows = fetchCSV(
+// "https://covid19.who.int/WHO-COVID-19-global-data.csv",
+// {
+// last: 100,
+// columns: ["New_cases", "Date_reported", "Country"],
+// }
+// );
export async function fetchCSV(callExpression) {
console.time("fetchCSV Total");
const [
diff --git a/examples/macros/matchInFile.tsx b/examples/macros/matchInFile.tsx
index a73f7ee8bfbc0..1f5c20fb36957 100644
--- a/examples/macros/matchInFile.tsx
+++ b/examples/macros/matchInFile.tsx
@@ -1,8 +1,11 @@
// macro code
-export function matchInFile(callExpression) {
+export function matchInFile(callExpression: BunAST.CallExpression) {
const [filePathNode, matcherNode] = callExpression.arguments;
- const filePath: string = filePathNode.get();
- const matcher: RegExp = matcherNode.get();
+ let filePath: string;
+ filePath = filePathNode.get();
+
+ let matcher: RegExp;
+ matcher = matcherNode.get();
const file: string = Bun.readFile(Bun.cwd + filePath);
return (
@@ -18,3 +21,81 @@ export function matchInFile(callExpression) {
);
}
+
+export declare namespace BunAST {
+ export abstract class ASTNode {
+ constructor(...args: any);
+ }
+
+ export interface ASTElement<
+ P = any,
+ T extends string | JSXElementConstructor =
+ | string
+ | JSXElementConstructor
+ > {
+ type: T;
+ props: P;
+ key: Key | null;
+ }
+
+ export abstract class Expression extends ASTNode {}
+
+ export abstract class CallExpression extends Expression {
+ arguments: AnyExpression[];
+ name: string;
+ target: AnyExpression;
+ }
+
+ export abstract class StringExpression extends Expression {
+ get(): string;
+ value: string;
+ }
+
+ export interface StringExpressionElementProps {
+ value: string;
+ }
+
+ export type StringExpressionElement = ASTElement<
+ StringExpressionElementProps,
+ StringExpression
+ >;
+
+ export abstract class RegExpExpression extends Expression {
+ get(): RegExp;
+
+ flags: string;
+ pattern: string;
+ raw: string;
+ }
+
+ export type AnyExpression =
+ | CallExpression
+ | StringExpression
+ | RegExpExpression;
+}
+
+declare global {
+ namespace JSX {
+ interface Element extends BunAST.ASTElement {}
+ interface ElementClass extends BunAST.Expression {}
+ interface ElementAttributesProperty {
+ props: {};
+ }
+ interface ElementChildrenAttribute {
+ children: {};
+ }
+
+ // // We can't recurse forever because `type` can't be self-referential;
+ // // let's assume it's reasonable to do a single React.lazy() around a single React.memo() / vice-versa
+ // type LibraryManagedAttributes = C extends React.MemoExoticComponent | React.LazyExoticComponent
+ // ? T extends React.MemoExoticComponent | React.LazyExoticComponent
+ // ? ReactManagedAttributes
+ // : ReactManagedAttributes
+ // : ReactManagedAttributes;
+
+ interface IntrinsicElements {
+ // HTML
+ string: BunAST.StringExpressionElement;
+ }
+ }
+}
diff --git a/examples/macros/package.json b/examples/macros/package.json
index de4e264534206..dff2c648e122c 100644
--- a/examples/macros/package.json
+++ b/examples/macros/package.json
@@ -5,8 +5,13 @@
"license": "MIT",
"dependencies": {
"moment": "^2.29.1",
+ "papaparse": "^5.3.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-refresh": "^0.10.0"
+ },
+ "devDependencies": {
+ "@types/react": "^17.0.24",
+ "@types/react-dom": "^17.0.9"
}
}
diff --git a/examples/macros/styles.css b/examples/macros/styles.css
index 87f0ef1a81d27..a8109a8206d0a 100644
--- a/examples/macros/styles.css
+++ b/examples/macros/styles.css
@@ -18,9 +18,30 @@ body {
font-family: monospace;
}
-.Lines {
+.Table {
+ display: grid;
+ width: fit-content;
+}
+
+.Row,
+.Header {
+ display: grid;
+ grid-template-columns: 2fr 1fr 1fr;
+ text-align: right;
+
+ column-gap: 2rem;
+}
+
+.Heading {
+ text-align: right;
+}
+
+.Header {
+ border-bottom: 1px solid rgb(0, 255, 0);
+ margin-bottom: 20px;
+ padding-bottom: 20px;
+}
+
+.Heading:nth-of-type(2) {
text-align: left;
- margin: 0 auto;
- max-width: fit-content;
- line-height: 1.5;
}