/**
 * Add the capability to load CMD modules in node environment
 * @author lifesinger@gmail.com
 */

var fs = require("fs")
var path = require("path")
var vm = require("vm")
var moduleStack = []


runSeaJS("../dist/sea-debug.js")

hackNative()
attach()
keep()

seajs.cwd(process.cwd())


function runSeaJS(filepath) {
  var code = fs.readFileSync(path.join(__dirname, filepath), "utf8")
  code = code.replace("})(this);", "})(exports);")

  // Run "sea.js" code in a fake browser environment
  var sandbox = require("./sandbox")
  vm.runInNewContext(code, sandbox, "sea-debug.vm")

  global.seajs = sandbox.exports.seajs
  global.define = sandbox.exports.define
}

function hackNative() {
  var NodeModule = module.constructor
  var _load = NodeModule._load
  var _compile = NodeModule.prototype._compile

  NodeModule._load = function(request, parent, isMain) {
    var exports = _load(request, parent, isMain)

    var filename = NodeModule._resolveFilename(request, parent)
    var mod = seajs.cache[filename]

    if (mod) {
      var SeaModule = mod.constructor
      if (mod.status < SeaModule.STATUS.EXECUTING) {
        SeaModule.load(filename)
      }
      exports = NodeModule._cache[filename] = mod.exports
    }

    return exports
  }

  NodeModule.prototype._compile = function(content, filename) {
    moduleStack.push(filename)
    try {
      return _compile.call(this, content, filename)
    }
    finally {
      moduleStack.pop()
    }
  }
}

function attach() {
  seajs.on("request", requestListener)
}

function requestListener(data) {
  var requestUri =  pure(data.requestUri)
  var ext = path.extname(requestUri)
  //process.stdout.write("requestUri = " + requestUri + "\n")

  if (ext === ".js") {
    // Use native `require` instead of script-inserted version
    require(requestUri)
    data.callback()
    data.requested = true
  }
  // Throw error if this function is the last request handler
  else if (seajs.events["request"].length === 1) {
    throw new Error("Do NOT support to load this file in node environment: "
        + requestUri)
  }
}

function keep() {
  var _off = seajs.off

  seajs.off = function() {
    _off()
    attach()
    return seajs
  }
}

function pure(uri) {
  // Remove timestamp etc
  return uri.replace(/\?.*$/, "")
}


@@ -173,30 +173,8 @@
 m%22)%0A
-var moduleStack = %5B%5D%0A%0A
 %0Arun
@@ -634,24 +634,46 @@
 s.define%0A%7D%0A%0A
+var moduleStack = %5B%5D%0A%0A
 function hac
@@ -756,55 +756,8 @@
 load
-%0A  var _compile = NodeModule.prototype._compile
 %0A%0A  
@@ -981,46 +981,8 @@
 ) %7B%0A
-      var SeaModule = mod.constructor%0A
     
@@ -1004,25 +1004,25 @@
 s %3C 
-SeaModule.
+4) %7B // %3C 
 STATUS
-.
+_
 EXEC
@@ -1026,19 +1026,16 @@
 XECUTING
-) %7B
 %0A       
@@ -1039,31 +1039,38 @@
     
-SeaModule
+mod.constructor
 .load(
+%5B
 filename
 )%0A  
@@ -1061,24 +1061,40 @@
 ad(%5Bfilename
+%5D, function() %7B%7D
 )%0A      %7D%0A  
@@ -1180,16 +1180,64 @@
 ts%0A  %7D%0A%0A
+  var _compile = NodeModule.prototype._compile%0A%0A
   NodeMo
@@ -1313,24 +1313,20 @@
 ck.push(
-filename
+this
 )%0A    tr
@@ -1497,16 +1497,53 @@
 stener)%0A
+  seajs.on(%22define%22, defineListener)%0A
 %7D%0A%0Afunct
@@ -2062,16 +2062,16 @@
 ment: %22%0A
-
         
@@ -2083,32 +2083,144 @@
 uestUri)%0A  %7D%0A%7D%0A%0A
+function defineListener(data) %7B%0A  if (!data.uri) %7B%0A    data.uri = moduleStack%5BmoduleStack.length - 1%5D.id%0A  %7D%0A%7D%0A%0A
 function keep() 

Fix bugs in Node.js