<commit_before>###
Postie.js
Copyright 2013 <NAME>

Version: 0.1.0
Author: <NAME>
URL: http://github.com/paulspringett/postie.js

Released under the MIT license
http://mit-license.org/
###

Postie = {}

# Postie.Client
# The Client references and connects to the Server in another Frame.
# The Available methods are fetched from the Server and instantiated
# as methods on the Client
# Example:
# ```
# client = new Postie.Client('#serveriframe')
# client.ready ->
#   client.getUser 123, (attrs) ->
#     @user = new User(attrs)
# ```
class Postie.Client
  _callbacks: []

  # Create a new client, and start listening to responses
  #
  # serverFrame - reference to the Window or iFrame the server is listening in
  #
  # Returns a Postie.Client
  constructor: (serverUrl) ->
    @_listen()
    @serverUrl = serverUrl

  # Wait until the server Frame is ready and then
  # request the available method endpoints from the
  # server's Receiver object
  #
  # `callback` - function to run when ready
  #
  # Returns nothing
  ready: (callback) ->
    @_createFrame @serverUrl, =>
      uuid = @_dispatch('getEndpoints', true)

      @_registerCallback uuid, (methods) =>
        @_createEndpoints(methods)
        callback()

  # Add the callback for the given UUID for the callbacks Array
  #
  # uuid - String of the UUID
  # fn - Function, the callback to run
  #
  # Returns an Array of the UUID and function added
  _registerCallback: (uuid, fn) ->
    @_callbacks.push
      uuid: uuid
      fn: fn

    [uuid, fn]

  # Takes an argument and attempts to return a Window that can have
  # postMessage called on it successfully
  #
  # frame - String, Object or Function
  #
  # Raises Error if a Window cannot be parsed
  # Returns a Window
  _createFrame: (serverUrl, callback) ->
    frame = document.createElement('iframe')
    frame.setAttribute 'src', serverUrl
    frame.setAttribute 'id', 'postie-server-iframe'
    frame.setAttribute 'style', 'display:none;'

    frame.onload = callback
    document.body.appendChild frame

    @_frame = frame.contentWindow


  # Create methods on this client from the list of endpoints from the server
  #
  # Returns this
  _createEndpoints: (endpoints) ->
    @_endpoints = endpoints

    for endpoint in endpoints
      do (endpoint) =>
        @[endpoint] = (args...) ->
          [data, callback] = @_parseArgs(args)
          uuid = @_dispatch(endpoint, data)
          @_registerCallback(uuid, callback) if callback?

    @

  # Take an artibuarty number of arguments and determine which is the data and
  # which is a callback function
  #
  # Returns an Array
  _parseArgs: (args) ->
    # If more than 2 args throw an error
    if args.length > 2
      throw new Error 'ArgumentError: more than 2 args passed to an endpoint. Pass a data argument and a callback argument only'

    # If 2 args, they should be in order already
    if args.length is 2
      return args

    # If only 1 arg, determine if it's a callback function or data
    if args.length is 1
      arg = args[0]

      if typeof(arg) is 'function'
        return [null, arg]

      else
        return [arg, null]

    [null, null]

  # Dispatch the encapsulated message to the Frame
  # using postMessage
  #
  # Returns a String of the Message's UUID
  _dispatch: (method, data) ->
    uuid = @_generateUuid()

    payload = @_payload(uuid, method, data)
    @_frame.postMessage payload, '*'
    uuid

  # Creates a payload String. postMessage only supports sending of string data.
  # Takes a UUID, endpoint method and data (any type) and creates a JSON object
  # which is then stringified
  #
  # uuid - String of the UUID
  # method - String of the endpoint method to run
  # data - Any (String, Int, JSON) of the data to send
  #
  # Returns a String
  _payload: (uuid, method, data) ->
    message = { postie: true, uuid: uuid, method: method, payload: data }
    JSON.stringify(message)

  # Creates a randon UUID for each message
  #
  # Returns a String
  _generateUuid: ->
    s4 = ->
      (((1+Math.random())*0x10000)|0).toString(16).substring(1)

    "#{s4()}#{s4()}-#{s4()}-#{s4()}-#{s4()}-#{s4()}#{s4()}#{s4()}"

  # Bind to the window.message event to listen for incoming postMessage
  # events
  #
  # Binds event to @_receive
  # Returns nothing<commit_msg>Register callback with UUID before dispatch is called<commit_after>###
Postie.js
Copyright 2013 <NAME>

Version: 0.1.0
Author: <NAME>
URL: http://github.com/paulspringett/postie.js

Released under the MIT license
http://mit-license.org/
###

Postie = {}

# Postie.Client
# The Client references and connects to the Server in another Frame.
# The Available methods are fetched from the Server and instantiated
# as methods on the Client
# Example:
# ```
# client = new Postie.Client('#serveriframe')
# client.ready ->
#   client.getUser 123, (attrs) ->
#     @user = new User(attrs)
# ```
class Postie.Client
  _callbacks: []

  # Create a new client, and start listening to responses
  #
  # serverFrame - reference to the Window or iFrame the server is listening in
  #
  # Returns a Postie.Client
  constructor: (serverUrl) ->
    @_listen()
    @serverUrl = serverUrl

  # Wait until the server Frame is ready and then
  # request the available method endpoints from the
  # server's Receiver object
  #
  # `callback` - function to run when ready
  #
  # Returns nothing
  ready: (callback) ->
    @_createFrame @serverUrl, =>
      uuid = @_generateUuid()
      @_dispatch(uuid, 'getEndpoints', true)

      @_registerCallback uuid, (methods) =>
        @_createEndpoints(methods)
        callback()

  # Add the callback for the given UUID for the callbacks Array
  #
  # uuid - String of the UUID
  # fn - Function, the callback to run
  #
  # Returns an Array of the UUID and function added
  _registerCallback: (uuid, fn) ->
    @_callbacks.push
      uuid: uuid
      fn: fn

    [uuid, fn]

  # Takes an argument and attempts to return a Window that can have
  # postMessage called on it successfully
  #
  # frame - String, Object or Function
  #
  # Raises Error if a Window cannot be parsed
  # Returns a Window
  _createFrame: (serverUrl, callback) ->
    frame = document.createElement('iframe')
    frame.setAttribute 'src', serverUrl
    frame.setAttribute 'id', 'postie-server-iframe'
    frame.setAttribute 'style', 'display:none;'

    frame.onload = callback
    document.body.appendChild frame

    @_frame = frame.contentWindow


  # Create methods on this client from the list of endpoints from the server
  #
  # Returns this
  _createEndpoints: (endpoints) ->
    @_endpoints = endpoints

    for endpoint in endpoints
      do (endpoint) =>
        @[endpoint] = (args...) ->
          [data, callback] = @_parseArgs(args)
          uuid = @_generateUuid()
          @_registerCallback(uuid, callback) if callback?
          @_dispatch(uuid, endpoint, data)
    @

  # Take an artibuarty number of arguments and determine which is the data and
  # which is a callback function
  #
  # Returns an Array
  _parseArgs: (args) ->
    # If more than 2 args throw an error
    if args.length > 2
      throw new Error 'ArgumentError: more than 2 args passed to an endpoint. Pass a data argument and a callback argument only'

    # If 2 args, they should be in order already
    if args.length is 2
      return args

    # If only 1 arg, determine if it's a callback function or data
    if args.length is 1
      arg = args[0]

      if typeof(arg) is 'function'
        return [null, arg]

      else
        return [arg, null]

    [null, null]

  # Dispatch the encapsulated message to the Frame
  # using postMessage
  #
  # Returns a String of the Message's UUID
  _dispatch: (uuid, method, data) ->
    payload = @_payload(uuid, method, data)
    @_frame.postMessage payload, '*'
    uuid

  # Creates a payload String. postMessage only supports sending of string data.
  # Takes a UUID, endpoint method and data (any type) and creates a JSON object
  # which is then stringified
  #
  # uuid - String of the UUID
  # method - String of the endpoint method to run
  # data - Any (String, Int, JSON) of the data to send
  #
  # Returns a String
  _payload: (uuid, method, data) ->
    message = { postie: true, uuid: uuid, method: method, payload: data }
    JSON.stringify(message)

  # Creates a randon UUID for each message
  #
  # Returns a String
  _generateUuid: ->
    s4 = ->
      (((1+Math.random())*0x10000)|0).toString(16).substring(1)

    "#{s4()}#{s4()}-#{s4()}-#{s4()}-#{s4()}-#{s4()}#{s4()}#{s4()}"

  # Bind to the window.message event to listen for incoming postMessage
  # events
  #
  # Binds event to @_receive
  # Returns nothing
{'fraction_non_alphanumeric': 0.10099032703823123, 'fraction_numerical': 0.008751727314601566, 'mean_word_length': 2.940562613430127, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 41, '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': '5032571', 'n_tokens_mistral': 2682, 'n_tokens_neox': 2607, 'n_words': 985}