Skip to content

refactor: clean up public owners and singleton APIs#270

Draft
jderochervlk wants to merge 35 commits into
mainfrom
vlk/base
Draft

refactor: clean up public owners and singleton APIs#270
jderochervlk wants to merge 35 commits into
mainfrom
vlk/base

Conversation

@jderochervlk

@jderochervlk jderochervlk commented May 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR continues the WebAPI package split by moving object ownership toward public leaf modules and making global/singleton APIs callable directly from their leaf modules.

// before: get the host object and pass it to the module function
let before = Dom.crypto->Crypto.randomUUID

// after: call the leaf API directly
let after = Crypto.randomUUID()

The package now models focused feature relationships in rescript.json, removes the residual DOMExtended source bucket, and keeps public modules registered through source public lists. Consumers can depend on narrower feature slices instead of compiling the whole DOM/WebAPI surface.

{
  "dependencies": [
    {
      "name": "@rescript/webapi",
      "features": ["WebAPI.Crypto", "WebAPI.Location"]
    }
  ]
}

Public Owner Cleanup

  • Moved many public object APIs toward local type t ownership and pipeable @send functions.
  • Added scripts/audit-method-style.mjs and tests/unmonorepo/method-style.test.mjs to track remaining type-bucket method receivers.
  • Removed DOMExtended in favor of explicit leaf source directories and feature dependencies.
  • Kept follow-up work in one active plan: docs/superpowers/plans/2026-06-09-public-owner-follow-ups.md.

Event And DOM Shape

  • Keeps DOM, Event, and EventTarget interoperable through shared hidden base owners.
  • Keeps DOM.event opaque and exposes event behavior through Event getters.
  • Keeps the DOM feature thin for React-oriented consumers while moving broader API behavior to leaf features.

Testing

Passed locally during this branch:

  • npm run build
  • npm test
  • npm run format:check
  • node_modules/.bin/rescript build --features WebAPI.DOM --prod
  • node_modules/.bin/rescript build --features WebAPI.Event --prod
  • node_modules/.bin/rescript build --features WebAPI.Fetch --prod
  • node_modules/.bin/rescript build --features WebAPI.File --prod
  • node_modules/.bin/rescript build --features WebAPI.CredentialManagement --prod
  • node_modules/.bin/rescript build --features WebAPI.Notification --prod
  • node_modules/.bin/rescript build --features WebAPI.Push --prod
  • node_modules/.bin/rescript build --features WebAPI.Locks --prod

@jderochervlk jderochervlk marked this pull request as draft May 20, 2026 14:23
@jderochervlk

Copy link
Copy Markdown
Collaborator Author

@codex

@jderochervlk jderochervlk marked this pull request as ready for review May 30, 2026 15:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49420e4362

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/WebCrypto/Crypto.res Outdated
@jderochervlk jderochervlk marked this pull request as draft May 30, 2026 15:38
@jderochervlk jderochervlk changed the title refactor: move DOM file out of base folder refactor: split DOM bindings into focused feature modules May 30, 2026
@jderochervlk jderochervlk marked this pull request as ready for review May 30, 2026 15:38
@jderochervlk

Copy link
Copy Markdown
Collaborator Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c526dd58cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/WebCrypto/Crypto.res Outdated
@jderochervlk jderochervlk requested review from brnrdog and tsnobip May 31, 2026 13:35

@tsnobip tsnobip left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rest looks ok to me but I have two main comments on the general structure

Comment thread src/DOM/DOM.res Outdated
Comment thread src/Base/Base.res Outdated
@jderochervlk jderochervlk requested a review from tsnobip June 2, 2026 00:48

@tsnobip tsnobip left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I re-reviewed it, and really I don't understand this PR, we had quite a nice structure where DOM was in base package, this way we could make rescript-react and other dependencies depend on DOM.element for example, now it would depend on Base.Element.element and these types are not really usable anymore given they use abstract types that are duplicated.

Comment thread src/DOM/DomTypes.res Outdated
Comment thread src/Base/Base__Document.res Outdated
Comment on lines +3 to +7
type node
type htmlElement
type nodeList<'tNode>
type domImplementation
type documentType

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get this, why do we redefine those as abstract types?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't, I am cleaning this up.

Comment thread src/Base/Base__Element.res Outdated
Comment thread src/Base/Base__Element.res Outdated
Comment thread src/Base/Base__Document.res Outdated
Comment thread src/DOM/DOM.res Outdated
@jderochervlk jderochervlk marked this pull request as draft June 2, 2026 15:30
Comment thread src/DOM/Document.res Outdated
Comment on lines +14 to +15
@scope("globalThis.document")
external getElementById: string => null<DomTypes.element> = "getElementById"

@brnrdog brnrdog Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason getElementById is the only Document method scoped to globalThis.document? Everything else in this module is still @send.

This means iframeDocument->Document.getElementById(id) would break, since it always reads from the global doc (so no iframes/XML docs, for example). Should we keep using @send for flexibility?

@jderochervlk jderochervlk Jun 2, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal is to rely on @scope instead of @send. This means you can avoid having to get the object and pipe it to a function and then you can just call the functions directly on the module, but I am not sure that will actually work in practice for everything.

It depends really on what we want the public API to be.

let e: Event.t = {}

let value = e->Event.target

// or
let e: Event.t = {
  target: /* */
}
let value = e.target

Comment thread docs/content/docs/contributing/api-module-structure.mdx Outdated
Comment on lines +80 to +82

`Element.res` is a method module. It does not define the `element` record type directly. The shared DOM element type is owned by Base and threaded back into DOM through aliases:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not 100% on this one. It is similar to how the old webapi bindings worked and does not expose keys on an object and instead relies on piping to access values using @get or @send.

This means you have to do this:

let title = element->Element.title

instead of this:

let title = element.title

By using the pipe option we can have the types not required by other libraries such as rescript-react which can make it more lightweight, but if Event and Element are lightweight enough I don't see why they can't be a requirement of rescript-react?


location->WebAPI.Location.reload
WebAPI.Location.reload()
```

@jderochervlk jderochervlk Jun 3, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use a simpler way to get the location instead of using current. I don't know how I feel about that pattern actually, but I suppose we need some way to pass around location? I actually don't know why you would need to do that...

let href = WebAPI.Location.href

WebAPI.Location.reload()

With `"-open WebAPI"`, the same modules can be referenced without the `WebAPI.` prefix:

```ReScript
let location = Location.current

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how I feel about that pattern actually, but I suppose we need some way to pass around location? I actually don't know why you would need to do that...

jderochervlk and others added 2 commits June 3, 2026 12:20
* refactor: establish option 2 DOM API shape

* docs: document option 2 DOM API shape

* refactor: remove DOM compatibility aliases

* fix: expose document APIs through Document.t

* fix: include DOM owner modules in DOM feature

* fix: shrink DOM feature for React consumers

* Simplify internal feature groups

* Address PR review for shared DOM base types

* Add method style audit plan

* Move CanvasRenderingContext2D methods to public receiver

* Move DOMExtended methods to public receivers

* Move IndexedDB methods to public receivers

* Move Window methods to public receiver

* Move Canvas methods to public receivers

* Move DOM utility methods to public receivers

* Move HTML methods to public receivers

* working with AI and it's not doing great

* fix DOM casing and cleanup CSSStyleSheet

* remove DomExtended

* Rename DOMTypes module to DOM

---------

Co-authored-by: Codex <codex@openai.com>
@jderochervlk jderochervlk changed the title refactor: split DOM bindings into focused feature modules refactor: clean up public owners and singleton APIs Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants