Skip to content

Commit d442623

Browse files
tsnobipjderochervlkcodex
authored
Split webAPI into multiple subpackages (#249)
* clean types in Prelude * split into subpackages * add back getter functions for Window * move back Navigator to DOM * remove globals package * delete files that should not be versioned * add some more typealiases in DOM/Types * format * delete JS files * format package.json * fix docs generation * change namespace to `@rescript/webapi-[section]` * publish all subpackages in CI * refactor: carry over post-monorepo pre-alpha cleanup (#252) * refactor: carry over post-monorepo pre-alpha cleanup Port the surviving API cleanup from the final pre-alpha branch onto the monorepo split introduced in #249. This adds the missing concrete modules, translates the fetch/runtime/canvas/websocket/media surface cleanup into the package layout, and keeps the branch green with updated tests. * refactor(DOM): remove numeric scroll overloads Drop scroll2/scrollTo2/scrollBy2 and keep the descriptive *XY overload names requested in review. Co-authored-by: Codex <codex@openai.com> --------- Co-authored-by: Codex <codex@openai.com> * format * simplify FOrmDataEntryValue type * clean alert and postMessage * fix CI * remove useless namespace * mark bindings of classes/interfaces as private records to prevent creation records that have mutable fields were not marked as private for now because mutating these mutable fields is not allowed * format * add missing getters for Navigator * add Window.t type --------- Co-authored-by: Josh Vlk <josh@vlkpack.com> Co-authored-by: Codex <codex@openai.com>
1 parent 61b1074 commit d442623

1,070 files changed

Lines changed: 28288 additions & 27357 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: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,62 @@ jobs:
5656
id: vars
5757
run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
5858

59-
- name: Update version to -<commit-hash>
60-
run: npm version --no-git-tag-version "${{ steps.package-version.outputs.current-version }}-experimental-${{ env.COMMIT_HASH }}"
61-
62-
- name: Package npm project
63-
run: npm pack
59+
- name: Update workspace versions to -<commit-hash>
60+
env:
61+
PACKAGE_VERSION: ${{ steps.package-version.outputs.current-version }}-experimental-${{ env.COMMIT_HASH }}
62+
run: |
63+
node <<'NODE'
64+
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+
}
94+
NODE
95+
96+
- name: Package npm workspaces
97+
run: npm pack --workspaces
6498

6599
- name: Upload npm package artifact
66100
uses: actions/upload-artifact@v7
67101
with:
68-
name: npm-package
102+
name: npm-packages
69103
path: "*.tgz"
70104

71-
- name: Publish to npm
105+
- name: Publish npm packages
72106
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
73107
env:
74108
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
75-
run: npm publish --access public ./*.tgz --tag experimental
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
76115
77116
deploy-docs:
78117
needs: build

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,12 @@ dist/
66
tmp/
77
docs/public/llm.txt
88
*~
9+
10+
**/lib/bs/
11+
**/lib/ocaml
12+
13+
.DS_Store
14+
15+
rescript.lock
16+
17+
**/*.res.js

docs/llm.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ async function getDocJson(filePath) {
3232

3333
async function processFile(filePath) {
3434
const json = await getDocJson(filePath);
35-
36-
const moduleName = "WebAPI." + json.name.replace("-WebAPI", "");
35+
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}`;
3740

3841
const types = [];
3942
const functions = [];
@@ -89,12 +92,12 @@ async function processFile(filePath) {
8992
functionString = "\n\nFunctions:\n\n" + functions.join("\n\n");
9093
}
9194

92-
return `File: ${json.source.filepath}
95+
return `WebApiFile: ${json.source.filepath}
9396
Module: ${moduleName}${typeString}${functionString}
9497
`;
9598
}
9699

97-
const pattern = "../src/**/*.res";
100+
const pattern = "../packages/*/src/**/*.res";
98101
const files = [];
99102
for await (const file of fs.glob(pattern, { recursive: true, cwd: import.meta.dirname })) {
100103
files.push(path.join(import.meta.dirname, file));

docs/utils.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ export function createTypeModuleLink(parentModuleLink, typeName) {
2424
}
2525

2626
function mapTypeModules(parentModuleLink, file) {
27-
const folder = file.replace(".res", "");
27+
const folder = path.dirname(file);
2828

2929
if (!existsSync(folder)) {
3030
return [];
3131
}
3232

3333
const files = readdirSync(folder);
3434
return files
35-
.filter((f) => f.endsWith(".res"))
35+
.filter((f) => f.endsWith(".res") && f !== "Types.res")
3636
.map((file) => {
3737
const filePath = path.join(folder, file);
3838

39-
const moduleName = file.replace("$", "").replace(folder, "").replace(".res", "");
39+
const moduleName = file.replace("$", "").replace(".res", "");
4040
const apiRouteParameter = toKebabCase(moduleName);
4141
const link = createTypeModuleLink(parentModuleLink, moduleName);
4242
const typeName = moduleName[0].toLocaleLowerCase() + moduleName.slice(1);
@@ -54,8 +54,8 @@ function mapTypeModules(parentModuleLink, file) {
5454
}
5555

5656
function mapRescriptFile(srcDir, file) {
57-
const moduleName = path.basename(file, ".res").replace("$", "");
5857
const filePath = path.join(srcDir, file);
58+
const moduleName = path.basename(path.dirname(srcDir)).replace("$", "");
5959
const link = createAPIModuleLink(moduleName);
6060
const items = Object.fromEntries(mapTypeModules(link, filePath));
6161

@@ -68,10 +68,13 @@ function mapRescriptFile(srcDir, file) {
6868
};
6969
}
7070

71-
const srcDir = path.resolve(process.cwd(), "src");
72-
export const apiModules = readdirSync(srcDir)
73-
.filter((f) => f.endsWith(".res"))
74-
.map((r) => mapRescriptFile(srcDir, r));
71+
const packagesDir = path.resolve(process.cwd(), "packages");
72+
export const apiModules = readdirSync(packagesDir, { withFileTypes: true })
73+
.filter((entry) => entry.isDirectory())
74+
.map((entry) => path.join(packagesDir, entry.name, "src"))
75+
.filter((srcDir) => existsSync(path.join(srcDir, "Types.res")))
76+
.map((srcDir) => mapRescriptFile(srcDir, "Types.res"))
77+
.sort((a, b) => a.moduleName.localeCompare(b.moduleName));
7578

7679
async function getRescriptDoc(absoluteFilePath) {
7780
const { stdout, stderr } = await execAsync(`rescript-tools doc ${absoluteFilePath}`, {
@@ -149,11 +152,11 @@ export const testFiles = readdirSync(testDir, { recursive: true })
149152
.map((tf) => {
150153
const sourcePath = path.join(testDir, tf);
151154
const source = readFileSync(sourcePath, "utf-8");
152-
const outputPath = sourcePath.replace(".res", ".js");
155+
const outputPath = sourcePath.replace(".res", ".res.js");
153156
const output = readFileSync(outputPath, "utf-8");
154157

155158
const parts = tf.split(path.sep);
156-
const name = parts[parts.length - 1].replace("__tests.res", "");
159+
const name = parts[parts.length - 1].replace(".res", "");
157160

158161
return {
159162
sourcePath: sourcePath.replace(testDir, ""),

0 commit comments

Comments
 (0)