Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Check formatting
run: npm run format:check

- name: Rebuild ReScript code
run: npm run build

Expand Down Expand Up @@ -81,4 +84,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v4
16 changes: 3 additions & 13 deletions docs/content/docs/contributing/api-modelling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,7 @@ String(unsafeConversation(t))
}
`

<Code
code={fillStyleModule}
title="DOMAPI/FillStyle.res"
lang="ReScript"
></Code>
<Code code={fillStyleModule} title="DOMAPI/FillStyle.res" lang="ReScript"></Code>

We can now use `FillStyle.decode` to get the actual value of the `fillStyle` property.
And use `FillStyle.fromString`, `FillStyle.fromCanvasGradient`, and `FillStyle.fromCanvasPattern` to set the value.
Expand All @@ -135,11 +131,5 @@ switch ctx.fillStyle->FillStyle.decode {
}
```

<Icon
name="information"
color="var(--sl-color-text-accent)"
class="inline-icon"
size="1.5rem"
/>
Try and use `decoded` and `decode` as conventions for the type and function
names.
<Icon name="information" color="var(--sl-color-text-accent)" class="inline-icon" size="1.5rem" />
Try and use `decoded` and `decode` as conventions for the type and function names.
4 changes: 2 additions & 2 deletions docs/content/docs/contributing/api-module-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ type htmlSpanElement = {
```

<Aside>
Properties spreading is not possible in recursive types! When a circular
reference is detected, the base properties are duplicated instead.
Properties spreading is not possible in recursive types! When a circular reference is detected,
the base properties are duplicated instead.
</Aside>

```ReScript
Expand Down
5 changes: 1 addition & 4 deletions docs/content/docs/contributing/code-generation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,7 @@ interfaceHierarchy = [
name: "Temp",
entries: [
enums(["WebGLPowerPreference"]),
dictionaries([
"ImageBitmapRenderingContextSettings",
"WebGLContextAttributes",
]),
dictionaries(["ImageBitmapRenderingContextSettings", "WebGLContextAttributes"]),
],
opens: [],
},
Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/contributing/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ slug: "01-getting-started"
import { Aside } from "@astrojs/starlight/components";

<Aside type="caution">
**Real talk**: First time diving into this project? Might feel like a letdown.
But hey, the upside? It’s stupid easy to toss us a PR and make it better!
**Real talk**: First time diving into this project? Might feel like a letdown. But hey, the
upside? It’s stupid easy to toss us a PR and make it better!
</Aside>

The [WebAPI](https://developer.mozilla.org/en-US/docs/Web/API) are vast and ever-growing. We need your help to make them better.
Expand Down
23 changes: 7 additions & 16 deletions docs/content/docs/contributing/module-type-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ open DOMAPI
// A concrete type for \`T.t\` is passed later using the \`include\` keyword.
module Impl = (T: { type t }) => {

/**
/\*_
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/HTMLElement/focus)
*/
_/
@send
external focus: (T.t, ~options: focusOptions=?) => unit = "focus"

Expand All @@ -56,11 +56,7 @@ external focus: (T.t, ~options: focusOptions=?) => unit = "focus"
include Impl({ type t = htmlElement })
`;

<Code
code={htmlElementModule}
title="DOMAPI/HTMLElement.res"
lang="ReScript"
></Code>
<Code code={htmlElementModule} title="DOMAPI/HTMLElement.res" lang="ReScript"></Code>

export const buttonModule = `
open DOMAPI
Expand All @@ -70,17 +66,12 @@ include HTMLElement.Impl({ type t = htmlButtonElement })

// Add additional methods specific to HTMLButtonElement:

/**
/\*_
Returns whether a form will validate when it is submitted, without having to submit it.
[Read more on MDN](
https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/checkValidity)
*/
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/checkValidity)
_/
@send
external checkValidity: htmlButtonElement => bool = "checkValidity"
`;

<Code
code={buttonModule}
title="DOMAPI/HTMLButtonElement.res"
lang="ReScript"
></Code>
<Code code={buttonModule} title="DOMAPI/HTMLButtonElement.res" lang="ReScript"></Code>
5 changes: 2 additions & 3 deletions docs/content/docs/contributing/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ npm test
If any of the existing tests have different ouput JavaScript, you will see a diff in the output and the test will fail.

<Aside>
Depending on your use-case, it might be okay to have slightly different output
JavaScript. The maintainers will help you to decide if the change is
acceptable.
Depending on your use-case, it might be okay to have slightly different output JavaScript. The
maintainers will help you to decide if the change is acceptable.
</Aside>

## Why add tests?
Expand Down
12 changes: 2 additions & 10 deletions docs/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,10 @@ Install the package using your favorite package manager:

<Tabs syncKey="package manager">
<TabItem label="npm">
<Code
lang="shell"
frame="none"
code="npm i @rescript/webapi@experimental"
/>
<Code lang="shell" frame="none" code="npm i @rescript/webapi@experimental" />
</TabItem>
<TabItem label="bun">
<Code
lang="shell"
frame="none"
code="bun i @rescript/webapi@experimental"
/>
<Code lang="shell" frame="none" code="bun i @rescript/webapi@experimental" />
</TabItem>
</Tabs>

Expand Down
144 changes: 72 additions & 72 deletions docs/llm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,102 +6,102 @@ import fs from "node:fs/promises";
const execAsync = promisify(exec);

const bins = await import(
path.join(import.meta.dirname, "../node_modules/rescript/cli/common/bins.js")
path.join(import.meta.dirname, "../node_modules/rescript/cli/common/bins.js")
);
const rescriptTools = bins["rescript_tools_exe"];

if (!rescriptTools) {
throw new Error("rescript-tools not found");
throw new Error("rescript-tools not found");
}

async function getDocJson(filePath) {
try {
const command = `${rescriptTools} doc "${filePath}"`;
const options = { maxBuffer: 10 * 1024 * 1024 };
const { stdout, stderr } = await execAsync(command, options);

if (stderr) {
throw new Error(`Error executing command for ${filePath}: ${stderr}`);
}

return JSON.parse(stdout);
} catch (error) {
throw new Error(`Failed to get documentation JSON for ${filePath}:`, error);
try {
const command = `${rescriptTools} doc "${filePath}"`;
const options = { maxBuffer: 10 * 1024 * 1024 };
const { stdout, stderr } = await execAsync(command, options);

if (stderr) {
throw new Error(`Error executing command for ${filePath}: ${stderr}`);
}

return JSON.parse(stdout);
} catch (error) {
throw new Error(`Failed to get documentation JSON for ${filePath}:`, error);
}
}

async function processFile(filePath) {
const json = await getDocJson(filePath);

const moduleName = "WebAPI." + json.name.replace("-WebAPI", "");

const types = [];
const functions = [];

function mkType(item) {
let description = "";
if (item.docstrings.length > 0) {
description = "\n Description: " + item.docstrings.join("\n");
}
let fields = "";
if (item.detail && item.detail.kind === "record") {
fields =
"\n Fields:\n" +
item.detail.items
.map((field) => {
let fieldDoc = "";
if (field.docstrings.length > 0) {
fieldDoc = " - " + field.docstrings.join(" ");
}
return ` - ${field.name}: ${field.signature}${fieldDoc}`;
})
.join("\n");
}
return `- ${item.signature}${description}${fields}`;
}
const json = await getDocJson(filePath);

function mkFunction(item) {
let description = "";
if (item.docstrings.length > 0) {
description = "\n Description: " + item.docstrings.join("\n");
}
return `- ${item.signature}${description}`;
}
const moduleName = "WebAPI." + json.name.replace("-WebAPI", "");

for (const item of json.items) {
switch (item.kind) {
case "type":
types.push(mkType(item));
break;
case "value":
functions.push(mkFunction(item));
break;
}
}
const types = [];
const functions = [];

let typeString = "";
if (types.length > 0) {
typeString = "\n\nTypes:\n\n" + types.join("\n\n");
function mkType(item) {
let description = "";
if (item.docstrings.length > 0) {
description = "\n Description: " + item.docstrings.join("\n");
}
let fields = "";
if (item.detail && item.detail.kind === "record") {
fields =
"\n Fields:\n" +
item.detail.items
.map((field) => {
let fieldDoc = "";
if (field.docstrings.length > 0) {
fieldDoc = " - " + field.docstrings.join(" ");
}
return ` - ${field.name}: ${field.signature}${fieldDoc}`;
})
.join("\n");
}
return `- ${item.signature}${description}${fields}`;
}

let functionString = "";
if (functions.length > 0) {
functionString = "\n\nFunctions:\n\n" + functions.join("\n\n");
function mkFunction(item) {
let description = "";
if (item.docstrings.length > 0) {
description = "\n Description: " + item.docstrings.join("\n");
}
return `- ${item.signature}${description}`;
}

for (const item of json.items) {
switch (item.kind) {
case "type":
types.push(mkType(item));
break;
case "value":
functions.push(mkFunction(item));
break;
}
}

let typeString = "";
if (types.length > 0) {
typeString = "\n\nTypes:\n\n" + types.join("\n\n");
}

return `File: ${json.source.filepath}
let functionString = "";
if (functions.length > 0) {
functionString = "\n\nFunctions:\n\n" + functions.join("\n\n");
}

return `File: ${json.source.filepath}
Module: ${moduleName}${typeString}${functionString}
`;
}

const pattern = "../src/**/*.res"
const pattern = "../src/**/*.res";
const files = [];
for await (const file of fs.glob(pattern, { recursive: true, cwd: import.meta.dirname })) {
files.push(path.join(import.meta.dirname, file));
for await (const file of fs.glob(pattern, { recursive: true, cwd: import.meta.dirname })) {
files.push(path.join(import.meta.dirname, file));
}
files.sort();

const pages = await Promise.all(files.map(processFile))
const pages = await Promise.all(files.map(processFile));
const packageJson = await fs.readFile(path.join(import.meta.dirname, "../package.json"), "utf-8");
let version = JSON.parse(packageJson).version;
const sha = await execAsync("git rev-parse --short HEAD").then(({ stdout }) => stdout.trim());
Expand All @@ -111,7 +111,7 @@ const header = `Experimental Rescript WebAPI Documentation ${fullVersion}
This is the API documentation for the experimental WebAPI module version ${fullVersion}.
More information can be found on https://rescript-lang.github.io/experimental-rescript-webapi/

`
`;
const content = pages.join("\n---\n\n");
await fs.writeFile(path.join(import.meta.dirname, "public/llm.txt"), header + content);
console.log("Generated llm.txt");
console.log("Generated llm.txt");
Loading