Skip to content

fix: remove legacy assert#46068

Open
unional wants to merge 2 commits into
nodejs:mainfrom
unional:patch-1
Open

fix: remove legacy assert#46068
unional wants to merge 2 commits into
nodejs:mainfrom
unional:patch-1

Conversation

@unional

@unional unional commented Jan 3, 2023

Copy link
Copy Markdown

fixes #46050

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/loaders
  • @nodejs/modules

@nodejs-github-bot nodejs-github-bot added doc Issues and PRs related to the documentations. esm Issues and PRs related to the ECMAScript Modules implementation. labels Jan 3, 2023
as now they always have `*`
@JakobJingleheimer

Copy link
Copy Markdown
Member

Hiya! Thanks for the contribution!

I'm not sure this is complete though: from the title, it sounds like an actual algorithm would be updated, but this only updates the spec.

@unional

unional commented Jan 3, 2023

Copy link
Copy Markdown
Author

The actual implementation is here:

function patternKeyCompare(a, b) {
  const aPatternIndex = StringPrototypeIndexOf(a, '*');
  const bPatternIndex = StringPrototypeIndexOf(b, '*');
  const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1;
  const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1;
  if (baseLenA > baseLenB) return -1;
  if (baseLenB > baseLenA) return 1;
  if (aPatternIndex === -1) return 1;
  if (bPatternIndex === -1) return -1;
  if (a.length > b.length) return -1;
  if (b.length > a.length) return 1;
  return 0;
}

It does not do any assertion.

I can simplify the logic to:

function patternKeyCompare(a, b) {
  const aPatternIndex = StringPrototypeIndexOf(a, '*');
  const bPatternIndex = StringPrototypeIndexOf(b, '*');
  const baseLenA = aPatternIndex + 1;
  const baseLenB = bPatternIndex + 1;
  if (baseLenA > baseLenB) return -1;
  if (baseLenB > baseLenA) return 1;
  if (a.length > b.length) return -1;
  if (b.length > a.length) return 1;
  return 0;
}

But that would be a breaking change as I don't know if there are code out there hits the non-asserted cases.

So should I change it?

@unional

unional commented Jan 3, 2023

Copy link
Copy Markdown
Author

In pattern-key-compare, I'm implementing it with assertions:

export function patternKeyCompare(keyA: string, keyB: string) {
  const iA = keyA.indexOf('*')
  const iB = keyB.indexOf('*')
  assert(iA !== -1, `'${keyA}' does not contain '*'`)
  assert(iB !== -1, `'${keyB}' does not contain '*'`)
  assert(keyA.lastIndexOf('*') === iA, `'${keyA}' has more than one '*'`)
  assert(keyB.lastIndexOf('*') === iB, `'${keyB}' has more than one '*'`)
  const baseLengthA = iA + 1
  const baseLengthB = iB + 1
  if (baseLengthA > baseLengthB) return -1
  if (baseLengthA < baseLengthB) return 1
  return keyA.length > keyB.length ? -1 : keyA.length < keyB.length ? 1 : 0
}

@unional

unional commented Jan 3, 2023

Copy link
Copy Markdown
Author

Or, I can at least add some comments there to indicate the code supports a legacy/deprecated algorithm

@unional

unional commented Jan 3, 2023

Copy link
Copy Markdown
Author

btw, I have a question about the conditions in the algorithm.

The code in Node.js and in resolve.exports both uses Set<string>.

Which does not handle:

{
  "exports": {
    "node": {
      "import": "./a.js"
    },
    "import": {
      "node": "./b.js"
     }
  }
}

Is that intentional or is that a bug or limitation due to legacy implementation?

@aduh95

aduh95 commented Apr 13, 2023

Copy link
Copy Markdown
Contributor

@nodejs/loaders we should review this.

@GeoffreyBooth

Copy link
Copy Markdown
Member

Cc @guybedford

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc Issues and PRs related to the documentations. esm Issues and PRs related to the ECMAScript Modules implementation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PATTERN_KEY_COMPARE algorithm should be updated

5 participants