new parse (v2)

Revision 2 of this benchmark created on


Setup

window.parseRequestInfoOld = function(requestPath) {
  const matches =
    requestPath.match(
      /[/]?(@[-_a-z-A-Z0-9.]+\/[-_a-z-A-Z0-9.]+|[a-zA-Z-0-9.]+)(@([-_a-zA-Z-0-9.]+))?(\/v([0-9.]+))?(\/(bundled|unbundled))?(\/[-_/a-zA-Z0-9.+]+)?/,
    ) || [];

  const packageName = matches[1] || '';
  const version = matches[3] || '';
  const bundled = (matches.length > 8 && matches[7]) === 'bundled';
  const filePath = (matches.length > 8 && matches[8]) || '';

  return {
    packageName,
    version,
    bundled,
    filePath,
  };
}

window.parseRequestInfoNew = function(requestPath) {
  let packageName = '';
  let version = '';
  let bundled = false;
  let filePath = '';
  let pathname;
  
  try {
    // Convert to a full URL if needed to make a URL object.
    // (The URL constructor handles slash and path segment normalization if needed.)
    requestPath = requestPath.includes('://') ? requestPath : `http://localhost/${requestPath}`;
    pathname = new URL(requestPath).pathname;
  } catch (err) {
    console.warn(`Invalid URL received by parseRequestInfo: ${requestPath}`);
    return { packageName, version, bundled, filePath };
  }

  // get the path segments and remove leading and trailing slashes
  const segments = pathname.split('/');
  segments.shift(); // URL's pathname always starts with a slash
  if (segments[segments.length - 1] === '') segments.pop();

  if (segments.length) {
    // if the first segment starts with an `@`, it's a scope
    const scope = segments[0].match(/^@[\w.-]+$/) ? segments.shift() + '/' : '';
    // the next segment is the package name, optionally followed by `@version`
    // (the regex uses named capture groups)
    const packageMatch = segments.shift()?.match(/^(?<unscopedName>[\w.-]+)(@(?<version>[\w.-]+))?$/);

    if (packageMatch?.groups) {
      packageName = scope + packageMatch.groups.unscopedName;
      version = packageMatch.groups.version || '';

      // remove the optional refresh version segment, e.g. v3.2
      if (/^v[\d.]+$/.test(segments[0] || '')) {
        segments.shift();
      }

      // optional bundled/unbundled segment
      if (segments[0] === 'bundled' || segments[0] === 'unbundled') {
        bundled = segments.shift() === 'bundled';
      }

      // the rest is the file path
      if (segments.length) {
        filePath = '/' + segments.join('/');
      }
    }
  }

  return { packageName, version, bundled, filePath };
}

Test runner

Ready to run.

Testing in
TestOps/sec
Test old
parseRequestInfoOld('@foo/bar@1.1.1/bundled/a/b/c')
ready
Test new
parseRequestInfoNew('@foo/bar@1.1.1/bundled/a/b/c')
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.