<commit_before>#     NoFlo - Flow-Based Programming for JavaScript
#     (c) 2013 The Grid
#     (c) 2011-2012 <NAME>, Nemein
#     NoFlo may be freely distributed under the MIT license
#
# NoFlo graphs are Event Emitters, providing signals when the graph
# definition changes.
#
# On Node.js we use the build-in EventEmitter implementation
unless require('./Platform').isBrowser()
  {EventEmitter} = require 'events'
# On browser we use Component's EventEmitter implementation
else
  EventEmitter = require 'emitter'

# This class represents an abstract NoFlo graph containing nodes
# connected to each other with edges.
#
# These graphs can be used for visualization and sketching, but
# also are the way to start a NoFlo network.
class Graph extends EventEmitter
  name: ''
  properties: {}
  nodes: []
  edges: []
  initializers: []
  exports: []
  inports: {}
  outports: {}
  groups: []

  # ## Creating new graphs
  #
  # Graphs are created by simply instantiating the Graph class
  # and giving it a name:
  #
  #     myGraph = new Graph 'My very cool graph'
  constructor: (@name = '') ->
    @properties = {}
    @nodes = []
    @edges = []
    @initializers = []
    @exports = []
    @inports = {}
    @outports = {}
    @groups = []
    @transaction =
      id: null
      depth: 0

  # ## Group graph changes into transactions
  #
  # If no transaction is explicitly opened, each call to
  # the graph API will implicitly create a transaction for that change
  startTransaction: (id, metadata) ->
    if @transaction.id
      throw Error("Nested transactions not supported")

    @transaction.id = id
    @transaction.depth = 1
    @emit 'startTransaction', id, metadata

  endTransaction: (id, metadata) ->
    if not @transaction.id
      throw Error("Attempted to end non-existing transaction")

    @transaction.id = null
    @transaction.depth = 0
    @emit 'endTransaction', id, metadata

  # TODO: use a decorator on relevant methods to inject these, instead of manually
  checkTransactionStart: () ->
    if not @transaction.id
      @startTransaction 'implicit'
    else if @transaction.id == 'implicit'
      @transaction.depth += 1

  checkTransactionEnd: () ->
    if @transaction.id == 'implicit'
      @transaction.depth -= 1
    if @transaction.depth == 0
      @endTransaction 'implicit'

  # ## Modifying Graph properties
  #
  # This method allows changing properties of the graph.
  setProperties: (properties) ->
    for item, val of properties
      @properties[item] = val
    @emit 'changeProperties', @properties

  # ## Exporting a port from subgraph
  #
  # This allows subgraphs to expose a cleaner API by having reasonably
  # named ports shown instead of all the free ports of the graph
  #
  # The ports exported using this way are ambiguous in their direciton. Use
  # `addInport` or `addOutport` instead to disambiguate.
  addExport: (publicPort, nodeKey, portKey, metadata = {x:0,y:0}) ->
    # Check that node exists
    return unless @getNode nodeKey

    @checkTransactionStart()

    exported =
      public: publicPort
      process: nodeKey
      port: portKey
      metadata: metadata<commit_msg>Transactions for property changes too<commit_after>#     NoFlo - Flow-Based Programming for JavaScript
#     (c) 2013 The Grid
#     (c) 2011-2012 <NAME>, Nemein
#     NoFlo may be freely distributed under the MIT license
#
# NoFlo graphs are Event Emitters, providing signals when the graph
# definition changes.
#
# On Node.js we use the build-in EventEmitter implementation
unless require('./Platform').isBrowser()
  {EventEmitter} = require 'events'
# On browser we use Component's EventEmitter implementation
else
  EventEmitter = require 'emitter'

# This class represents an abstract NoFlo graph containing nodes
# connected to each other with edges.
#
# These graphs can be used for visualization and sketching, but
# also are the way to start a NoFlo network.
class Graph extends EventEmitter
  name: ''
  properties: {}
  nodes: []
  edges: []
  initializers: []
  exports: []
  inports: {}
  outports: {}
  groups: []

  # ## Creating new graphs
  #
  # Graphs are created by simply instantiating the Graph class
  # and giving it a name:
  #
  #     myGraph = new Graph 'My very cool graph'
  constructor: (@name = '') ->
    @properties = {}
    @nodes = []
    @edges = []
    @initializers = []
    @exports = []
    @inports = {}
    @outports = {}
    @groups = []
    @transaction =
      id: null
      depth: 0

  # ## Group graph changes into transactions
  #
  # If no transaction is explicitly opened, each call to
  # the graph API will implicitly create a transaction for that change
  startTransaction: (id, metadata) ->
    if @transaction.id
      throw Error("Nested transactions not supported")

    @transaction.id = id
    @transaction.depth = 1
    @emit 'startTransaction', id, metadata

  endTransaction: (id, metadata) ->
    if not @transaction.id
      throw Error("Attempted to end non-existing transaction")

    @transaction.id = null
    @transaction.depth = 0
    @emit 'endTransaction', id, metadata

  # TODO: use a decorator on relevant methods to inject these, instead of manually
  checkTransactionStart: () ->
    if not @transaction.id
      @startTransaction 'implicit'
    else if @transaction.id == 'implicit'
      @transaction.depth += 1

  checkTransactionEnd: () ->
    if @transaction.id == 'implicit'
      @transaction.depth -= 1
    if @transaction.depth == 0
      @endTransaction 'implicit'

  # ## Modifying Graph properties
  #
  # This method allows changing properties of the graph.
  setProperties: (properties) ->
    @checkTransactionStart()
    for item, val of properties
      @properties[item] = val
    @emit 'changeProperties', @properties
    @checkTransactionEnd()

  # ## Exporting a port from subgraph
  #
  # This allows subgraphs to expose a cleaner API by having reasonably
  # named ports shown instead of all the free ports of the graph
  #
  # The ports exported using this way are ambiguous in their direciton. Use
  # `addInport` or `addOutport` instead to disambiguate.
  addExport: (publicPort, nodeKey, portKey, metadata = {x:0,y:0}) ->
    # Check that node exists
    return unless @getNode nodeKey

    @checkTransactionStart()

    exported =
      public: publicPort
      process: nodeKey
      port: portKey
      metadata: metadata
{'fraction_non_alphanumeric': 0.09373040752351097, 'fraction_numerical': 0.006269592476489028, 'mean_word_length': 3.15700325732899, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1030665', 'n_tokens_mistral': 1826, 'n_tokens_neox': 1753, 'n_words': 679}