Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(compartment-mapper): fix ReadPowers-related types #2188

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

boneskull
Copy link
Collaborator

@boneskull boneskull commented Mar 28, 2024

Description

This change:

  1. Creates a minimal interface for the fs, url, and crypto objects as passed into makeReadPowers(). This makes it easier to duck-type the objects. The drawback here is that it is not future-proof, and these types will need to be updated if we end up using additional methods on these objects.
  2. Fixes the invalid type of MaybeReadPowers; properties (defined thru @property) are ignored in a @typedef of that @typedef does not extend object/Object.
  3. Added necessary type assertion in powers.js
  4. Adds return type to makeReadPowersSloppy()

Upgrade Considerations

This is a type-only change.

This change:

1. Creates a minimal interface for the `fs`, `url`, and `crypto` objects as passed into `makeReadPowers()`. This makes it easier to duck-type the objects.
2. Fixes the invalid type of `MaybeReadPowers`; properties (defined thru `@property`) are ignored in a `@typedef` of that `@typedef` does not extend `object`/`Object`.
3. Added necessary type assertion in `powers.js`
4. Adds return type to `makeReadPowersSloppy()`

# Conflicts:
#	packages/compartment-mapper/src/types.js
@boneskull
Copy link
Collaborator Author

boneskull commented Mar 28, 2024

Comment on lines +33 to +35
* @param {import('./types.js').FsAPI} args.fs
* @param {import('./types.js').UrlAPI} [args.url]
* @param {import('./types.js').CryptoAPI} [args.crypto]
Copy link
Member

Choose a reason for hiding this comment

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

I’m a tiny bit worried that, if we need more powers from these modules, reaching them going forward will constitute a breaking change. Is it possible to address your concerns without narrowing these types?

Copy link
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 see it as possible to do without breaking things, no. But currently, we're asking for way more than we need to.

I'd even be amenable to ditching these objects entirely, and asking for the specific functions in isolation--i.e., instead of discrete fs, url and crypto objects, we'd ask for a bucket of functions matching what we need.

Copy link
Member

Choose a reason for hiding this comment

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

I’m with you on principle of least authority but not aligned on resilience to change. This is a tool for attenuating the Node.js builtins down to the powers the compartment mapper already needs. The powers space is very narrowly scoped and any new powers have to be optional and have backward-compatible fallbacks. The attenuator however benefits from being able to reach for more powers as needed to upgrade gracefully. Last time we needed this, it was to reach for fs.realpath in order to canonicalize. I hope the dependencies for compartment mapper are stable, but I’m not sure.

@@ -18,7 +18,8 @@ export const unpackReadPowers = powers => {
if (typeof powers === 'function') {
read = powers;
} else {
({ read, maybeRead, canonical } = powers);
({ read, maybeRead, canonical } =
/** @type {import('./types.js').MaybeReadPowers} */ (powers));
Copy link
Member

Choose a reason for hiding this comment

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

Cool.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this is actually MaybeReadPowers | ReadPowers, but we don't know until L29

@@ -165,8 +165,7 @@ export {};
*/

/**
* @typedef {ReadPowers | object} MaybeReadPowers
* @property {MaybeReadFn} maybeRead
* @typedef {ReadPowers & {maybeRead: MaybeReadFn}} MaybeReadPowers
Copy link
Member

Choose a reason for hiding this comment

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

The old pattern broken in general? Used to be vogue.

Copy link
Collaborator Author

@boneskull boneskull Mar 29, 2024

Choose a reason for hiding this comment

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

I don't recall that ever working. To combine types in a @typedef, I've always needed to use intersections or something akin to type-fest's Merge.

As written, it looks like it might work (it does not), but for the wrong reasons--afaict ReadPowers | object simplifies to object.

@boneskull boneskull self-assigned this Apr 1, 2024
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.

None yet

2 participants