Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
48 changes: 9 additions & 39 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,62 +56,32 @@ jobs:
id: vars
run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV

- name: Update workspace versions to -<commit-hash>
- name: Update package version to -<commit-hash>
env:
PACKAGE_VERSION: ${{ steps.package-version.outputs.current-version }}-experimental-${{ env.COMMIT_HASH }}
run: |
node <<'NODE'
const fs = require("node:fs");
const path = require("node:path");

const packagesDir = path.join(process.cwd(), "packages");
const version = process.env.PACKAGE_VERSION;
const packages = fs
.readdirSync(packagesDir)
.filter((dir) => fs.existsSync(path.join(packagesDir, dir, "package.json")))
.map((dir) => {
const packageJsonPath = path.join(packagesDir, dir, "package.json");
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
return { packageJsonPath, packageJson };
});
const workspaceNames = new Set(packages.map(({ packageJson }) => packageJson.name));

for (const { packageJsonPath, packageJson } of packages) {
packageJson.version = version;

for (const field of ["dependencies", "peerDependencies", "devDependencies"]) {
if (!packageJson[field]) continue;

for (const dependencyName of Object.keys(packageJson[field])) {
if (workspaceNames.has(dependencyName)) {
packageJson[field][dependencyName] = version;
}
}
}

fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
}
const packageJsonPath = "package.json";
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
packageJson.version = process.env.PACKAGE_VERSION;
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
NODE

- name: Package npm workspaces
run: npm pack --workspaces
- name: Package npm package
run: npm pack

- name: Upload npm package artifact
uses: actions/upload-artifact@v7
with:
name: npm-packages
path: "*.tgz"

- name: Publish npm packages
- name: Publish npm package
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
run: |
for package in packages/*; do
if [ -f "$package/package.json" ]; then
npm publish --workspace "$package" --access public --tag experimental
fi
done
run: npm publish --access public --tag experimental

deploy-docs:
needs: build
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
dist/
tmp/
docs/public/llm.txt
.npm-cache/
*.tgz
*~
.worktrees/

**/lib/bs/
**/lib/ocaml
Expand All @@ -14,4 +17,6 @@ docs/public/llm.txt

rescript.lock

**/*.res.js
src/**/*.js
tests/**/*.js
**/*.res.js
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,22 @@ and add `@rescript/webapi` to your `rescript.json`:
```json
{
"bs-dependencies": [
+ "@rescript/webapi",
"@rescript/webapi"
],
"bsc-flags": [
+ "-open WebAPI.Global"
"-open WebAPI.Global"
]
}
```

## Usage

```rescript
let location = window.location
let href = location.href
location->WebAPI.Location.reload
```

## Documentation

More information can be found on https://rescript-lang.github.io/experimental-rescript-webapi/
4 changes: 2 additions & 2 deletions docs/content/docs/contributing/api-modelling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ mutable fillStyle: fillStyle
When we wish to read and write the `fillStyle` property, we can use a helper module to lift the type to an actual ReScript variant:

export const fillStyleModule = `
open WebApiCanvas
open WebApiDOM
open WebAPI.Canvas
open WebAPI.DOM

external fromString: string => fillStyle = "%identity"
external fromCanvasGradient: canvasGradient => fillStyle = "%identity"
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/contributing/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Aside } from "@astrojs/starlight/components";
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.
The [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) are vast and ever-growing. We need your help to make them better.
There is no way our [contributors](https://github.com/rescript-lang/experimental-rescript-webapi/graphs/contributors) can cover everything.
And that's where you come in! A small PR, focused on what you want to get out of this project can make a huge difference.

Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ and add `@rescript/webapi` to your `rescript.json`:
export const rescriptJson = `
{
"bs-dependencies": [
"@rescript/webapi",
"@rescript/webapi"
],
"bsc-flags": [
"-open WebAPI.Global"
Expand All @@ -61,7 +61,7 @@ let location = window.location
let href = location.href

// Invoke methods using the \`->TypeModule.method\`
location->Location.reload
location->WebAPI.Location.reload
`;

export const compiledSample = `
Expand Down
23 changes: 8 additions & 15 deletions docs/content/docs/philosophy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ The bindings are generated from the [MDN Web API documentation](https://develope

In other words, if you are searching for a specific JavaScript binding, begin your journey at the [MDN Web API documentation](https://developer.mozilla.org/en-US/docs/Web/API) and determine which module contains your sample. Ensure that the module is available in the bindings by checking the specific API. Please [open an issue](https://github.com/rescript-lang/experimental-rescript-webapi/issues/new/choose) if you require an API that is not yet present.

Each API will have its interface and auxiliary types in a module named after the API, suffixed with `API` to prevent collisions with the type module.
The bindings are exposed under the `WebAPI` namespace, with feature entry modules such as `WebAPI.DOM` available when you want to scope imports more narrowly.

```ReScript
open WebAPI.Global
open WebAPI.DOMAPI
// or WebAPI.DOM

let myElement: element = document->Document.createElement( ~localName = "div")
let myElement: WebAPI.Element.t = document->WebAPI.Document.createElement("div")
```

## Interfaces
Expand All @@ -44,18 +44,11 @@ JavaScript supports function overloads, where a function can have multiple signa
In some cases, type conversion will be required. Subtypes can safely be cast to their base type using conversion helpers within their module.

```ReScript
open WebAPI
open WebAPI.Global
// or WebAPI.DOM

let element: element = document->Document.createElement( ~localName = "div")
let node: node = element->Element.asNode
let element: WebAPI.Element.t = document->WebAPI.Document.createElement("div")
let node: WebAPI.Node.t = element->WebAPI.Element.asNode
```

Any other conversions can be performed using the `Base.unsafeConversation` helper. This should be done with caution, as it can lead to runtime errors.

```ReScript
open WebAPI

let element: element = document->Document.createElement( ~localName = "div")
// This is potentially unsafe, as the type system cannot guarantee the conversion
let divElement: htmlDivElement = element->Base.unsafeConversation
```
Any other conversions should be treated as unsafe casts and used with caution, because the type system cannot guarantee they are valid at runtime.
29 changes: 23 additions & 6 deletions docs/llm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from "node:path";
import { exec } from "node:child_process";
import { promisify } from "node:util";
import fs from "node:fs/promises";
import { featureSpecs, publicNameForLeafModule } from "../scripts/unmonorepo/feature-spec.mjs";

const execAsync = promisify(exec);

Expand Down Expand Up @@ -33,10 +34,7 @@ async function getDocJson(filePath) {
async function processFile(filePath) {
const json = await getDocJson(filePath);
const relativePath = path.relative(path.join(import.meta.dirname, ".."), filePath);
const parts = relativePath.split(path.sep);
const packageName = parts[1];
const leafName = path.basename(filePath, ".res");
const moduleName = leafName === "Types" ? packageName : `${packageName}.${leafName}`;
const moduleName = moduleNameForFile(relativePath);

const types = [];
const functions = [];
Expand Down Expand Up @@ -97,7 +95,26 @@ Module: ${moduleName}${typeString}${functionString}
`;
}

const pattern = "../packages/*/src/**/*.res";
const specByDir = new Map(featureSpecs.map((spec) => [spec.dirName, spec]));

function moduleNameForFile(relativePath) {
const [, dirName, fileName] = relativePath.split(path.sep);
const spec = specByDir.get(dirName);

if (!spec) {
throw new Error(`Unsupported source directory for documentation: ${relativePath}`);
}

const leafName = path.basename(fileName, ".res");

if (leafName === spec.publicModule) {
return `WebAPI.${spec.publicModule}`;
}

return `WebAPI.${spec.publicModule}.${publicNameForLeafModule(leafName, spec.internalPrefix)}`;
}

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));
Expand All @@ -109,7 +126,7 @@ const packageJson = await fs.readFile(path.join(import.meta.dirname, "../package
let version = JSON.parse(packageJson).version;
const sha = await execAsync("git rev-parse --short HEAD").then(({ stdout }) => stdout.trim());
const fullVersion = `${version}-experimental-${sha}`;
const header = `Experimental Rescript WebAPI Documentation ${fullVersion}
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/
Expand Down
Loading
Loading