Repository: facebook/react
File: packages/react-client/src/ReactFlightReplyClient.js (JavaScript)

Code before:
      return callServer(id, boundArgs.concat(args));
    }
    // Since this is a fake Promise whose .then doesn't chain, we have to wrap it.
    // TODO: Remove the wrapper once that's fixed.
    return ((Promise.resolve(p): any): Promise<Array<any>>).then(
      function (boundArgs) {
        return callServer(id, boundArgs.concat(args));
      },
    );
  };
  if (__DEV__) {
    const location = metaData.location;
    if (location) {
      const functionName = metaData.name || '';
      const [, filename, , , enclosingLine, enclosingCol] = location;
      const env = metaData.env || 'Server';
      const sourceMap =
        findSourceMapURL == null ? null : findSourceMapURL(filename, env);
      action = createFakeServerFunction(
        functionName,
        filename,
        sourceMap,
        enclosingLine,
        enclosingCol,
        env,
        action,
      );
    }
  }
  registerBoundServerReference(action, id, bound, encodeFormAction);
  return action;
}

// This matches either of these V8 formats.
//     at name (filename:0:0)
//     at filename:0:0
//     at async filename:0:0
const v8FrameRegExp =
  /^ {3} at (?:(.+) \((.+):(\d+):(\d+)\)|(?:async )?(.+):(\d+):(\d+))$/;
// This matches either of these JSC/SpiderMonkey formats.
// name@filename:0:0
// filename:0:0
const jscSpiderMonkeyFrameRegExp = /(?:(.*)@)?(.*):(\d+):(\d+)/;

function parseStackLocation(error: Error): null | ReactCallSite {
  // This parsing is special in that we know that the calling function will always
  // be a module that initializes the server action. We also need this part to work
  // cross-browser so not worth a Config. It's DEV only so not super code size
  // sensitive but also a non-essential feature.
  let stack = error.stack;
  if (stack.startsWith('Error: react-stack-top-frame\n')) {

Review comment (suggestion):
We want the fake function to be generated based on both like we do in `ReactFlightClient`. 

Right now this causes devtools to point to the beginning of the module since that's the enclosing line number of the `registerServerReference` call.

https://github.com/user-attachments/assets/2c9e29be-963c-49fe-b193-8ff7b5a775a3


Before this change we pointed at the declaration of `increment` since that's where `registerServerReference` call sourcemaps to:

```
1   | 'use server'
      ^ maps to 'use server'
      enclosing line number
      we don't want that
... |
29  | registerServerReference(increment, "...", "increment");
      ^ maps maps to `function increment() {}`
      line number
      we want that

```



Code after:
      return callServer(id, boundArgs.concat(args));
    }
    // Since this is a fake Promise whose .then doesn't chain, we have to wrap it.
    // TODO: Remove the wrapper once that's fixed.
    return ((Promise.resolve(p): any): Promise<Array<any>>).then(
      function (boundArgs) {
        return callServer(id, boundArgs.concat(args));
      },
    );
  };
  if (__DEV__) {
    const location = metaData.location;
    if (location) {
      const functionName = metaData.name || '';
      const [, filename, line, col] = location;
      const env = metaData.env || 'Server';
      const sourceMap =
        findSourceMapURL == null ? null : findSourceMapURL(filename, env);
      action = createFakeServerFunction(
        functionName,
        filename,
        sourceMap,
        line,
        col,
        env,
        action,
      );
    }
  }
  registerBoundServerReference(action, id, bound, encodeFormAction);
  return action;
}

// This matches either of these V8 formats.
//     at name (filename:0:0)
//     at filename:0:0
//     at async filename:0:0
const v8FrameRegExp =
  /^ {3} at (?:(.+) \((.+):(\d+):(\d+)\)|(?:async )?(.+):(\d+):(\d+))$/;
// This matches either of these JSC/SpiderMonkey formats.
// name@filename:0:0
// filename:0:0
const jscSpiderMonkeyFrameRegExp = /(?:(.*)@)?(.*):(\d+):(\d+)/;

function parseStackLocation(error: Error): null | ReactCallSite {
  // This parsing is special in that we know that the calling function will always
  // be a module that initializes the server action. We also need this part to work
  // cross-browser so not worth a Config. It's DEV only so not super code size
  // sensitive but also a non-essential feature.
  let stack = error.stack;
  if (stack.startsWith('Error: react-stack-top-frame\n')) {