Skip to content

Commit f1dd992

Browse files
committed
refactor: unmonorepo webapi package
1 parent 2e1b997 commit f1dd992

376 files changed

Lines changed: 3550 additions & 2991 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -56,62 +56,32 @@ jobs:
5656
id: vars
5757
run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
5858

59-
- name: Update workspace versions to -<commit-hash>
59+
- name: Update package version to -<commit-hash>
6060
env:
6161
PACKAGE_VERSION: ${{ steps.package-version.outputs.current-version }}-experimental-${{ env.COMMIT_HASH }}
6262
run: |
6363
node <<'NODE'
6464
const fs = require("node:fs");
65-
const path = require("node:path");
66-
67-
const packagesDir = path.join(process.cwd(), "packages");
68-
const version = process.env.PACKAGE_VERSION;
69-
const packages = fs
70-
.readdirSync(packagesDir)
71-
.filter((dir) => fs.existsSync(path.join(packagesDir, dir, "package.json")))
72-
.map((dir) => {
73-
const packageJsonPath = path.join(packagesDir, dir, "package.json");
74-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
75-
return { packageJsonPath, packageJson };
76-
});
77-
const workspaceNames = new Set(packages.map(({ packageJson }) => packageJson.name));
78-
79-
for (const { packageJsonPath, packageJson } of packages) {
80-
packageJson.version = version;
81-
82-
for (const field of ["dependencies", "peerDependencies", "devDependencies"]) {
83-
if (!packageJson[field]) continue;
84-
85-
for (const dependencyName of Object.keys(packageJson[field])) {
86-
if (workspaceNames.has(dependencyName)) {
87-
packageJson[field][dependencyName] = version;
88-
}
89-
}
90-
}
91-
92-
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
93-
}
65+
const packageJsonPath = "package.json";
66+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
67+
packageJson.version = process.env.PACKAGE_VERSION;
68+
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
9469
NODE
9570
96-
- name: Package npm workspaces
97-
run: npm pack --workspaces
71+
- name: Package npm package
72+
run: npm pack
9873

9974
- name: Upload npm package artifact
10075
uses: actions/upload-artifact@v7
10176
with:
10277
name: npm-packages
10378
path: "*.tgz"
10479

105-
- name: Publish npm packages
80+
- name: Publish npm package
10681
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
10782
env:
10883
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
109-
run: |
110-
for package in packages/*; do
111-
if [ -f "$package/package.json" ]; then
112-
npm publish --workspace "$package" --access public --tag experimental
113-
fi
114-
done
84+
run: npm publish --access public --tag experimental
11585

11686
deploy-docs:
11787
needs: build

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
dist/
66
tmp/
77
docs/public/llm.txt
8+
.npm-cache/
9+
*.tgz
810
*~
911
.worktrees/
1012

@@ -15,4 +17,6 @@ docs/public/llm.txt
1517

1618
rescript.lock
1719

20+
src/**/*.js
21+
tests/**/*.js
1822
**/*.res.js

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ and add `@rescript/webapi` to your `rescript.json`:
1717
```json
1818
{
1919
"bs-dependencies": [
20-
+ "@rescript/webapi",
20+
"@rescript/webapi"
2121
],
2222
"bsc-flags": [
23-
+ "-open WebAPI.Global"
23+
"-open WebApi.DOM.Global"
2424
]
2525
}
2626
```

docs/content/docs/contributing/api-modelling.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ mutable fillStyle: fillStyle
8888
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:
8989

9090
export const fillStyleModule = `
91-
open WebApiCanvas
92-
open WebApiDOM
91+
open WebApi.Canvas
92+
open WebApi.DOM
9393
9494
external fromString: string => fillStyle = "%identity"
9595
external fromCanvasGradient: canvasGradient => fillStyle = "%identity"

docs/content/docs/contributing/getting-started.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { Aside } from "@astrojs/starlight/components";
1111
upside? It’s stupid easy to toss us a PR and make it better!
1212
</Aside>
1313

14-
The [WebAPI](https://developer.mozilla.org/en-US/docs/Web/API) are vast and ever-growing. We need your help to make them better.
14+
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.
1515
There is no way our [contributors](https://github.com/rescript-lang/experimental-rescript-webapi/graphs/contributors) can cover everything.
1616
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.
1717

docs/content/docs/index.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Getting started
33
description: Learn more about @rescript/webapi.
44
hero:
5-
title: "ReScript WebAPI"
5+
title: "ReScript WebApi"
66
tagline: ReScript bindings for everything you need in the browser.
77
actions:
88
- text: Let's go!
@@ -39,10 +39,10 @@ and add `@rescript/webapi` to your `rescript.json`:
3939
export const rescriptJson = `
4040
{
4141
"bs-dependencies": [
42-
"@rescript/webapi",
42+
"@rescript/webapi"
4343
],
4444
"bsc-flags": [
45-
"-open WebAPI.Global"
45+
"-open WebApi.DOM.Global"
4646
]
4747
}
4848
`;
@@ -54,14 +54,14 @@ export const rescriptJson = `
5454
After installing the package , you can use bindings for the various Web APIs as defined in [MDN](https://developer.mozilla.org/en-US/docs/Web/API).
5555

5656
export const rescriptSample = `
57-
// Note that this only works when you added the \`-open WebAPI.Global\` bsc flag.
57+
// Note that this only works when you added the \`-open WebApi.DOM.Global\` bsc flag.
5858
let location = window.location
5959
6060
// Access properties using \`.\`
6161
let href = location.href
6262
6363
// Invoke methods using the \`->TypeModule.method\`
64-
location->Location.reload
64+
location->WebApi.DOM.Location.reload
6565
`;
6666

6767
export const compiledSample = `

docs/content/docs/philosophy.mdx

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ The bindings are generated from the [MDN Web API documentation](https://develope
1616

1717
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.
1818

19-
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.
19+
Each feature is grouped under a `WebApi.<Feature>` module so related interfaces and helper modules stay together without relying on flat package-wide names.
2020

2121
```ReScript
22-
open WebAPI.Global
23-
open WebAPI.DOMAPI
22+
open WebApi.DOM.Global
2423
25-
let myElement: element = document->Document.createElement( ~localName = "div")
24+
let myElement: WebApi.DOM.Types.element = document->WebApi.DOM.Document.createElement("div")
2625
```
2726

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

4645
```ReScript
47-
open WebAPI
46+
open WebApi.DOM.Global
4847
49-
let element: element = document->Document.createElement( ~localName = "div")
50-
let node: node = element->Element.asNode
48+
let element: WebApi.DOM.Types.element = document->WebApi.DOM.Document.createElement("div")
49+
let node: WebApi.DOM.Types.node = element->WebApi.DOM.Element.asNode
5150
```
5251

53-
Any other conversions can be performed using the `Base.unsafeConversation` helper. This should be done with caution, as it can lead to runtime errors.
54-
55-
```ReScript
56-
open WebAPI
57-
58-
let element: element = document->Document.createElement( ~localName = "div")
59-
// This is potentially unsafe, as the type system cannot guarantee the conversion
60-
let divElement: htmlDivElement = element->Base.unsafeConversation
61-
```
52+
Any other conversions should be treated as unsafe casts and used with caution, because the type system cannot guarantee they are valid at runtime.

docs/llm.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as path from "node:path";
22
import { exec } from "node:child_process";
33
import { promisify } from "node:util";
44
import fs from "node:fs/promises";
5+
import { featureSpecs, publicNameForLeafModule } from "../scripts/unmonorepo/feature-spec.mjs";
56

67
const execAsync = promisify(exec);
78

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

4139
const types = [];
4240
const functions = [];
@@ -97,7 +95,26 @@ Module: ${moduleName}${typeString}${functionString}
9795
`;
9896
}
9997

100-
const pattern = "../packages/*/src/**/*.res";
98+
const specByDir = new Map(featureSpecs.map((spec) => [spec.dirName, spec]));
99+
100+
function moduleNameForFile(relativePath) {
101+
const [, dirName, fileName] = relativePath.split(path.sep);
102+
const spec = specByDir.get(dirName);
103+
104+
if (!spec) {
105+
throw new Error(`Unsupported source directory for documentation: ${relativePath}`);
106+
}
107+
108+
const leafName = path.basename(fileName, ".res");
109+
110+
if (leafName === spec.publicModule) {
111+
return `WebApi.${spec.publicModule}`;
112+
}
113+
114+
return `WebApi.${spec.publicModule}.${publicNameForLeafModule(leafName, spec.internalPrefix)}`;
115+
}
116+
117+
const pattern = "../src/*/**/*.res";
101118
const files = [];
102119
for await (const file of fs.glob(pattern, { recursive: true, cwd: import.meta.dirname })) {
103120
files.push(path.join(import.meta.dirname, file));
@@ -109,9 +126,9 @@ const packageJson = await fs.readFile(path.join(import.meta.dirname, "../package
109126
let version = JSON.parse(packageJson).version;
110127
const sha = await execAsync("git rev-parse --short HEAD").then(({ stdout }) => stdout.trim());
111128
const fullVersion = `${version}-experimental-${sha}`;
112-
const header = `Experimental Rescript WebAPI Documentation ${fullVersion}
129+
const header = `Experimental ReScript WebApi Documentation ${fullVersion}
113130
114-
This is the API documentation for the experimental WebAPI module version ${fullVersion}.
131+
This is the API documentation for the experimental WebApi module version ${fullVersion}.
115132
More information can be found on https://rescript-lang.github.io/experimental-rescript-webapi/
116133
117134
`;

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
2-
"name": "experimental-rescript-webapi",
2+
"name": "@rescript/webapi",
33
"version": "0.1.0",
4-
"private": true,
54
"description": "Experimental successor to [rescript-webapi](https://github.com/TheSpyder/rescript-webapi)",
65
"keywords": [
76
"dom",
@@ -23,8 +22,11 @@
2322
"type": "git",
2423
"url": "git+https://github.com/rescript-lang/experimental-rescript-webapi.git"
2524
},
26-
"workspaces": [
27-
"packages/*"
25+
"files": [
26+
"rescript.json",
27+
"src/**/*.res",
28+
"src/**/*.resi",
29+
"README.md"
2830
],
2931
"type": "module",
3032
"publishConfig": {
@@ -34,11 +36,9 @@
3436
"scripts": {
3537
"test": "node tests/index.js",
3638
"build": "rescript",
37-
"build:packages": "npm run build --workspaces --if-present",
3839
"format": "rescript format && oxfmt ./tests/index.js ./package.json ./docs && prettier --write ./docs/pages",
3940
"format:check": "rescript format --check && oxfmt ./tests/index.js ./package.json ./docs --check && prettier --check ./docs/pages",
4041
"docs": "astro dev",
41-
"create:npm-packages": "node scripts/create-npm-packages.js",
4242
"prebuild:docs": "node docs/llm.js",
4343
"build:docs": "astro build"
4444
},

0 commit comments

Comments
 (0)