<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en">
  <siteinfo>
    <sitename>CommonJS Spec Wiki</sitename>
    <base>http://wiki.commonjs.org/wiki/CommonJS</base>
    <generator>MediaWiki 1.15.3</generator>
    <case>first-letter</case>
    <namespaces>
      <namespace key="-2">Media</namespace>
      <namespace key="-1">Special</namespace>
      <namespace key="0" />
      <namespace key="1">Talk</namespace>
      <namespace key="2">User</namespace>
      <namespace key="3">User talk</namespace>
      <namespace key="4">CommonJS</namespace>
      <namespace key="5">CommonJS talk</namespace>
      <namespace key="6">File</namespace>
      <namespace key="7">File talk</namespace>
      <namespace key="8">MediaWiki</namespace>
      <namespace key="9">MediaWiki talk</namespace>
      <namespace key="10">Template</namespace>
      <namespace key="11">Template talk</namespace>
      <namespace key="12">Help</namespace>
      <namespace key="13">Help talk</namespace>
      <namespace key="14">Category</namespace>
      <namespace key="15">Category talk</namespace>
      <namespace key="102">Property</namespace>
      <namespace key="103">Property talk</namespace>
      <namespace key="104">Type</namespace>
      <namespace key="105">Type talk</namespace>
      <namespace key="106">Form</namespace>
      <namespace key="107">Form talk</namespace>
      <namespace key="108">Concept</namespace>
      <namespace key="109">Concept talk</namespace>
      <namespace key="170">Filter</namespace>
      <namespace key="171">Filter talk</namespace>
      <namespace key="200">Website</namespace>
      <namespace key="201">Website talk</namespace>
    </namespaces>
  </siteinfo>
  <page>
    <title>OldAPI</title>
    <id>3</id>
    <revision>
      <id>999</id>
      <timestamp>2009-09-10T03:15:35Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-CommonJS/API +OldAPI)</comment>
      <text xml:space="preserve">{{Old}}
Here are sections for proposed standard modules.

* [[OldAPI/console]]
* [[OldAPI/system]]
* [[OldAPI/binary]]
* [[OldAPI/file]]
* [[OldAPI/io]]
* [[OldAPI/ioString]]</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/ProposalK</title>
    <id>4</id>
    <revision>
      <id>1000</id>
      <timestamp>2009-09-10T03:15:45Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-CommonJS/API +OldAPI)</comment>
      <text xml:space="preserve">== Synopsis ==

In JavaScript there are both &quot;javascriptish/rhinocerous&quot;, native patterns for collection
types embodied by the usage and generic methods of &lt;tt&gt;Array&lt;/tt&gt; and
&lt;tt&gt;Object&lt;/tt&gt;.  However these objects and their patterns have several disadvantages
which give rise to the need for &quot;best practices&quot; in user-defined collections.

* &lt;tt&gt;.length&lt;/tt&gt; assignment is not observable in pure-JS interoperably
* &lt;tt&gt;[index]&lt;/tt&gt; assignment is only special for &lt;tt&gt;Array&lt;/tt&gt; and inheriting &lt;tt&gt;Array&lt;/tt&gt; does not imbue types with their specialness.
* &lt;tt&gt;[name]&lt;/tt&gt; assignment can have name collisions between names in an object's prototype chain and those that it ought to contain.  Assigning arbitrary strings in this domain can potentially mask builtins.
* The &lt;tt&gt;in&lt;/tt&gt; operator cannot be safely used on &lt;tt&gt;Object&lt;/tt&gt; instances to check for containment or iteration.  You have to use the &lt;tt&gt;Object.prototype.hasOwnProperty.call&lt;/tt&gt; method instead.
* Proxies for native objects cannot observe indexing or length assignment.
* &lt;tt&gt;Array&lt;/tt&gt;'s constructor is not strictly variadic.  That is, creating an Array with a single value that is a number must be done with Array literals.  &lt;tt&gt;Array&lt;/tt&gt; and &lt;tt&gt;Object&lt;/tt&gt; do not support copy construction.
* &lt;tt&gt;Object&lt;/tt&gt; can only be used for mappings from a domain of strings.

However, there are distinct advantages of playing nicely with these types, like 
being able to use the &lt;tt&gt;Array.prototype&lt;/tt&gt; generic methods.  For this reason,
there need to be two layers of collection types: those that play well with
natives (&quot;rhinocerous types&quot;, if you will), and those that can be manipulated
in pure JavaScript using a new set of conventional names.  With these
user-defined types, it's necessary to use methods for all interaction with
the underlying collection.

We can create a system of base types that support
mutual copy construction and mutual interface implementation.
That is, all collections should be constructable
by passing an iterable as their argument, and in turn all collections should
be iterable.  Python does this well, but we can do one step better by making
the default iteration on dictionary mappings to render an iterable of
(key, value) pairs instead of simply the keys.  We can also define orthogonal
interfaces intrinsic to each of the three main collection types and cross
implement those interfaces in each other type to the extent it make sense.
That is, a List is a duck-type for a Dict where the keys are offsets.
A Dict is a Set of pairs.  A Set is an unordered List.

Methods intrinsic to:
* Set (unordered values): insert, remove, retrieve, discard
* Dict (unordered pairs): get, set, del, has, put, cut
* List (ordered values, (index value pairs)): push, pop, shift, unshift

But List implements all of these Dict interface, and Dict can inherit Set.

This is a proposal for modules to be included in the standard library.
Since there's some coupling between iteration and stream IO, I've begun
layout out those modules as well.  My recommendation is to implement
the IO, file, and socket modules in the standard library.  That would leave
each platform to implement a &quot;posix&quot; module with all the routines that
these other libraries would need.

This is very rough draft status.  I imagine there's a lot of room for
discussion on nomenclature and intended scope for the CommonJS
standard library.

== API ==

* Iterations Module API [[OldAPI/iter/ProposalK]]
* Sets Module API [[OldAPI/set/ProposalK]]
* Dictionaries Module API [[OldAPI/dict/ProposalK]]
* Lists Module API [[OldAPI/list/ProposalK]]
* Binary Module API [[OldAPI/binary/ProposalK]]
* Posix Module API [[OldAPI/posix/ProposalK]]
* File Module API [[OldAPI/file/ProposalK]]
* IO Module API [[OldAPI/io/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/binary</title>
    <id>5</id>
    <revision>
      <id>1247</id>
      <timestamp>2009-09-12T04:40:59Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-\[\[(.+?)\|\1\]\] +[[\1]])</comment>
      <text xml:space="preserve">Please see the [[Binary]] proposal for details about the contents of the &quot;binary&quot; module.</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/binary/ProposalK</title>
    <id>6</id>
    <revision>
      <id>973</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/binary/ProposalK]] to [[OldAPI/binary/ProposalK]]</comment>
      <text xml:space="preserve"> 
 /*** Binary
     Returns a  representation of an array of bytes.
     Accepts a Binary, or an Array of Numbers.
     Throws an error if any Number is greater than or equal to 256,
     less than 0, or of sub-integer precision.
 */
 
 /**** length
 */
 
 /**** get
 */
 
 /**** set
 */
 
 /**** slice
 */
 
 /**** concat
 */
 
 /**** indexOf
 */
 
 /**** replace
 */
 
 /**** toSource
 */
 
 /**** toString
 */
 
 /**** toSource
 */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/console</title>
    <id>7</id>
    <revision>
      <id>975</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/console]] to [[OldAPI/console]]</comment>
      <text xml:space="preserve">Many client-side libraries already support a JavaScript console object.  Since this functionality is useful on the server, and to ease migration of client-side JavaScript to the server, server-side JavaScript platforms need to provide a &quot;console&quot; object suitable for use with minimal modification to existing scripts.  Rather than provide a &quot;console&quot; free variable like web browsers, interoperable JavaScript modules may explicitly import the &quot;console&quot; module and bind it to a module local &quot;console&quot; variable.

= Specification =

The &quot;console&quot; top-level module must be available in all platforms.  The module must provide the following exports:

; log(message) : logs a message
; info(message) : logs an informational message
; warn(message) : logs a warning message
; error(message) : logs an error message

Messages may be any reference.  Names must be strings.


= Prior Art =
* [http://getfirebug.com/logging.html Firebug]
* [http://developer.apple.com/internet/safari/faq.html#anchor14 Safari 1.3 Console]
* [http://operawiki.info/OperaJSConsole Opera JavaScript Console]
* Internet Explorer 8 JavaScript Console

= Relevant Discussions =

= Show of Hands =

= Implementations =</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/dict/ProposalK</title>
    <id>8</id>
    <revision>
      <id>977</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/dict/ProposalK]] to [[OldAPI/dict/ProposalK]]</comment>
      <text xml:space="preserve"> 
 /*** Dict
     an unordered collection of key to value mappings.
     Unlike `Object`, a `Dict` object's key domain includes any
     object, with better performance when the `hash` of each
     key does not collide.  That is, the `Number` ``1`` and the
     `String` ``&quot;1&quot;`` are distinct objects.
 
     `Dict` inherits from  `Iterable` and `Set`, overriding the `eq` and
     `hash` of the underlying `Set` to use versions that hash and compare
     equivalence based on the pair component of key value pairs.
 
     Different than Python ``dict``:
 
     - ``update``: `add`
     - ``has_key``: `hasKey`
     - ``iteritems``: `itemsIter`
     - ``iterkeys``: `keysIter`
     - ``itervalues``: `valuesIter`
     - ``fromkeys(S, v)``: ``Dict(each(S.keys(), function (k) {return [k, v]}))``
     - ``setdefault``: use `set` and `get`
     - ``__del__`` -&gt; `remove`
     - ``__contains__`` -&gt; `has`
 
     Same as Python:
 
     - `get`
     - `clear`
     - `copy`
     - `items`
     - `keys`
     - `values`
     - `pop`
 
 */
 
     /**** keysIter
         returns an `Iter` of keys from the 
         key and value pairs (items) in the dictionary.
         Uses `itemsIter`.
 
         - `stateless`
     */
 
     /**** keys
         returns a `Set` of keys from the 
         key and value pairs (items) in the dictionary.
         Uses `keysIter` and `itemsIter`.
 
         - `stateless`
     */
 
     /**** valuesIter
         returns an `Iter` of values from the
         key and value pairs (items) in the dictinoary.
         Uses `itemsIter`.
 
         - `stateless`
     */
 
     /**** values
         returns a `List` of values from the
         key and value pairs (items) in the dictionary.
         Uses `valuesIter` and `itemsIter`.
 
         - `stateless`
     */
 
     /**** itemsIter
         returns an iteration, `Iter`, of the key and
         value pairs (items) in the dictionary.
         Items are represented as native JavaScript
         `Array` objects.
         Uses `iter`, which is defined for the
         `Set` base-type.
 
         - `stateless`
     */
 
     /**** items
         returns a `List` of the key and value
         pairs (items) in the dictionary.
         Items are represnted as native JavaScript
         `Array` objects.
         Uses `itemsIter`.
 
         - `stateless`
     */
 
     /**** get
         returns the value of an item in
         the dictionary that has a given
         key.  If there is item for the key,
         attempts to return a default value, 
         checking whether you've specified
         a default value to return as a second
         argument, or deferring to `getDefault`.
         If no acceptable default exists,
         throws a `KeyError`.
 
         accepts:
         - a key (any object)
         - an optional default value, which
            can be `undefined` or `null`
            if you wish to avoid throwing
            a `KeyError`.
 
         - `stateless`
     */
 
     /**** set 
         stores a key and corresponding value
         (an item) in the dictionary.  If
         an item already exists in the dictionary
         that has the same key, it is overwritten.
 
         - stateful
         - chainable
     */
 
     /**** put
         an alias for `set`
     */
 
     /**** has
         returns whether a dictionary contains
         a given key.
     */
 
     /**** cut
         returns the value for a given key and
         removes the corresponding key, value pair
         from the dictionary.
 
         - `stateful`
     */
 
     /**** del
         deletes the key and value pair (item)
         in the dictionary
         that has a given key.
 
         - `stateful`
         - `chainable`
     */
 
     /**** getDefault
         an overridable function that returns
         a value or throws a KeyError if you
         attempt to `get` an item for a key
         that the dictionary does not contain.
 
         - `stateless`, but overrides may
            be stateful.
     */
 
     /**** hasValue
         returns whether the dictionary contains
         an item with the given value.
 
         - `stateless`
     */
 
     /**** hasKey
         an alias of `has`
 
         - `stateless`
     */
 
     /**** update
         Sets the given iterable of key value pairs on this
         dictionary, overriding any existing keys.
 
         - `stateful`
         - `chainable`
     */
 
     /**** updated
         Returns a new copy of this dictionary that has been
         updated with the pairs in a given iterable.
         
         - `stateless`
         - `chainable`
     */
 
     /**** complete
         Sets the given iterable of key value pairs on this
         dictionary, except for those with existing keys.
 
         - `stateful`
         - `chainable`
     */
 
     /**** completed
         Returns a new copy of this dictionary that has been
         completed with the pairs in a given iterable.
 
         - `stateless`
         - `chainable`
     */
 
     /**** find
         - `stateless`
     */
 
     /**** findReverse
         since dictionary keys are not ordered, `findReverse`
         is an alias of `find`.
 
         - `stateless`
     */
 
     /**** add
         - `stateful`
         - `chainable`
     */
 
     /**** added
         - `stateless`
         - `chainable`
     */
 
     /**** eq
         - `stateless`
     */
 
     /**** repr
         - `stateless`
     */
 
     /**** string
         - `stateless`
     */
 
     /**** hash
         - `stateless`
     */
 
     /**** invoke
         an alias of `get` that permits a dictionary
         to be used as a unary relation on its 
         domain of keys to its range of values.
     */
 
 /*** toDict
 */
 
 /*** toObject
     Creates a new native JavaScript `Object`
     from any instance.
 
     Defers to any user defined `toObject` method
     of the given object.  Failing that, defers
     to `dict` to convert the given object to
     a `Dict` and then creates an `Object` from
     that dictionary's key value pairs.
 */
 
 /*** hasKey
     - `polymorphic`
 */
 
 /*** hasValue
     - `polymorphic`
 */
 
 /*** update
     - `polymoprhic`
     - `stateful`
     - `chainable`
 */
 
 /*** updated
     - `polymorphic`
     - `stateless`
     - `chainable`
 */
 
 /*** complete
     - `polymoprhic`
     - `stateful`
     - `chainable`
 */
 
 /*** completed
     - `polymorphic`
     - `stateless`
     - `chainable`
 */
 
 /*** clear
     removes all key value pairs from list and dict-like objects
     including native Arrays, Objects, and types that override
     the `clear` function like `Dict` and `List`.
 
     - `polymorphic`
     - `stateful`
     - `chainable`
 */
 
 /*** keys
     - `polymorphic`
     - `stateless`
 */
 
 /*** keysIter
     - `polymorphic`
     - `stateless`
 */
 
 /*** values
     - `polymorphic`
     - `stateless`
 */
 
 /*** valuesIter
     - `polymorphic`
     - `stateless`
 */
 
 /*** items
     - `polymorphic`
     - `stateless`
 */
 
 /*** itemsIter
     - `polymorphic`
     - `stateless`
 */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/file</title>
    <id>9</id>
    <revision>
      <id>1239</id>
      <timestamp>2009-09-12T04:35:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-Filesystem API +Filesystem)</comment>
      <text xml:space="preserve">Moved to [[Filesystem]] and the original proposal at [[Filesystem/A]].</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/file/Names</title>
    <id>10</id>
    <revision>
      <id>981</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/file/Names]] to [[OldAPI/file/Names]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Names]].</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/file/ProposalK</title>
    <id>11</id>
    <revision>
      <id>983</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/file/ProposalK]] to [[OldAPI/file/ProposalK]]</comment>
      <text xml:space="preserve"> 
 /**
 */
 
 /*** File
     - :isa:`io#Io`
 */
 
 /*** Stat
     - :isa:`Object`
     a representation of a file's metadata including permissions,
     ownership, time stamps, and other traits.
 */
 
 /*** Dir
 */
 
 /**** iter
 */
 
 /*** glob
     returns a `List` of file names for a given &quot;glob&quot; expression
     that may contain patterns:
 
       ===  ======================================================
       ?    matches any single character
   
       *    matches any pattern of characters
   
       **   matches any pattern of characters
            in the file names of a depth first traversal
            starting with the file names and directories
            that start with the file name characters before ``**``
            and ending with the file name characters after ``**``
       ===  ======================================================
   
 */
 
 /*** globIter
     returns an iteration of file names for a given &quot;glob&quot; expression
     that may contain patterns according to those documented
     in `glob`
 */
 
 /*** separator
     The path separator for the platform's file systems.
 */
 
 /*** resolve
     returns the real, absolute, fully-qualified path arrived
     at from a ``base`` path following an relative ``rel`` path.
     When no ``base`` is provided, resolves the ``rel`` path
     relative to the current working directory.
 
     - accepts ``rel``
     - accepts an optional ``base``
 
 */
 
 /*** relative
     returns the relative path between two fully-qualifed paths.
 */
 
 /*** baseName
 */
 
 /*** dirName
 */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/io/ProposalK</title>
    <id>12</id>
    <revision>
      <id>985</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/io/ProposalK]] to [[OldAPI/io/ProposalK]]</comment>
      <text xml:space="preserve"> 
This module and the file module in this proposal are a hybrid of mostly the Ruby API melded with Pythonic/Rhinocerous iteration, and liberated of the notion that certain things should be static methods as opposed to simply hosted by the module.

 /**
 */
 
 /*** Io
     - :is:`iter#Iterable`
 */
 
 /**** input
     - accepts an optional `String` line terminator
     - accepts an optional `String` encoding module identifier
     - returns a `String` decoded from reading
 */
 
 /**** print
     - accepts a `String` to encode and write
     - accepts an optional `String` line terminator
     - accepts an optional `String` encoding module identifier
 */
 
 /**** read
     - accepts a maximum `Number` of bytes to read.
     - returns a `Binary` of however many bytes were actually read.
 */
 
 /**** write
     - returns a `Number` of however many bytes were actually
       written.
 */
 
 /**** readNonblock
     - accepts a maximum `Number` of bytes to read.
     - returns a `Binary` of however many bytes were read without
       blocking.
 */
 
 /**** writeNonblock
     - accepts a `Binary` of bytes to write.
     - returns a `Number` of however many bytes were actually
       written without blocking.
 */
 
 /**** isEof
     returns whether the read/write head is at or beyond the
     end of the stream.
 */
 
 /**** iter
     an alias for `linesIter`
 */
 
 /**** linesIter
     - accepts an optional `String` line terminator
     - accepts an optional `String` encoding module identifier
     returns an iteration on lines (`String`) of the stream.
 */
 
 /**** charsIter
     - accepts an optional `String` encoding module identifier
     returns an iteration of characters (`String`) of the stream.
 */
 
 /**** bytesIter
     returns an iteration on bytes (`Binary`) of the stream.
 */
 
 /**** fcntl
 */
 
 /**** getFileNo
     returns an integer `Number` for the process stream number
     that the IO object is attached to.
 */
 
 /**** toNumber
     an alias for `getFileNo`
 */
 
 /**** getLineNo
     returns the current &quot;line&quot; number from the file.
     updated on read.
 */
 
 /**** isTty
     returns whether the stream is attached to a
     terminal device, a teletype, ``tty``.
 */
 
 /**** getPos
     get the current byte offset of the
     read/write head in the stream.
 */
 
 /**** setPos
     set the current byte offset of the
     read/write head in the stream.
 */
 
 /**** rewind
     Equivalent to ``setPos(0)``
 */
 
 /**** seek
     Seeks to a given integer `Number` offset in the
     stream relative to a given position:
 
     Accepts:
 
     - ``offset``, an integer `Number`
     - ``whence``, an enumerated integer `Number` supplied
       by one of the following constants.
     
     Whence:
 
       ========  ==================================
       SEEK_CUR  Seeks to current position
                 plus ``offset``
 
       SEEK_END  Seeks to the end of the stream
                 plus ``offset``, usually negative.
 
       SEEK_SET  Seeks to the beginning of the
                 stream plus ``offset``
       ========  ==================================
 
 
     Example::
 
         var file = require('file');
         var io = require('io');
         var f = file.File(&quot;testfile&quot;, &quot;utf-8&quot;);
         f.seek(-13, io.SEEK_END);
         var line = f.input()
         
 */
 
 /**** stat
 */
 
 /**** select
 */
 
 /**** fsync
 */
 
 /**** ioctl
 */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/iter/ProposalK</title>
    <id>13</id>
    <revision>
      <id>987</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/iter/ProposalK]] to [[OldAPI/iter/ProposalK]]</comment>
      <text xml:space="preserve"> 
 /*** Iterable
     a mixin that adds convenience functions to types
     that implement `iter`.
 */
 
 /**** iter
     a default ``iter`` that returns itself.
 */
 /**** added */
 /**** nextCatch */
 /**** len
     a default, destructive implementation
     of `len` that consumes the remaining elements
     of the iteration and returns how many were
     encountered.
 */
 /**** toObject */
 /**** toArray */
 /**** toList */
 /**** toDict */
 /**** toUnique
     returns a `Set` of the unique elements of the iterable.
 */
 /**** toString
     returns the concatenation of the elements of the 
     iterable coerced into `String` objects.
 */
 /**** toNumber
     a polymorphic alias of `len`.
 */
 /**** toBoolean
     returns whether `toNumber` is greater than 0.
 */
 /**** sliced */
 /**** forEach */
 /**** forEachApply */
 /**** each */
 /**** eachIter */
 /**** eachApply */
 /**** eachApplyIter */
 /**** where */
 /**** whereIter */
 /**** whereApply */
 /**** whereApplyIter */
 /**** zip */
 /**** zipIter */
 /**** transpose */
 /**** transposeIter */
 /**** enumerate */
 /**** enumerateIter */
 /**** reduce */
 /**** reduced */
 /**** flatten */
 /**** flattened */
 /**** group */
 /**** sorted */
 /**** reversed */
 /**** min */
 /**** mix */
 /**** sum */
 /**** product */
 /**** all */
 /**** any */
 /**** join */
 
 
 /*** Iter
     - :is:`Iterable`
 
     Accepts:
 
     - an optional ``next`` `Function`.  Without a ``next`` function,
       returns an empty iteration.
     - an optional ``hasNext`` `Function``.
 
 */
 /**** next */
 /**** hasNext */
 
 /*** iter
     Returns an iteration of a given object.  Attempts
     to call the polymorphic `iter` of a typed object.
     Otherwise, coerces to the first applicable of 
     `String`, `Array`, or `Object` types.
 */
 
 /*** objectIter */
 /*** arrayIter */
 /*** stringIter */
 
 
 /**
     Top Level Functions
     ===================
 
     Functions that operate on iterables, or objects
     coercible to iterables using the polymorphic `iter`
     function.
 */
 
 /*** forEach */
 /*** forEachApply */
 /*** each */
 /*** each */
 /*** eachIter */
 /*** eachApply */
 /*** eachApplyIter */
 /*** where */
 /*** whereIter */
 /*** whereApply */
 /*** whereApplyIter */
 /*** map */
 /*** mapIter */
 /*** forTimes */
 /*** timesIter */
 /*** times */
 /*** transpose */
 /*** transposeIter */
 /*** zip */
 /*** zipIter
 /*** enumerate */
 /*** enumerateIter */
 /*** reduce */
 /*** cycle */
 /*** chain */
 /*** repeat */
 /*** flatten */
 /*** compact */
 /*** compactIter */
 /*** without */
 /*** withoutIter */
 /*** group */
 /*** all */
 /*** any */
 /*** min */
 /*** max */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/list/ProposalK</title>
    <id>14</id>
    <revision>
      <id>989</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/list/ProposalK]] to [[OldAPI/list/ProposalK]]</comment>
      <text xml:space="preserve"> 
 /*** List 
     is `Iterable`
 
     Different than Python:
 
     - append: `push`
     - extend: `add`
     - count: `len`
     - index: `find`
     - insert: `put`
     - remove: `del`
 
     Same as Python:
 
     - `pop`
     - `sort`
     - `reverse`
 
 */
 
     /**** toIter
         - `stateless`
     */
 
     /**** len
         - `stateless`
     */
 
     /**** push
         - `stateful`
         - `chainable`
     */
 
     /**** pop
         - `stateful`
     */
 
     /**** unshift
         - `stateful`
         - `chainable`
     */
 
     /**** shift
         - `stateful`
     */
 
     /**** reverse
         - `stateful`
         - `chainable`
     */
 
     /**** reversed
         - `stateless`
     */
 
     /**** reversedIter
         - `stateless`
     */
 
     /**** sort
         - `stateful`
         - `chainable`
     */
 
     /**** sorted
         - `stateless`
         - `chainable`
     */
 
     /**** slice
         - `stateful`
         - `chainable`
     */
 
     /**** sliced
         - `stateless`
         - `chainable`
     */
 
     /**** splice
         - `stateful`
     */
 
     /**** spliced
         - `stateless`
         - `chainable`
     */
 
     /**** clear
         - `stateful`
         - `chainable`
     */
 
     /**** first
         - `stateless`
     */
 
     /**** last
         - `stateless`
     */
 
     /**** begins
         returns whether the first elements of
         a given list-like-object are equal, by way of `eq`,
         the respective elements in this list.
 
         In Python, this function is called ``startswith``.
         This divergence from Python nomenclature is
         a matter of idealism.  Ideally the semantic group
         of `start`, `stop`, `pause`, `resume`,
         and `run` are all temporal verbs, whereas the
         semantic group `begins`, `ends`, `first`,
         `last`, and such all apply to the state of
         spatial segments or lists.
 
         - `stateless`
     */
 
     /**** ends
         returns whether the last elements of a given
         list-like-object are equal, by way of `eq`,
         the respective elements in this list.
 
         In Python, this function is called ``endsWith``.
         See ``startsWith`` for the rationale.
 
         - `stateless`
     */
 
     /**** reduce
         reduce is an in place operation.
         see reduced for a stateless variant
 
         - `stateful`
         - `chainable`
     */
 
     /**** keysIter
         - `stateless`
     */
 
     /**** keys
         - `stateless`
     */
 
     /**** valuesIter
         - `stateless`
     */
 
     /**** values
         an alias of `copy` so that lists can be used
         as dictionary like objects.
 
         - `stateless`
     */
 
     /**** itemsIter
         enumerates the values of the list.
 
         - `stateless`
     */
 
     /**** items
         returns a list of the enumerated values from 
         this list, using `itemsIter`.
 
         - `stateless`
     */
 
     /**** get
         gets a value by its offset.
 
         - `stateless`
     */
 
     /**** set
         sets a value at a particular offset.
 
         - `stateful`
         - `chainable`
     */
 
     /**** put
         displaces the item at a given index, sending
         successive elements down the line.
 
         - `stateful`
         - `chainable`
     */
 
     /**** cut
         gets the value at a given offset and delete
         the value from the list.
 
         - `stateful`
     */
 
     /**** del
         removes a value from the list, shifting all
         successive values into its void.
         
         - `stateful`
         - `chainable`
     */
 
     /**** has
         returns whether the list contains
         a given value.
 
         - `stateless`
     */
 
     /**** hasKey
         returns whether the list contains a value
         at a given index.
 
         - `stateless`
     */
 
     /**** hasValue
         retunrs whether the list contains
         a given value.
         Uses `has`.
 
         - `stateless`
     */
 
     /**** find
         returns the first index of a given value
         in the list, or throws a `ValueError`
         if none can be found.
 
         - `stateless`
     */
 
     /**** findReverse
         returns the last index of a given value
         in the list, or throws a `ValueError`
         if none can be found.
 
         - `stateless`
     */
 
 
     /**** insert
         an alias of `push`
     */
     /**** retrieve */
     /**** remove */
     /**** discard */
 
     /**** add
         - `stateful`
         - `chainable`
     */
 
     /**** added
         - `stateless`
         - `chainable`
     */
 
     /**** eq
         returns whether this list has the same cardinality, order,
         and respective values as another object.
 
         - `stateless`
     */
 
     /**** lt
         returns whether the the most significant, distinct
         value between the respective values of this list and another
         list-like object is less than the other.
 
         - `stateless`
     */
 
     /**** join
         returns a `String` of the joined string values of
         the values in this list, on a given delimiter or simply
         concatenated.
 
         - `stateless`
     */
 
     /**** repr
         - `stateless`
     */
 
     /**** toArray
         - `stateless`
     */
 
     /**** hash
         - `stateless`
     */
 
 /*** toList
     constructs a `List` from any given iterable.
     Defers to a `toList` or `toIter` method of the given
     object if it exists.
 
     - `poymorphic` on `toList` or `toIter`
 */
 
 /*** toArray
     constructs a native JavaScript `Array` from
     any iterable.
 
     - `polymorphic` on `toArray` or `toIter`
 */
 
 /*** len
     returns the length of a `List`, `Array`, `Object`,
     or any other object that provides a `len` member
     function.
 
     - `polymorphic`
 */
 
 /*** reversed
     returns a `List` of the values from an iterable
     in reversed order.
 
     - `stateless`
 */
 
 /*** sorted
     returns a `List` of the values in a given `Iteration` in
     sorted order.  Accepts an optional override of `compare`,
     a binary relation that returns a `Number` that has the same
     comparison relationship with ``0`` as the relationship between
     the given values.  For example, ``-1`` if the first is less
     than the second, or ``0`` if they are equal.
 
     - `stateless`
 */
 
 /*** slice
     - `polymorphic`
     - `not-curry`
     - `stateless`
 */
 
 /*** splice
 */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/posix/ProposalK</title>
    <id>15</id>
    <revision>
      <id>991</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/posix/ProposalK]] to [[OldAPI/posix/ProposalK]]</comment>
      <text xml:space="preserve">The idea behind this module is that it would be implemented as a native module on each respective platform and hosted by the default loader.  Other IO modules would use these functions as a basis. 

 /**
 */
 
 /*** open
 
     Accepts:
 
     - ``fileName``
     - ``mode``
 
     Returns a file descriptor of unspecified type.
 
     Modes
     =====
 
     Mode Meaning
     ==== ======================================================================
     &quot;r&quot;  read-only, starting at the beginning of the file
     &quot;r+&quot; read-write, starting at the beginning of the file
     &quot;w&quot;  write-only, truncates an existing file to empty or creates a new file
     &quot;w+&quot; read-write, truncates an existing file to empty or creates a new file
     &quot;a&quot;  write-only, starts at end of file if file exists or creates a new file
     &quot;a+&quot; read-write, starts at end of file if file exists or creates a new file
     &quot;b&quot;  binary file mode, may appear before any of the modes above
     
 
 */
 
 /*** close
 */
 
 /*** creat
 */
 
 /*** flush
 */
 
 /*** tell
 */
 
 /*** stat
 */
 
 /*** lstat
 */
 
 /*** unlink
 */
 
 /*** chown
 */
 
 /*** chmod
 */
 
 /*** dup
 */
 
 /*** dup2
 */
 
 /*** fctnl
 */
 
 /*** ioctl
 */
 
 /*** select
 */
 
 /*** getcwd
 */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/set/ProposalK</title>
    <id>16</id>
    <revision>
      <id>993</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/set/ProposalK]] to [[OldAPI/set/ProposalK]]</comment>
      <text xml:space="preserve"> 
 
 /*** Set
     An unordered collection of unique values.
 
     Accepts:
 
     - optional ``values`` (may be ``undefined``, or any iterable object,
       by way of the polymorphic `toIter`)
     - optional custom ``hash`` relation.
     - optional custom ``eq`` binary equivalence relation.
 
     Inherits member functions from `Iterable`.
  
     `Set` operations operate in constant time best case,
     and linear for degenerate cases.
 
     If you insert an object in a set and modify that object
     in such a way that its ``hash`` result changes, it
     will be irrecoverable.
     Most other libraries enforce that only immutable
     objects should be inserted in sets for this reason,
     so be careful.
 
 */
 
     /*** insert
         inserts a value in the `Set`. 
         Position is not relevant.  Replaces
         an existing value if the value has the same
         `hash` key and is `eq` to an existing
         value.  The `hash` function and `eq` function
         can be overridden in the `Set` constructor.
 
          - `stateful`
          - `chainable`
     */
 
     /*** retrieve
         retrieves a value from the `Set` that has
         the same `hash` key and is `eq` to a given
         value.  `eq` and `hash` can be overridden
         in the `Set` constructor.
 
          - `stateless`
     */
 
     /**** remove
         removes a value from the `Set` if it has
         the same `hash` and is `eq` to the value.
         throws a `ValueError` if no matching value
         can be found.
 
          - `stateful`
          - `chainable`
     */
 
     /**** discard
         discards a value from the `Set` if it has
         the same `hash` and is `eq` to the value.
         Unlike `remove`, does not throw a `ValueError`
         if no matching value can be found.
 
          - `stateful`
          - `chainable`
     */
 
     /**** clear
         removes all values in this set.
 
          - `stateful`
          - `chainable`
     */
 
     /**** has
         returns whether a set contains a given value.
         uses `eq` and `hash` to attempt to find
         the value in the set.  These functions
         can be overridden in the `Set` constructor.
     */
 
     /**** find
         searches all of the values in set for one
         that is `eq` to a given value.  returns that
         value.  throws a `ValueError` if no value
         can be found.
 
          - accepts a value to find
          - accepts an optional override to the `eq` function
 
          - `stateless`
     */
 
     /**** toIter */
 
     /**** eq */
 
     /**** union
         augments itself with any values that exist in another
         iterable.
 
          - `stateful`
          - `chainable`
     */
 
     /**** intersect
          - `stateful`
          - `chainable`
     */
 
     /**** difference
          - `stateful`
          - `chainable`
     */
 
     /**** unioned
         returns all elements that are in itself and another iterable.
 
          - `stateless`
          - `chainable`
     */
 
     /**** intersected
         returns all values that are in
         this set and another.
 
          - `stateless`
          - `chainable`
     */
 
     /**** differenced
         returns the set of all values that are
         in this set but not another.
 
          - `stateless`
          - `chainable`
     */
 
     /**** symmetricDifferenced
         returns the set of all values that are exactly one
         set between itself and another.
 
          - `stateless`
          - `chainable`
     */
 
     /**** isSuperSet
         returns whether this set contains all of the values
         in a given container.
 
          - `stateless`
     */
 
     /**** isSubSet
         returns whether a given container contains all of
         this set's values.
 
          - `stateless`
     */
 
     /**** added
         alias of `unioned`
 
          - `stateless`
          - `chainable`
     */
 
     /**** add
         alias of `union`
 
          - `stateful`
          - `chainable`
     */
 
     /**** muled
         alias of `intersected`
 
          - `stateless`
          - `chainable`
     */
 
     /**** mul
         alias of `intersect`
 
          - `stateful`
          - `chainable`
     */
 
     /**** subed
         alias of `differenced`
 
          - `stateless`
          - `chainable`
     */
 
     /**** sub
         alias of `difference`
 
          - `stateful`
          - `chainable`
     */
 
     /**** and
         alias of `intersect`
 
          - `stateful`
          - `chainable`
     */
 
     /**** anded
         alias of `intersected`
 
          - `stateless`
          - `chainable`
     */
 
     /**** or
         alias of `union`
 
          - `stateful`
          - `chainable`
     */
 
     /**** ored
         alias of `unioned`
 
          - `stateless`
          - `chainable`
     */
 
     /**** xor
         alias of `symmetricDifferenced`
 
          - `stateful`
          - `chainable`
     */
 
     /**** xored
         alias of `symmetricDifferenced`
 
          - `stateless`
          - `chainable`
     */
 
 /**
     Functions
     =========
 
     Functions that operate on sets, or arrays
     coercible to sets using the polymorphic
     `toSet` function.
 */
 
 /*** toSet */
 /*** insert */
 /*** retrieve */
 /*** remove */
 /*** discard */
 /*** clear */
 /*** has */
 /*** union */
 /*** intersect */
 /*** difference */
 /*** symetricDifference */
 /*** isSuperSet */
 /*** isSubSet */</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/system</title>
    <id>17</id>
    <revision>
      <id>1248</id>
      <timestamp>2009-09-12T04:41:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-\[\[(.+?)\|\1\]\] +[[\1]])</comment>
      <text xml:space="preserve">See the [[System]] proposal.  It is as yet undecided whether the &quot;system&quot; object will be a free variable available to all modules, or a module that can be required.</text>
    </revision>
  </page>
  <page>
    <title>OldAPI/url/ProposalK</title>
    <id>18</id>
    <revision>
      <id>997</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/API/url/ProposalK]] to [[OldAPI/url/ProposalK]]</comment>
      <text xml:space="preserve"> 
 /*** resolve
     returns the real, absolute, fully-qualified URL arrived
     at from a ``base`` URL following an relative ``rel`` URL.
     When no ``base`` is provided, resolves the ``rel`` URL
     relative to the current working directory.
 
     - accepts ``rel``
     - accepts an optional ``base``
 
 */
 
 /*** relative
     returns the relative URL between two fully-qualifed paths.
 */</text>
    </revision>
  </page>
  <page>
    <title>Binary</title>
    <id>19</id>
    <revision>
      <id>2772</id>
      <timestamp>2010-05-13T19:12:31Z</timestamp>
      <contributor>
        <username>Markm</username>
        <id>54</id>
      </contributor>
      <comment>/* Relevant Discussions */</comment>
      <text xml:space="preserve">'''STATUS: PROPOSALS, DISCUSSION'''

JavaScript does not have a binary data type. However, in server-side scenarios, binary data needs to be often processed. That is why we need some working byte or binary array or string class.

== Proposals ==

# [[Binary/A]] Proposal A from Ondras
# [[Binary/B]] Proposal B from Kris Kowal (implemented by a few platforms)
# [[Binary/C]] Proposal C from Daniel Friesen
# [[Binary/D]] Proposal D from Kris Kowal (based on [[Binary/B]], -array-comprehsiveness, +bits, +radix-encoding)
# [[Binary/E]] Proposal E (based on [[Binary/D]] with byte string &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; returning Number instead of ByteString, +Binary base type, -bits, -radix-encoding, -patching)
# [[Binary/Lite]] Proposal &quot;Lite&quot; from Ondras (single Binary type -charsets)
# [[Binary/F]] Proposal F (based on [[Binary/E]] but viciously trimmed, -ByteString, s/ByteArray/Buffer/ -flexible length)

== Prior Art ==

* [http://help.adobe.com/en_US/AIR/1.1/jslr/flash/utils/ByteArray.html Adobe AIR's ByteArray]
* [https://developer.mozilla.org/En/NsIBinaryInputStream Mozilla's nsIBinaryInputStream]
* [https://developer.mozilla.org/En/NsIBinaryOutputStream Mozilla's nsIBinaryOutputStream]
* [http://www.ejscript.org/products/ejs/doc/api/ejscript/intrinsic-ByteArray.html EJScript ByteArray]
* [http://code.google.com/apis/gears/api_blob.html Google Gears Blob]
* [http://code.google.com/p/jslibs/wiki/jslang#jslang::Blob_class  JSlibs Blob]
* [http://flusspferd.org/docs/js/Blob Flusspferd Blob] [http://github.com/ruediger/flusspferd/blob/1ead764aca33aca6926b6ac85871d1482c465616/src/core/blob.jsdoc repository link] (since it has been removed, the docs might go away at some point)
* [http://www.w3.org/TR/FileAPI/ W3C File API] (blob, FileBlob, readAsBinaryString, readAsDataUrl)

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst First Proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/da076076c965d069/2cd8ac336387ceb3?lnk=gst Comments on Binary object]
* [http://groups.google.com/group/commonjs/browse_thread/thread/e866544eb3aff182/16ed57b3c78b86e1?lnk=gst Binary API Brouhaha]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal] regarding proposal B
* [http://groups.google.com/group/commonjs/browse_thread/thread/0680b464e775726c Binary/C - range for memcopy]
* [http://groups.google.com/group/commonjs/browse_thread/thread/8a0d9db68e81baae ByteString / ByteArray duality]
* [http://groups.google.com/group/commonjs/browse_thread/thread/3b0a3a20a67987d8 Alternate binary proposal] regarding [[Binary/C]]
* [http://wiki.ecmascript.org/doku.php?id=strawman:typed_arrays Typed Arrays strawman on the EcmaScript wiki]  which cites Khronos's proposed [https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/doc/spec/TypedArray-spec.html TypedArray spec] as its primary source.

[[Encodings]] are a related topic.</text>
    </revision>
  </page>
  <page>
    <title>Binary/A</title>
    <id>20</id>
    <revision>
      <id>871</id>
      <timestamp>2009-09-10T02:48:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Binary/A]] to [[Binary/A]]</comment>
      <text xml:space="preserve">== Binary Data ==

JavaScript does not have a binary data type. However, in server-side scenarios, binary data needs to be often processed. That is why we need some working &lt;tt&gt;Binary()&lt;/tt&gt; class.

=== Binary() object proposition ===

This is an interface of my proposed Binary object. I also created a sample implementation, see http://tmp.zarovi.cz/binary.js.
&lt;source&gt;
/**
 * Creates a new variable holding binary data.
 * @param {number} initialData Variable amount if initial arguments. 
   Every number represents a byte.
 * @returns {Binary}
 */
function Binary(initialData) {};

/**
 * Returns the number of bytes stored in this structure.
 * This is intentionally named &quot;getLength&quot; instead of &quot;length&quot; to indicate a method (and not a property).
 * @returns {number}
 */
Binary.prototype.getLength = function() {};

/**
 * Converts the binary variable to string by UTF-8 encoding its contents.
 * @returns {string}
 */
Binary.prototype.toString = function() {};

/**
 * Returns a byte value from a given index.
 * @param {number} index
 * @returns {number}
 */
Binary.prototype.getByte = function(index) {};

/**
 * Sets a byte value at given index.
 * @param {number} index
 */
Binary.prototype.setByte = function(index, value) {};

/**
 * These are essentialy copied from the Array class.
 */
Binary.prototype.pop = function() {};
Binary.prototype.push = function() {};
Binary.prototype.shift = function() {};
Binary.prototype.unshift = function() {};

/**
 * Encodes the data in Base64
 * @returns {string}
 */
Binary.prototype.base64encode = function() {};

/**
 * Calculates MD5 hash
 * @returns {string}
 */
Binary.prototype.md5 = function() {};

/**
 * Calculates SHA1 hash
 * @returns {string}
 */
Binary.prototype.sha1 = function() {};

/**
 * Decodes the Base64 encoded string
 * @returns {Binary}
 */
String.prototype.base64decode = function() {};

/**
 * Converts an UTF-8 encoded string into its binary (one byte per item) variant
 * @returns {Binary}
 */
String.prototype.toBinary = function() {};

[[User:Ondras|Ondras]] 08:24, 5 February 2009 (UTC)</text>
    </revision>
  </page>
  <page>
    <title>Binary/B</title>
    <id>21</id>
    <revision>
      <id>2790</id>
      <timestamp>2010-05-24T00:03:54Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>added NarwhalJSC and NarwhalNode to list of compliant implementations</comment>
      <text xml:space="preserve">{{Spec
|status=proposed, discussed, some implementations
|implementations=Flusspferd, GPSEE, NarwhalRhino=0.2, NarwhalJSC=0.2, NarwhalNode=0.5, RingoJS, v8cgi
}}

Draft 2.

All platforms must support two types for interacting with binary data: ByteArray and ByteString.  The ByteArray type resembles the interface of Array in that it is mutable, extensible, and indexing will return number values for the byte in the given position, zero by default, or undefined if the index is out of bounds.  The ByteString type resembles the interface of String in that it is immutable and indexing returns a ByteString of length 1.  These types are exported by the 'binary' top-level module and both types are subtypes of Binary, which is not instantiable but exists only for the convenience of referring to both ByteArray and ByteString.  (The idea of using these particular two types and their respective names originated with Jason Orendorff in the [http://groups.google.com/group/commonjs/msg/89808c05d46b92d0 Binary API Brouhaha] discussion.)

= Philosophy =

This proposal is not an object oriented variation on pack and unpack with notions of inherent endianness, read/write head position, or intrinsic codec or charset information.  The objects described in this proposal are merely for the storage and direct manipulation of strings and arrays of byte data.  Some object oriented conveniences are made, but the exercise of implementing pack, unpack, or an object-oriented analog thereof are left as an exercise for a future proposal of a more abstract type or a 'struct' module (as mentioned by Ionut Gabriel Stan on [http://groups.google.com/group/commonjs/msg/592442ba98c6c70e the list]).  This goes against most mentioned [[../|prior art]].

This proposal also does not provide named member functions for any particular subset of the possible charsets, codecs, compression algorithms, or consistent hash digests that might operate on a byte string or array.  Instead, convenience member functions are provided for interfacing with any named charset, with the IANA charset name space, and with the possibility of eventually employing a system of modular extensions for other codecs or digests, requiring that the given module exports a specified interface. (As supported originally by Robert Schultz, Davey Waterson, Ross Boucher, and tacitly myself, Kris Kowal, on the [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst First proposition] thread on the mailing list).  This proposal does not address the need for stream objects to support pipelined codecs and hash digests (mentioned by Tom Robinson and Robert Schultz in the same conversation).

This proposal also reflects both group sentiment and a pragmatic point about properties.  This isn't a decree that properties like &quot;length&quot; should be consistently used throughout the CommonJS APIs.  However, given that all platforms support properties at the native level (to host String and Array objects) and that byte strings and arrays will require support at the native level, pursuing client-side interoperability is beyond the scope of this proposal and therefore properties have been specified.  (See comments by Kris Zyp about the implementability of properties in all platforms, comments by Davey Waterson from Aptana about the counter-productivity of attempting to support this API in browsers, and support properties over accessor and mutator functions by Ionut Gabriel Stand and Cameron McCormack on the [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst mailing list]).

The byte types provide functions for encoding, decoding, and transcoding, but they are all shallow interfaces that defer to a charset manager module, and may in turn use a system level charset or use a pair of pure JavaScript modules to transcode through an array or stream of canonical Unicode code points.  This behavior may be specified further in the future.

In accordance with Daniel Friesen's [[Binary/C]], a high priority in this proposal was String/ByteString and Array/ByteArray interoperability.  For a defined subset of the String and Array APIs, Strings are interoperable with ByteStrings and Arrays with ByteArrays.  To this end, it is necessary to support valueAt as an alternative to charAt on Strings with which ByteStrings would iteroperate.  Supporting charAt on ByteString would be counter-intuitive.  Similarly, codeAt must be implemented on both String and ByteString as an alternative to charCodeAt.

The following methods are interoperable between ByteString and String:
* codeAt returning Number (added to String)
* valueAt returning ByteString or String respectively (added to String)
* get returning ByteString or String respectively (added to String)
* indexOf
* lastIndexOf
* split
* slice
* substr
* substring

The following methods are interoperable between ByteArray and Array:
* get returning Number (added to Array)
* indexOf
* lastIndexOf
* concat
* pop
* push
* shift
* unshift
* reverse
* slice
* sort
* splice
* split
* forEach
* every
* some
* map
* reduce
* reduceRight

The following methods are interoperable between ByteString and ByteArray:
* codeAt returning Number
* valueAt returning ByteString
* get returning ByteString or Number respectively
* toByteString
* toByteArray
* toString
* toArray
* decodeToString
* indexOf
* lastIndexOf
* slice returning ByteString or ByteArray respectively
* split returning an Array of ByteStrings or ByteArrays respectively
* concat returning ByteString or ByteArray respectively


= Specification =

The &quot;binary&quot; top-level module must export &quot;Binary&quot;, &quot;ByteArray&quot; and &quot;ByteString&quot;.

(In multi-sandbox scenarios, the implementation should strive to consistently export the same &quot;Binary&quot;, &quot;ByteArray&quot;, and &quot;ByteString&quot;)

== Binary ==

A Binary function must exist.  The Binary function must throw a ValueError if it is ever called or constructed.  The Binary type exists only to affirm that ByteString and ByteArray instances of Binary.

== ByteString ==

A ByteString is an immutable, fixed-width representation of a C unsigned char (byte) array that does not implicitly terminate at the first 0-valued byte.  Indexing returns a byte substring of length 1.  ByteString instances are instances of ByteString, Binary, and Object.  The typeof a ByteString is &quot;object&quot;.  Object.prototype.call.toString(byteString) returns &quot;[object ByteString]&quot;.

=== Constructor ===

; ByteString()
: Construct an empty byte string.
; ByteString(byteString)
: Copies byteString.
; ByteString(byteArray)
: Use the contents of byteArray.
; ByteString(arrayOfNumbers)
: Use the numbers in arrayOfNumbers as the bytes.
: If any element is outside the range 0...255, a RangeError is thrown.
; ByteString(string, charset)
: Convert a string. The ByteString will contain string encoded with charset.

=== Constructor methods ===

; join(array, delimiter)
: Like Array.prototype.join, but for Binarys. Returns a ByteString.

The following are equivalent expressions.

    ByteString.join([1,2,3], 0)
    ByteString([1, 0, 2, 0, 3])

=== Instance properties ===

; length
: The length in bytes. Immutable.

=== Instance operators ===

; [] ByteString
: the immutable [] operator returning ByteStrings

=== Instance methods (in prototype) ===

; toByteArray()
: Returns a byte for byte copy in a ByteArray.
; toByteArray(sourceCharset, targetCharset)
: Returns a transcoded copy in a ByteArray.
; toByteString()
: Returns itself, since there's no need to copy an immutable ByteString.
; toByteString(sourceCharset, targetCharset)
: Returns a transcoded copy.
; toArray()
: Returns an array containing the bytes as numbers.
; toArray(charset)
: Returns an array containing the decoded Unicode code points.
; toString()
: Returns a debug representation like &quot;[ByteString 10]&quot;, where 10 is the length of the Array. Alternative debug representations are valid too, as long as (1) this method will never fail, (2) the length is included.
; toSource()
: returns &quot;ByteString([])&quot; for a null byte string or &quot;ByteString([0, 1, 2])&quot; for a byte string of length 3 with bytes 0, 1, and 2.
; decodeToString(charset)
: Returns the decoded ByteArray as a string.
; indexOf(byte)
; indexOf(byte, start)
; indexOf(byte, start, stop)
: Returns the index of the first occurance of byte (a Number or a ByteString or ByteArray of any length) or -1 if none was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.
; lastIndexOf(byte)
; lastIndexOf(byte, start)
; lastIndexOf(byte, start, stop)
: Returns the index of the last occurance of byte (a Number or a ByteString or ByteArray of any length) or -1 if none was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.
; codeAt(offset) Number
: Return the byte at offset as a Number.
; byteAt(offset) ByteString
; valueAt(offset) ByteString
; get(offset) ByteString
: Return the byte at offset as a ByteString. get(offset) is analogous to indexing with brackets.
; copy(target, start, stop, targetStart)
: copies the Number values from this ByteString between start and stop to a target ByteArray or Array at the targetStart offset.  start, stop, and targetStart must be Numbers, undefined, or omitted.  If omitted, start is presumed to be 0.  If omitted, stop is presumed to be the length of this ByteString.  If omitted, targetStart is presumed to be 0.
; split(delimiter, [options])
: Split at delimiter, which can by a Number, a ByteString, a ByteArray or an Array of the prior (containing multiple delimiters, i.e., &quot;split at any of these delimiters&quot;). Delimiters can have arbitrary size.
: Options is an optional object parameter with the following optional properties:
* ''count'' - Maximum number of elements (ignoring delimiters) to return. The last returned element may contain delimiters.
* ''includeDelimiter'' - Whether the delimiter should be included in the result.
: Returns an array of ByteStrings.
; slice()
; slice(start)
; slice(start, stop)
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; concat(...ByteString/ByteArray/Array...)
: returns a ByteString composed of itself concatenated with the given ByteString, ByteArray, and Array values.
; substr(start)
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substr String.prototype.substr]
; substr(start, length)
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substr String.prototype.substr]
; substring(first)
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substring String.prototype.substring]
; substring(first, last)
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substring String.prototype.substring]

ByteString does not implement toUpperCase() or toLowerCase() since they are not meaningful without the context of a charset.

== ByteArray ==

A ByteArray is a mutable, flexible representation of a C unsigned char (byte) array.  Instances of ByteArray are instances of ByteArray, Binary, and Object.  The typeof a ByteArray is &quot;object&quot;.  Object.prototype.toString.call(byteArray) returns &quot;[object ByteArray]&quot;.

=== Constructor ===

; ByteArray()
: New, empty ByteArray.
; ByteArray(length)
: New ByteArray filled with length zero bytes.
; ByteArray(byteArray)
: Copy byteArray.
; ByteArray(byteString)
: Copy contents of byteString.
; ByteArray(arrayOfBytes)
: Use numbers in arrayOfBytes as contents.
: Throws an exception if any element is outside the range 0...255 (''TODO'').
; ByteArray(string, charset)
: Create a ByteArray from a Javascript string, the result being encoded with charset.

Unlike the Array, the ByteArray is not variadic so that its initial length constructor is not ambiguous with its copy constructor.

All values within the length of the array are numbers stored as bytes that default to 0 if they have not been explicitly set.  Assigning beyond the bounds of a ByteArray implicitly grows the array, just like an Array.  Retrieving a value from an index that is out of the bounds of the Array, lower than 0 or at or beyond the length, the returned value is &quot;undefined&quot;.  Assigning an index with a value that is larger than fits in a byte will be implicitly and silently masked against 0xFF.  Negative numbers will be bit extended to a byte in two's complement form and likewise masked.

=== Instance properties ===

; mutable length property
: extending a byte array fills the new entries with 0.

=== Instance Operators ===

; [] Number
: The mutable [] operator for numbers

=== Instance methods (in prototype) ===

; toArray()
: n array of the byte values
; toArray(charset)
: an array of the code points, decoded
; toString()
: A string debug representation like &quot;[ByteArray 10]&quot;, where 10 is the length of the byte string.  This method must not throw an error.
; toSource()
: returns &quot;ByteArray([])&quot; for a null byte array or &quot;ByteArray([0, 1, 2])&quot; for a byte array of length 3 with bytes 0, 1, and 2.
; decodeToString(charset String)
: returns a String from its decoded bytes in a given charset.
; toByteArray()
: returns a copy
; toByteArray(sourceCharset, targetCharset)
: transcoded
; toByteString()
: byte for byte copy
; toByteString(sourceCharset, targetCharset)
: transcoded
; byteAt(offset) ByteString
; valueAt(offset) ByteString
: Return the byte at offset as a ByteString.
; get(offset) Number
; codeAt(offset) Number
: Return the byte at offset as a Number.  get(offset) is anlaogous to indexing with brackets.
; copy(target, start, stop, targetStart)
: copies the Number values from this ByteArray between start and stop to a target ByteArray or Array at the targetStart offset.  start, stop, and targetStart must be Numbers, undefined, or omitted.  If omitted, start is presumed to be 0.  If omitted, stop is presumed to be the length of this ByteArray.  If omitted, targetStart is presumed to be 0.
; fill(value, start, stop)
: fills each of the contained bytes with the given value (either a unary ByteString, ByteArray, or a Number) from the &quot;start&quot; offset to the &quot;stop&quot; offset.  &quot;start&quot; and &quot;stop&quot; must be numbers, undefined, or omitted.  If omitted, &quot;start&quot; is presumed to be 0.  If omitted, &quot;stop&quot; is presumed to beh the length of this ByteArray.
; concat(other:ByteArray|ByteString|Array) ByteArray
; pop() byte:Number
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/pop Array.prototype.pop]
; push(...variadic Numbers...) -&gt; count(Number)
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/push Array.prototype.push]
; extendRight(...variadic Numbers / Arrays / ByteArrays / ByteStrings ...)
: equivalent to this.push.apply(this, arguments)
; shift() byte:Number
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/shift Array.prototype.shift]
; unshift(...variadic Numbers...) count:Number
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/unshift Array.prototype.unshift]
; extendLeft(...variadic Numbers / Arrays / ByteArrays / ByteStrings ...)
: equivalent to this.unshift.apply(this, arguments)
; reverse() in place reversal
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/reverse Array.prototype.reverse]
; slice()
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; sort()
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/sort Array.prototype.sort]
; splice()
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/splice Array.prototype.splice]
; indexOf()
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/indexOf Array.prototype.indexOf]
; lastIndexOf()
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/lastIndexOf Array.prototype.lastIndexOf]
; split()
: Returns an array of ByteArrays instead of ByteStrings.
; filter(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter Array.prototype.filter]
; forEach(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach Array.prototype.forEach]
; every(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/every Array.prototype.every]
; some(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/some Array.prototype.some]
; map(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/map Array.prototype.map]
; reduce(callback[, initialValue])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/reduce Array.prototype.reduce]
; reduceRight(callback[, initialValue])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/reduceRight Array.prototype.reduceRight]
; displace(start, stop, values/ByteStrings/ByteArrays/Arrays...) -&gt; length
: start/stop are specified like for slice. Can be used like splice but does not return the removed elements.

== String ==

The String prototype will be extended with the following members:

; toByteArray(charset)
: Converts a string to a ByteArray encoded in charset.
; toByteString(charset)
: Converts a string to a ByteString encoded in charset.
; charCodes()
: Returns an array of Unicode code points (as numbers).
; charAt(offset) Number
: an alias for charCodeAt that interoperates with ByteString's charAT.
; get(offset) String
: an alias for the index operator and interoperable with ByteString, ByteArray, and Array.

== Array ==

The Array prototype will be extended with the following members:

; toByteArray(charset)
: Converts an array of Unicode code points to a ByteArray encoded in charset.
; toByteString(charset)
: Converts an array of Unicode code points to a ByteString encoded in charset.
; get(offset)
: an alias for the index operator and interoperable with ByteString, ByteArray, and String.

== General Requirements ==

None of the specified prototypes or augmentations to existing prototypes are enumerable.

Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &quot;us-ascii&quot; and &quot;utf-8&quot;.

Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.

Charsets are case insensitive.

= Tests =

* [http://github.com/tlrobinson/narwhal/tree/master/tests/serverjs CommonJS tests] compatible with [http://github.com/tlrobinson/narwhal/tree/master/lib/test this test framework]. (targetting draft 1)

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a8d3a91af37fd355 ByteArray: byteAt method]
* [http://groups.google.com/group/commonjs/browse_thread/thread/45190ac89d7b422a Binary/B Extension Proposals and Implementation Notes]</text>
    </revision>
  </page>
  <page>
    <title>Binary/C/Essay</title>
    <id>23</id>
    <revision>
      <id>877</id>
      <timestamp>2009-09-10T02:48:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Binary/C/Essay]] to [[Binary/C/Essay]]</comment>
      <text xml:space="preserve">This page contains the essay like portions of [[../|Binary/C]] which were essay like and were moved out of the spec.

== ByteArray? ==
From the discussions in the CommonJS mailing list I do not recall anyone saying
&quot;[I] want to mutate a [sequence] with the Array api&quot;. I only recall the statements
&quot;[I] want a way to mutate a [sequence]&quot; and &quot;mutable, like an Array&quot;.
The decision to use the name &quot;ByteArray&quot; had nothing to do with wanting an Array
type sequence. It had to do with wanting to mutate a sequence, and Arrays being
the other type of list.

Looking into prior art the Array api does not fit. There is a more relevant term used in computing, the buffer.</text>
    </revision>
  </page>
  <page>
    <title>Binary/C/Show of hands</title>
    <id>24</id>
    <revision>
      <id>1326</id>
      <timestamp>2009-09-18T09:09:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">This page lists the various show of hands for points within the [[Binary/C]] proposal.

Blob and Buffer in what module:
:A) Blob and Buffer in require('binary');
:* Kris Kowal
:* Ash Berlin
:B) Blob in require('binary'); and Buffer in require('io');
:* Mario Valente
:C) Blob and Buffer as globals
:* Kris Kowal
:D) Blob as global and Buffer in require('io/buffer');
:* Daniel Friesen (MonkeyScript will provide global Blob whether it is standard or a non-standard addition)
----
Method parameter preference for new methods like .clear .fill .remove (methods based on existing js methods will keep the same parameters.
:A) offset, length (used in .splice .substr)
:* Daniel Friesen
:B) begin, end (used in .slice .substring, Java)
:* Kris Kowal
:C) named arguments
:* Ash Berlin
:C.1) &lt;code&gt;x.remove({ from: 4, to: 5 });&lt;/code&gt;
:* Daniel Friesen (alt to A)
:C.2) &lt;code&gt;x.remove({ begin: 4, end: 5 });&lt;/code&gt;
:C.3) &lt;code&gt;x.remove({ start: 4, end: 5 });&lt;/code&gt;

----
blob[idx]:
:A) Leave blob[idx] out of the standard (easier to implement in js-only rhino)
:B) Require implementations to implement blob[idx] (Array (and string?) methods will work on blobs)
----
Property used on String, Blob, Buffer, Streams, and so on to refer to the mode it is running in (binary or text) by returning the String or the Blob constructor. (If you can think of a better name, just add a new item)
:A) Content
:* Kris Kowal
:B) Value
:C) contentConstructor
:* Daniel Friesen
:D) contentPrototype
:E) content
:F) value
:G) Unit
:H) Element

[[Category:Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Binary/C/Unpacking</title>
    <id>25</id>
    <revision>
      <id>881</id>
      <timestamp>2009-09-10T02:48:09Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Binary/C/Unpacking]] to [[Binary/C/Unpacking]]</comment>
      <text xml:space="preserve">These methods are related to unpacking, they were  be removed from the proposal in favor of specifying that at a higher layer but are here for reference until we write a proposal for unpacking of binary data.

;blob.integerAt(offset, size=1, signed=false, networkEndian=false);
:Extracts an integer out of a blob. Arguments may control the byte size extracted whether the number is signed or unsigned, and whether or not the byte is in networkEndian or not. The default is to return a single unsigned byte in the form of an integer in the range 0..255.

;blob.floatAt(offset, size);
:Extracts a float out of a blob. This method requires a size argument of either 4 (floats) or 8 (doubles) to extract a number and should generate a TypeError if passed invalid params.

;blob.stringAt(offset, size, fromCharset=UTF-16);
:Extracts a string out from a blob. This method is similar to if you had done &lt;code&gt;blob.slice(offset, size).toString(fromCharset||&quot;UTF-16&quot;);&lt;/code&gt;.</text>
    </revision>
  </page>
  <page>
    <title>C API</title>
    <id>26</id>
    <revision>
      <id>2070</id>
      <timestamp>2010-02-02T15:08:07Z</timestamp>
      <contributor>
        <username>Wesgarland</username>
        <id>13</id>
      </contributor>
      <comment>GPSEE URL update</comment>
      <text xml:space="preserve">For C/C++ based JavaScript interpreters, being able to interface easily with C libraries is a big win because of all of the available functionality. Each JavaScript interpreter has its own bridge to C, but if there is some common API (possibly exposed at the JavaScript level as in ctypes), then this will make it much easier to share work between interpreters.

== Prior Art ==

* The JSAPI is the C API for the [https://developer.mozilla.org/en/SpiderMonkey SpiderMonkey] JavaScript engine https://developer.mozilla.org/En/SpiderMonkey/JSAPI_
* NSPR API Reference https://developer.mozilla.org/en/NSPR_API_Reference
* Ejscript http://www.ejscript.org/products/ejs/doc/api/native.html is a complete native API to create objects, classes and composite native types. It also supports loadable modules with backing native libraries.
* jsffi http://code.google.com/p/jslibs/wiki/jsffi is a module that allow you to call any symbol in a native module (dll/so).
* jsext &quot;Including C functions&quot; http://jsext.sourceforge.net/Including%20C%20functions.html
* js-ctypes https://wiki.mozilla.org/JSctypes is a foreign-function library for Mozilla’s privileged JavaScript. It provides C-compatible data types and allows JS code to call functions in shared libraries (dll, so, dylib) and implement callback functions.
* SpiderApe plugins http://spiderape.sourceforge.net/plugins/
* NSPR API Reference https://developer.mozilla.org/en/NSPR_API_Reference
* K7 http://github.com/sebastien/k7 Uses a system of C preprocessor macros to product cross-interpreter native modules.
* Flusspferd's C++ api http://docs.flusspferd.org/ provides a nicer (and slightly abstracted) C++ API to Spidermonkey
* [http://code.google.com/p/gpsee/ GPSEE] has an FFI-like layer which exposes generic native types/calls which are portable without JS-land changes between various UNIX and Linux platforms. Currently implemented for SpiderMonkey.

== Papers ==

* [http://scholar.google.com/scholar?cluster=9334403348999738260&amp;hl=en&amp;as_sdt=2000 C APIs in extension and extensible languages]

The authors of Lua make a convincing argument for the advantages of the Lua 5 C API, which evolved considerably and incompatibly from Lua 1.  They compare it with Python's API, Java's JNI API, and others.  The main idea is that using a stack to communicate between Lua and C solves 2 &quot;impedance mismatches&quot; between Lua and C: 

* Converting between the C type system and the Lua type system
* Manual memory management in C and automatic memory management in Lua (garbage collection).  For example, the Python API is very concerned about the details of garbage collection, which Lua avoids.  v8's API is also influenced strongly by its particular implementation of garbage collection.

Using the stack for communication also allows for a much smaller API, and they compare the sizes of the various APIs.</text>
    </revision>
  </page>
  <page>
    <title>Coding Standards</title>
    <id>27</id>
    <revision>
      <id>845</id>
      <timestamp>2009-09-10T02:15:01Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Coding Standards]] to [[Coding Standards]]</comment>
      <text xml:space="preserve">Code will be formatted according to this style guide:

http://javascript.crockford.com/code.html

Need to add details about namespaces and thread safety. Also, documentation and testing practices for things that help to describe and verify the API.</text>
    </revision>
  </page>
  <page>
    <title>Command Line</title>
    <id>28</id>
    <revision>
      <id>2876</id>
      <timestamp>2010-08-19T23:31:39Z</timestamp>
      <contributor>
        <username>Panzi</username>
        <id>130</id>
      </contributor>
      <text xml:space="preserve">= Command line processing =

Many server-side tools use a command line as their interface, and there should be a high-level way to deal with the arguments.

== Prior Art ==

* Flusspferd's [http://flusspferd.org/docs/js/flusspferd%20core/getopt.html getopt] module
* v8cgi's [http://code.google.com/p/v8cgi/wiki/API_GetOpt GetOpt] module
* Microsoft [http://msdn.microsoft.com/en-us/library/ss1ysb2a(VS.85).aspx WshArguments] object in the Windows Script Host environment.
** [http://code.google.com/p/curlie/source/browse/trunk/curlIE.wsf?spec=svn9&amp;r=7#39 CommandLine object], by Olivier Mengué, a generic API to Unix-style parsed arguments with a concrete JavaScript implementation on top of WshArguments ([http://code.google.com/p/curlie/source/browse/trunk/curlIE.wsf?spec=svn9&amp;r=7#163 CScriptCommandLine]).
* Python's [http://docs.python.org/library/optparse.html optparse] module provides a reasonably powerful, flexible and full-featured option parser.
* [http://bitbucket.org/panzi/javascript-utils/src/tip/optparse.js optparse.js]: inspired by Python's optparse module but with some distinct differences.
* Narwhal's &quot;args&quot; module [http://github.com/tlrobinson/narwhal/blob/master/lib/narwhal.js example usage], [http://github.com/tlrobinson/narwhal/blob/master/lib/args.js the module]</text>
    </revision>
  </page>
  <page>
    <title>Concurrency</title>
    <id>29</id>
    <revision>
      <id>1940</id>
      <timestamp>2010-01-04T05:59:55Z</timestamp>
      <contributor>
        <username>Andychu</username>
        <id>62</id>
      </contributor>
      <comment>Add NodeJS</comment>
      <text xml:space="preserve">One should probably try to follow the [http://www.whatwg.org/specs/web-workers/current-work/ WebWorkers API] as far as it makes sense on the server.

However, WebWorkers cannot share state, they can only communicate via messages, so if traditional threads are desired they are not acceptable.

And traditional threads are generally considered deprecated in modern language design. The WebWorkers design was intentional.

* [http://www.synchro.net/ Synchronet's] load() method supports creating background tasks/threads and implements a bidirectional Queue object which may be used to communicate with the concurrently executing child script: http://synchro.net/docs/jsobjs.html#Queue

A possible alternative is a stronger eventing dispatch mechansim. Actionscript did lots of good work in this area. [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/ejs.events-classes.html Here] is a set of event, listener and timer classes from Ejscript. These can be retro fitted to interpreters for which threads and threading are problematic or impossible.

* JSAPI threading https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference#Threading
* NSPR threads https://developer.mozilla.org/en/NSPR_API_Reference#Threads
* NSPR in general https://developer.mozilla.org/en/NSPR_API_Reference
* JavaScript Strands adds coroutine and cooperative threading support to the JavaScript language http://www.xucia.com/strands-doc/index.html
* Erlang-style concurrency with JavaScript 1.7 http://www.beatniksoftware.com/erjs/index.html
* Threading in Javascript 1.7 http://www.neilmix.com/2007/02/07/threading-in-javascript-17/
* [http://nodejs.org/ NodeJS] makes a strong argument about doing concurrent I/O with an event loop.  The implementation uses threadpools to work around synchronous APIs, but these are all hidden from the user.  The user APIs are all asynchronous using callbacks and promises.</text>
    </revision>
  </page>
  <page>
    <title>CommonJS</title>
    <id>30</id>
    <revision>
      <id>2857</id>
      <timestamp>2010-07-15T10:49:35Z</timestamp>
      <contributor>
        <username>Zumbrunn</username>
        <id>5</id>
      </contributor>
      <comment>Undo revision 2856 by [[Special:Contributions/Adam holmes|Adam holmes]] ([[User talk:Adam holmes|Talk]])</comment>
      <text xml:space="preserve">Welcome to [http://commonjs.org CommonJS], a group with a goal of building up the JavaScript ecosystem for web servers, desktop and command line apps and in the browser.

This wiki is a starting point for collecting up ideas, links and any draft API suggestions for the [http://groups.google.com/group/commonjs CommonJS group]. Discussions occur on that mailing list and [http://log.serverjs.org/mochabot/join on IRC (#commonjs on freenode)].

== Meta ==

* [[Introduction]]
* [[FAQ]]
* [[Process]]
* [[Target Platforms]]
* [[Coding Standards]]

== Current Efforts ==

This is a list of issues currently being discussed / standardized. They come from the &quot;Low level&quot; department, as we need to have a solid basics prior to building a tower.

# [[Global|Uniform Baseline / Globals]] (discussion)
# [[Modules]] ([[Modules/1.1.1|1.1.1]])
## &lt;code&gt;binary&lt;/code&gt;: [[Binary]] Data Objects (byte arrays and/or strings) (proposals, discussion, early implementations)
## &lt;code&gt;encodings&lt;/code&gt;: [[Encodings]] and character sets (proposals, discussion, early implementations)
## &lt;code&gt;io&lt;/code&gt;: [[IO|I/O Streams]] (proposals, discussion)
## &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;fs-base&lt;/code&gt;: [[Filesystem]] (proposals, discussion, early implementations)
## &lt;code&gt;system&lt;/code&gt;: [[System]] Interface (stdin, stdout, stderr, &amp;c) ([[System/1.0|1.0]], amendments proposed)
## &lt;code&gt;assert&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;: [[Unit Testing]] ([[Unit_Testing/1.0|1.0]], amendment proposals pending)
## &lt;code&gt;sockets&lt;/code&gt;: [[Sockets|Socket I/O]] TCP/IP sockets (early proposals)
## &lt;code&gt;event-queue&lt;/code&gt;: [[Reactor]] Reactor/Event Queue (early proposals)
## &lt;code&gt;worker&lt;/code&gt;: [[Worker]] Worker (concurrent shared nothing process/thread) (proposal)
## &lt;code&gt;console&lt;/code&gt;: [[console]] (proposal)
# [[Packages]] ([[Packages/1.0|1.0]])
# [[JSGI|Web Server Gateway Interface (JSGI)]] (proposals, discussion, early implementations)
# [[Promises]] (proposal)

* [[Status|Pending Business / Calls for Action / Status Report]]

== Future Efforts ==

=== Low-level APIs ===

This is the collection of APIs that we'd like to see behaving consistently across JavaScript interpreters.

* [[Runtime Services|Language and Runtime Services]]
* [[Logging]]
* [[RDBMS|Relational database interface]]
* ResultSets (collections of data maybe from RDBMS, maybe from other sources)
* [[Concurrency]]
* [[String IO|String / ByteString I/O]]
* [[C API|C unified API]] to our Target Platforms
* [[Subprocess]]es (popen)

=== High-level APIs ===

This is the collection of APIs that implement common functionality on top of the low-level API.

* [[HTTP Client|HTTP client]] APIs
* [[Email]]
* [[XMPP|Jabber (XMPP)]]
* [[i18n|Internationalization]]
* [[Promise Manager]]
* [[Command Line|Command line processing]] 

== Implementations ==
{{ImplementationsTable
|standards={{#ask: [[Category:Spec]] [[Is standard::yes]] | link=none }}
|non-standards={{#ask: [[Category:Spec]] [[Is standard::no]] [[Has implementations::yes]] | link=none }}
}}

In development:
* mob is implementing SecurableModules in Ejscript http://www.ejscript.org
* pmuellr posted a sample loader for SecurableModules: http://wiki.github.com/pmuellr/modjewel
* atul varma has a SecurableModule implementation for Python/Spidermonkey: http://hg.toolness.com/pydertron/raw-file/tip/docs.html
* [[User: Alexandre.Morgaut|Alexandre]] implements several commonJS standards in Wakanda (SquirrelFish) http://www.wakandasoft.com
* [[User: Fbraem|Franky Braem]] tries to implement several commonJS standards in GLUEscript: http://gluescript.sf.net.
* Titanium is in the process of adding support for CommonJS. http://www.appcelerator.com

== Tests ==

* [http://github.com/280north/narwhal/tree/master/tests/commonjs/ CommonJS tests] compatible with [http://github.com/280north/narwhal/tree/master/lib/test/ this test framework].

== Further Reading ==

* [[Existing APIs]]
* [[Infrastructure]]
* [[High Level Tools]]
* [[Random Links]]

== Wiki ==
* [[Dumps]]</text>
    </revision>
  </page>
  <page>
    <title>DateTime</title>
    <id>31</id>
    <revision>
      <id>2144</id>
      <timestamp>2010-03-10T10:39:54Z</timestamp>
      <contributor>
        <username>Oberhamsi</username>
        <id>81</id>
      </contributor>
      <text xml:space="preserve">= Date and Time =

EcmaScript already supports a wide range of functions handling Date, see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date

but those kind of setters/getters are not very convinient when working with DateTimes. an easy way to e.g. add/substract timeranges, calculate time-diffs, etc. would be beneficial.

problems to solve
* outputting / parsing datetime
* date calculations / manipulating
* json date extension (see crockford's json module)?

including TZ conversion? naive datetime's - not knowing about TZ - are easier to handle, though it seems JS has native aware datetime objects. utc &amp; localtime.

== Prior Art ==
* RingoJS, minimal date extensions http://github.com/ringo/ringojs/blob/master/modules/core/date.js
e.g., 
 Date.diff
 Date.getTimespan
 Date.equals 

* datejs, clientside library. nifty &amp; big. http://code.google.com/p/datejs/
&lt;source&gt;
// Get today’s date
Date.today();
// Add 5 days to today
Date.today().add(5).days();
// Get Friday of this week
Date.friday();
// Get March of this year
Date.march();
// Is today Friday?
Date.today().is().friday();  // true|false
&lt;/source&gt;

* [http://api.dojotoolkit.org/jsdoc/1.3/dojo.date dojo.date] and [http://api.dojotoolkit.org/jsdoc/1.3/dojo.date.locale dojo.date.locale]  (dojo.date.stamp is obsoleted by ES5)
** dojo.date provides convenience methods
** dojo.date.locale provides format and parse functions which are data driven off the [http://unicode.org/cldr Unicode CLDR project], fully localized client-side, downloading localizations only as needed.  Support for hundreds of languages/variants.
&lt;source&gt;
&gt;&gt;&gt; dojo.date.locale.format(myDate, {selector: “date”, formatLength: “long”}) // en-us
 “June 28, 2008″

&gt;&gt;&gt; dojo.date.locale.format(myDate, {selector: “date”, formatLength: “long”}) // zh-cn
“2008年6月28日”
&lt;/source&gt;

** [http://api.dojotoolkit.org/jsdoc/1.3/dojox.date dojox.date] has experimental support for non-Gregorian calendars as well as Unix- and PHP-style formatting.

* Matthew Eernisse implemented a [http://js.fleegix.org/plugins/date/date Date-like class] in JS to deal with the Olson table client-side, as well as code to parse and preprocess the Olson table.

* ...</text>
    </revision>
  </page>
  <page>
    <title>Doctools</title>
    <id>32</id>
    <revision>
      <id>1085</id>
      <timestamp>2009-09-10T20:02:34Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Doctools]] to [[Doctools]]</comment>
      <text xml:space="preserve">= Documentation Tools =

A major output of CommonJS will be an API specification and possibly some user docs to help people get started with a CommonJS-compatible platform.

== Prior Art ==

* http://code.google.com/p/jsdoc-toolkit/  (requires Java)
* Ejscript has a javadoc style doc generator called ejsmod. This [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/index.html doc], was generated with ejsmod.
* http://scriptdoc.org/ (no public tooling)
* http://www.naturaldocs.org/ (requires Perl)
* [http://code.google.com/p/code-illuminated/ Code Illumionated] uses an approach with nice typography to document code.
* [http://sphinx.pocoo.org/ Sphinx] is a Python-based tool for building documentation packages based on ReStructured Text files. It can generate HTML and PDF. [http://www.blueskyonmars.com/projects/paver/ Paver] has support for Sphinx to be able to maintain example code separate from the documentation files.</text>
    </revision>
  </page>
  <page>
    <title>Email</title>
    <id>33</id>
    <revision>
      <id>1836</id>
      <timestamp>2009-12-08T14:59:11Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <comment>PHP Mail Object APIs</comment>
      <text xml:space="preserve">= Email APIs =

Sending email is an extremely common server side activity and must be supported. This means providing easy mechanisms for generating a MIME message and sending email via an SMTP server (or possibly via a local command).

== Prior Art ==
* Microsoft [http://msdn.microsoft.com/en-us/library/aa488400(EXCHG.65).aspx CDO.Message] object. Used in classic ASP, WSH, HTAs.
* Netscape Server [http://research.nihonsoft.org/javascript/ServerReferenceJS12/sendmail.htm JavaScript 1.2 Sendmail API]
* PHP [http://pear.php.net/manual/en/package.mail.mail-mime.php PEAR Mail_Mime] : [http://pear.php.net/manual/en/package.mail.mail-mime.example.php Sample]
* PHP [http://framework.zend.com/manual/en/zend.mail.html Zend Mail]</text>
    </revision>
  </page>
  <page>
    <title>Encodings/A/A</title>
    <id>34</id>
    <revision>
      <id>2021</id>
      <timestamp>2010-01-24T01:27:39Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>fixed recursive move error</comment>
      <text xml:space="preserve">#REDIRECT [[Encodings/A]]</text>
    </revision>
  </page>
  <page>
    <title>Encodings/A/OldClass</title>
    <id>35</id>
    <revision>
      <id>2018</id>
      <timestamp>2010-01-24T01:24:55Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>moved [[Encodings/OldClass]] to [[Encodings/A/OldClass]]:&amp;#32;putting in the proposal name space (non-versioned, lettered)</comment>
      <text xml:space="preserve">=== Class: Converter ===

There also should be a class enc.Converter for more advanced conversion.

Please note that the interface is ''one way''. Despite the fact that it has two methods, it's ''one way''. It only supports ''encoding'', '''no''' decoding! Multiple people have got that wrong when glancing over it, so it's emphasised here.

; [Constructor] Converter(from, to)
: Where from and to are the encoding names.
; [Method] write(byteStringOrArray)
: Convert input from a ByteString or ByteArray. The results are stored in an internal buffer, and also those parts of byteStringOrArray that could not be converted (for multi-byte encodings, in a separate buffer).
: Returns nothing.
; [Method] read([byteArray,] [maximumSize])
: Read maximumSize bytes or as many bytes as available out of the internal buffer. If byteArray is specified, the data is ''appended'' to that ByteArray.
: Returns a ByteString if byteArray is not specified, or byteArray itself otherwise.
; [Method] close()
: Close the stream. Throws an exception if there was a conversion error (specifically, a partial multibyte character).
: Returns nothing and takes no parameters.

Example usage:

  Converter = require('encodings').Converter
  converter = new Converter('iso-8859-1', 'utf-32')
  converter.write(input) // input is a ByteString
  output = converter.read() // output is a ByteString
  converter.close()</text>
    </revision>
  </page>
  <page>
    <title>Existing APIs</title>
    <id>36</id>
    <revision>
      <id>2113</id>
      <timestamp>2010-02-19T00:32:12Z</timestamp>
      <contributor>
        <username>Lucideer</username>
        <id>76</id>
      </contributor>
      <comment>It's a closed source project, but could still act as inspiration I suppose</comment>
      <text xml:space="preserve">Links to existing server-side JS APIs which may act as an inspiration for some coordinated progress.

* [http://code.google.com/p/piston/ Piston]
* [http://code.google.com/p/chironjs/ chironjs]
* [http://code.google.com/p/v8cgi/w/list v8cgi]
* [http://code.google.com/p/jslibs/wiki/JSLibs JSLibs]
* [http://www.ejscript.org/products/ejs/doc/ref/ejs/index.html EJScript]
* [http://www.ejscript.org/products/ejs/doc/api/ejscript/index.html EJScript API]
* [http://docs.persvr.org/documentation/server-side-js Persevere]
* [http://jsext.sourceforge.net/Object%20reference.html JSExt]
* [http://www.jsdb.org/reference.html jsdb]
* [http://www.jnext.org/index.html jnext]
* [http://www.modjs.org/ modjs]
* [http://helma.zumbrunn.com/reference/ helma]
* &lt;s&gt;http://www.wxjavascript.net/modules.html wxJavaScript&lt;/s&gt; (Replaced by [http://gluescript.sf.net GLUEscript])
* [http://appjet.com/docs/librefbrowser appjet]
* [http://www.10gen.com/apidocs/ 10gen]
* [http://www.aptana.com/reference/jaxer/api/Jaxer.index-frame.html Jaxer API]
* [http://freebaseapps.com/ Freebase Apps]
* [http://github.com/mvalente/starbucks/tree/master STARBUCKS SSJS Web Dev Framework] (uses JSLibs, moving to Jaxer?)
* [http://monkeyscript.org/ MonkeyScript] (uses JSLibs)
* [http://spiderape.sourceforge.net/ SpiderApe]
* [http://synchro.net/docs/jsobjs.html Synchronet]
* [http://www.adobe.com/devnet/acrobat/javascript.html JavaScript for Acrobat]
* &lt;del&gt;http://www.adobe.com/livedocs/flashm..._cs_asd_1.html&lt;/del&gt; (dead)
* [http://tinyclouds.org/node/ Node]
* [http://tinyclouds.org/node/api.html Node API]
* [http://www.page.ca/~wes/opensource/gpsee/ GPSEE Module Documenation]
* [http://gluescript.sf.net GLUEscript]
* [http://dev.opera.com/libraries/unite/docs/ Unite API]</text>
    </revision>
  </page>
  <page>
    <title>FAQ</title>
    <id>37</id>
    <revision>
      <id>1968</id>
      <timestamp>2010-01-12T03:22:28Z</timestamp>
      <contributor>
        <username>Pbannister</username>
        <id>65</id>
      </contributor>
      <comment>/* Why not Perl/PHP/Python/Ruby? */</comment>
      <text xml:space="preserve">=== Why use JavaScript on the server? ===
As the scripting language of the web browser, JavaScript is and will be familiar to many developers. 
The group of developers acquainted and fluent with JavaScript likely will only increase over time.
There is much developer productivity to be gained by re-using that fluency.

In addition, using the same language on both the client and server sides may allow for some degree of code sharing.

=== Why not Perl/PHP/Python/Ruby? ===
While entirely worthy (to varying degrees) languages not in the browser will always be familiar to a subset of web application developers, where JavaScript fluency is more universal. 
When a higher order language is useful, JavaScript is roughly comparable to the other higher order alternatives.
(Naturally, opinions will differ as to which is &quot;best&quot;.)
When developer fluency is factored in, JavaScript becomes a pragmatic choice.

Note that JavaScript inherits notions from some of the more interesting object-oriented languages, including [http://en.wikipedia.org/wiki/Self_(programming_language) Self], [http://en.wikipedia.org/wiki/Scheme_(programming_language) Scheme], and Prototype - all with a C/C++/Java-like syntax.

=== If sharing code is the objective, then why not compile language X to JavaScript to send to the browser? ===

Debugging compiled code is not an enjoyable experience. Often, the abstraction layer between language X and JavaScript also has some holes then you end up needing to plug with hand-crafted JS (and not just stock JS, but JS that is designed to interface with that library). By using JavaScript all the way across, there are no such leaks.

Also, there can be some impedance mismatch between the prototype-based object model in JavaScript and the class-based object models of other languages.

=== Is there a bonus reason to use JavaScript on the server? ===

Why yes, I'm glad you asked. JavaScript is powering increasingly complex applications in the browser. This has caused browser vendors to work hard on their JavaScript performance. Server side JavaScript has the potential to significantly outperform other common dynamic languages because of this work.</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/File/A</title>
    <id>38</id>
    <revision>
      <id>1092</id>
      <timestamp>2009-09-10T20:14:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[Filesystem/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/A]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem</title>
    <id>39</id>
    <revision>
      <id>2557</id>
      <timestamp>2010-04-06T12:26:59Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <comment>/* Prior Art */</comment>
      <text xml:space="preserve">'''STATUS: PROPOSALS, DISCUSSION'''

== Requirements/Proposals ==

* [[Filesystem/A]] Proposal
** [[Filesystem/A/0]] Proposal – a low level minimal proposal on which FS/A can be implemented using pure JS
* [[/Hierarchy|File API Class hierarchy proposal]]
* [[IO/B/Filesystem/Raw]] and [[IO/B/Filesystem]] of the [[IO/B]] proposal

== Questionnaires and show of hands ==

* [[/Names|File API name preferences questionnaire]]
* Summary/Comparison of current File APIs used by JS engines: [http://spreadsheets.google.com/pub?key=p9uiX8MUHeTiP0kPT591RUw CommonJS File Object Survey]
* [[/Show of hands/]]
* [[/Join/]]

== Prior Art ==

* Microsoft [http://msdn.microsoft.com/en-us/library/z9ty6h50.aspx Scripting.FileSystemObject]. Used in classic ASP, WSH, HTAs.
* [http://www.mozilla.org/js/js-file-object.html JavaScript File object proposal] (~1998)
* [https://developer.mozilla.org/En/SpiderMonkey:File_object Spidermonkey File object]
* [http://synchro.net/ Synchronet] provides a [http://synchro.net/docs/jsobjs.html#File File Class] that was originally inspired by SpiderMonkey's jsfile.c, but has been widely used and enhanced over the years.
* Ejscript's [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/ejs.io-File.html File class] is still evolving, but is fairly comprehensive. It supports stackable streams such as BinaryStream, StringStream. It can also do I/O to and from a ByteArray class.
* [http://jsext.sourceforge.net/JSEXT1.File.html JSExt.File]
* [http://code.google.com/p/jslibs/wiki/jsio jslibs jsio module]
* [http://www.wxjavascript.net/io/index.html wxJavascript IO module]
* v8cgi has a [http://code.google.com/p/v8cgi/wiki/API#File_functions File] and [http://code.google.com/p/v8cgi/wiki/API#Directory_functions Directory] interfaces
* helma has two File apis. One [http://helma.zumbrunn.com/reference/File.html deprecated] and one [http://helma.zumbrunn.com/reference/helma.File.html current]
* adobe's extendscript has a File constructor.Documentation is difficult to find online.
* generic [http://koberg.com/ripple/docs/api/ collection/document resource] (java) api (work in process)
* Opera Software's [http://dev.opera.com/articles/view/file-i-o-api-for-widgets/ File I/O API for widgets], which will probably be standardized by the [http://www.w3.org/2006/webapi/ W3C Web API Working Group].
* [http://www.w3.org/TR/file-upload/ W3C File Upload] (Last version: October 2006)
* [http://www.w3.org/TR/dap-api-reqs/#file-system W3C - Device APIs Requirements - File System] (Last version: October 2009)
* [http://www.w3.org/TR/FileAPI/ W3C File API] (Last version: November 2009)

=== Inspiration  ===

* (Python) PEP on new File IO http://www.python.org/dev/peps/pep-3116/
* Java File API http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html
* Java Output API http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileOutputStream.html
* Java Input API http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileInputStream.html
* E Secure File API http://www.erights.org/javadoc/java/io/File.html
* Joe-E Secure File System API http://www.cs.berkeley.edu/~daw/joe-e/api/org/joe_e/file/Filesystem.html
* Python Path API http://docs.python.org/library/os.path.html
* Ruby File API http://www.ruby-doc.org/core/classes/File.html
* Ruby IO API http://www.ruby-doc.org/core/classes/IO.html
* Perl Path::Class http://search.cpan.org/perldoc?Path::Class
* PHP Filesystem http://php.net/manual/book.filesystem.php

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/a1b175c20ad61ed7 writ or write?]
* [http://groups.google.com/group/commonjs/browse_thread/thread/5ed547baaba11f6c Filesystem API - Hobgoblin of little minds in little bike sheds with little bicycles]
* [http://groups.google.com/group/commonjs/browse_thread/thread/eb721e00452c4d02 Filesystem API: stat]
* [http://groups.google.com/group/commonjs/browse_thread/thread/abef650ba0c4f76d Filesystem API - Path(path, &lt;nowiki&gt;[fs]&lt;/nowiki&gt;)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f71e34667e1d5bde Filesystem API, Pure-JS glob implementation]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c4af0c8d278fd34b Return value of return? Partial writing?]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem/A</title>
    <id>40</id>
    <revision>
      <id>2788</id>
      <timestamp>2010-05-24T00:00:58Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>added NarwhalNode to list of implementations</comment>
      <text xml:space="preserve">{{Spec
|status=proposal, discussion
|implementations=NarwhalRhino=draft 4 in 0.1, NarwhalNode=0.5, RingoJS=minus globbing
}}

Proposal A, Draft 6

= Overview =

The &quot;fs&quot; module provides a file system API for the manipulation of paths, directories, files, links, and the construction of file streams.  The [[IO|IO stream API]] is beyond the scope of this specification.

''Note: Other objects, apart from the &quot;fs&quot; module exports, may claim to conform to this specification.''

This specification builds on the normal primitives exported by &quot;fs-base&quot; specified in [[Filesystem/A/0]].  All methods implemented by &quot;fs-base&quot; must be exported by and override methods of this module.

== Security ==

Objects implementing the File System API, including the &quot;file&quot; module object, are capability bearing objects that carry and mediate authority to read and write to the underlying storage.  As such, the &quot;fs&quot; module can return other objects that implement and attenuate the File System API for sandboxing.  Furthermore, streams returned by the file system object are implicitly attenuated to only give the receiver authority to manipulate the given file, without knowledge of the path on which it resides or access to references that would permit it to manipulate other parts of the file system.

== Regarding Paths ==

Many methods accept paths as arguments.  In every case, the path may be any object that is coercible to a &lt;code&gt;String&lt;/code&gt; with the &lt;code&gt;String&lt;/code&gt; constructor, that defers to &lt;code&gt;toString&lt;/code&gt; for most objects.  This includes &lt;code&gt;Path&lt;/code&gt; objects.

= Specification =

== Files ==

; open(path, mode|options)
: returns an [[IO]] stream that supports an appropriate interface for the given options and mode, which include reading, writing, updating, byte, character, unbuffered, buffered, and line buffered streams.
:* path: any value coercible to a String, including a Path, that can be interpreted as a fully-qualified path, or a path relative to the current working directory.
:* mode String: any subtring of &quot;rwa+bxc&quot; meaning &quot;read&quot;, &quot;write&quot;, &quot;append&quot;, &quot;update&quot;, &quot;binary&quot;, and &quot;exclusive&quot; flags respectively, in any order.
:* options
:** mode String: conforming to the above mentioned mode string pattern
:** charset String: an IANA, case insensitive, charset name.  &lt;code&gt;open&lt;/code&gt; must throw a ('''TODO''') error if the charset is not supported.  The &lt;code&gt;ascii&lt;/code&gt; and &lt;code&gt;utf-8&lt;/code&gt; charsets must be supported.
:** read Boolean: open for reading, do not create, set position to beginning of the file, throw an error if the file does not exist.
:** write Boolean: open for writing, create or truncate, set position to the beginning of the file.
:** append Boolean: open for appending, create if it doesn't exist, do not truncate, set position to end of the file.
:** update Boolean: open for updating, create if it doesn't exist, do not truncate, set position to the beginning of the file. 
:** binary Boolean return a raw stream instead of a buffered, charset encoded, text stream.
:** exclusive Boolean: open for write only if it does not already exist, otherwise throw an error.
: The &quot;open&quot; function mediates the construction of various kinds of streams.  As &quot;open&quot; is the only method with the authority to manipulate files, it constructs these types on behalf of a potentially unpriviledged caller.  Stream constructors are not directly callable in a secure sandbox, so where and how these stream types are implemented is beyond the necessary scope of this specification.  The &quot;open&quot; function always creates a byte stream, and by default wraps that in a textual IO wrapper.  &quot;open&quot; returns a stream resulting from the following algorithm:
:# create a &quot;raw&quot; byte stream.  If &quot;x&quot; mode (with either &quot;w&quot; or &quot;a&quot; mode), only open if the file does not already exist.  Create the file and open the stream atomically.
:#* if &quot;r&quot; mode, make &quot;raw&quot; a ByteReader
:#* if &quot;w&quot; mode, make &quot;raw&quot; a ByteWriter
:#* if &quot;u&quot; mode, make &quot;raw&quot; a ByteUpdater
:# if &quot;+&quot;, seek to end.
:# if not &quot;b&quot; mode, return &quot;raw&quot;.
:# return a wrapper encoded/decoded string stream, wrapped around a buffered stream, wrapped around &quot;raw&quot;. 
:#* if &quot;r&quot; mode, wrap &quot;raw&quot; in a TextReader
:#* if &quot;w&quot; mode, wrap &quot;raw&quot; in a TextWriter
:#* if &quot;u&quot; mode, wrap &quot;raw&quot; in a TextUpdater

; read(path, (mode|options)_opt)
: opens, reads, and closes a file, returning its content.  Equivalent to &lt;code&gt;open(source, mode).read()&lt;/code&gt;.

; write(path, content String|Binary, (mode|options)_opt)
: opens, writes, flushes, and closes a file with the given content.  If the content is a ByteArray or ByteString, the binary mode is implied.  Equivalent to &lt;code&gt;open(source, mode + &quot;w&quot; + (content instanceof Binary ? &quot;b&quot; : &quot;&quot;)).write(content).flush()&lt;/code&gt;, for mode Strings.

; copy(source, target)
: reads one file and writes another in byte mode.  Equivalent to &lt;code&gt;open(source, &quot;b&quot;).copy(target, &quot;b&quot;)&lt;/code&gt;

; rename(path, name String)
: Changes the name of a file at a given path.  This differs from move in that the target is relative to the source instead of the current working directory. This method in particular should be implemented by the native &quot;fs-base&quot; module overriding any pure JavaScript implementation, if possible.

; move
: [[Filesystem/A/0]]

; remove
: [[Filesystem/A/0]]

; touch
: [[Filesystem/A/0]]

== Directories ==

; makeDirectory
: [[Filesystem/A/0]]

; removeDirectory
: [[Filesystem/A/0]]

; makeTree(path)
: Creates the directory specified by &quot;path&quot; including any missing parent directories.

; removeTree(path)
: Removes whatever exists at the given path, regardless of whether it is a file, direcotory, or otherwise.  If the path refers to a directory, but not a symbolic link to a directory, calls &lt;code&gt;removeTree&lt;/code&gt; on each member of the directory.

; copyTree(source, target)
: copies files from a source path to a target path, copying the files of the source tree to the corresponding locations relative to the target, copying but not traversing into symbolic links to directories.

=== Listing ===

; list(path) Array * String
: [[Filesystem/A/0]]

; listTree(path) Array * String
: returns an Array that starts with the given path, and all of the paths relative to the given path, discovered by a depth first traversal of every directory in any visited directory, reporting but not traversing symbolic links to directories, in lexically sorted order within directories.  The first path is always &quot;&quot;, the path relative to itself.

; listDirectoryTree(path) Array * String
: returns an Array that starts with the given directory, and all the directories relative to the given path, discovered by a depth first traversal of every directory in any visited directory, not traversing symbolic links to directories, in lexically sorted order within directories.

=== Globbing ===

; glob(pattern)
: returns an Array of all paths that match the given glob pattern from the current working directory.
: glob patterns may include asterisks for 0 or more of any character except directory separator matches, question marks for exactly one of any character except directory separator matches, non-delimited square bracket notation for unions and escapes, comma delimited curly brace notation for nestable unions of substrings, and double asterisk for 0 or more of any character including directory separator matches (by way of a depth first traversal of intervening directories, visiting but not following symbolic links).

; match(path, pattern)
: returns whether a path matches a given glob pattern.

; escape(path)
: returns a path or path component as a glob pattern that would only match the given path component.

=== Path Objects ===

For each of the previous &quot;list&quot; and &quot;glob&quot; methods, there is a corresponding &quot;-Paths&quot; method that returns Path object instances instead of Strings.

; listPaths(path) Array * Path
; listTreePaths(paths) Array * Path
; listDirectoryTreePaths(paths) Array * Path
; globPaths(path) Array * Path

=== Iterator Objects ===

; iterate(path) Iterator * String
: returns an iterator that lazily browses a directory, backward and forward, for the base names of entries in that directory.

; iteratePaths(path) Iterator * Path
: returns an iterator that lazily browses a directory, backward and forward, for the full Paths of entries in that directory, joined on the given path.

Iterator objects have the following members:

; next() String or Path
: returns the next path in the iteration or throws a StopIteration if there is none.

; prev() String or Path
: returns the previous path in the iteration or throws a StopIteration if there is none.

; iterator()
: returns itself

; close()
: closes the iteration.  After calling close, all calls to next and prev must throw StopIteration.

Directory iterators also support the following Array methods:

* forEach
* map
* every
* some
* reduce
* reduceRight

== Links ==

Symbolic and hard links must not be emulated with Windows Shortcuts.

; link(source, target)
: [[Filesystem/A/0]]

; hardLink(source, target)
: [[Filesystem/A/0]]

; readLink(path) String
: [[Filesystem/A/0]]

== Tests ==

; exists(path)
: [[Filesystem/A/0]]

; isFile(path)
: [[Filesystem/A/0]]

; isDirectory(path)
: [[Filesystem/A/0]]

; isLink(path)
: [[Filesystem/A/0]]

; isReadable(path) Boolean
: [[Filesystem/A/0]]

; isWritable(path) Boolean
: [[Filesystem/A/0]]

; same(source, target) Boolean
: [[Filesystem/A/0]]

== Attributes ==

; size(path)
: [[Filesystem/A/0]]

; lastModified(path) Date
: [[Filesystem/A/0]]

== Extended Attributes (optional) ==

Extended attribute methods may be defined on systems that may support the feature on some volumes.

; getAttribute(path, key String, default ByteString) ByteString
: [[Filesystem/A/0]]

; setAttribute(path, key String, value ByteString)
: [[Filesystem/A/0]]

; removeAttribute(path, key String)
: [[Filesystem/A/0]]

; discardAttribute(path, key String)
: Removes the extended attribute for a given key, if there is a corresponding attribute.

; getAttributes(path) Object
: Returns an Object that maps all of the extended attribute keys to their corresponding values.

; listAttributeNames(path) Array * String
: [[Filesystem/A/0]]

== Security ==

; owner(path) String
: [[Filesystem/A/0]]

; changeOwner(path, name String)
: [[Filesystem/A/0]]

; permissions(path) Permissions
: [[Filesystem/A/0]]

; changePermissions(path, permissions Permissions)
: [[Filesystem/A/0]]

== Paths ==

; workingDirectory() String
: [[Filesystem/A/0]]

; changeWorkingDirectory(path)
: [[Filesystem/A/0]]

; workingDirectoryPath() Path
: returns the current working directory as an absolute Path object

=== Paths as Text ===

; join(...) String
: takes a variadic list of path Strings, joins them on the file system's path separator, and normalizes the result. [[Filesystem/Join|details]]

; split(path) Array * String
: returns an array of path components.  If the path is absolute, the first component will be an indicator of the root of the file system; for file systems with drives (such as Windows), this is the drive identifier with a colon, like &quot;c:&quot;; on Unix, this is an empty string &quot;&quot;.  The intent is that calling &quot;join.apply&quot; with the result of &quot;split&quot; as arguments will reconstruct the path.

; normal(path) String
: removes '.' path components and simplifies '..' paths, if possible, for a given path.

; absolute(path) String
: returns the absolute path, starting with the root of this file system object, for the given path, resolved from the current working directory.  If the file system supports home directory aliases, absolute resolves those from the root of the file system.  The resulting path is in normal form.  On most systems, this is equivalent to expanding any user directory alias, joining the path to the current working directory, and normalizing the result.  &quot;absolute&quot; can be implemented in terms of &quot;workingDirectory&quot;, &quot;join&quot;, and &quot;normal&quot;.

; canonical(path) String
: [[Filesystem/A/0]]

; readLink(path) String
: returns the text of a symbolic link at a given path.  Throws a '''TODO''' error if there is no accessible symbolic link at the given path.

; directory(path) String
: returns the path of a file's containing directory, albeit the parent directory if the file is a directory.  A terminal directory separator is ignored.

; base(path, extension_opt String) String
: returns the part of the path that is after the last directory separator.  If an extension is provided and is equal to the file's extension, the extension is removed from the result.

; extension(path) String
: returns the extension of a file.  The extension of a file is the last dot (excluding any number of initial dots) followed by one or more non-dot characters. Returns an empty string if no valid extension exists.  [http://github.com/kriskowal/narwhal-test/blob/master/src/test/file/extension.js unit test].

; resolve(...)
: a function like &quot;join&quot; except that it treats each argument as as either an absolute or relative path and, as is the convention with URL's, treats everything up to the final directory separator as a location, and everything afterward as an entry in that directory, even if the entry refers to a directory in the underlying storage.  Resolve starts at the location &quot;&quot; and walks to the locations referenced by each path, and returns the path of the last file.  Thus, resolve(file, &quot;&quot;) idempotently refers to the location containing a file or directory entry, and resolve(file, neighbor) always gives the path of a file in the same directory.  &quot;resolve&quot; is useful for finding paths in the &quot;neighborhood&quot; of a given file, while gracefully accepting both absolute and relative paths at each stage. [http://github.com/kriskowal/narwhal-test/blob/master/src/test/file/resolve.js unit test].

; relative(source, target_opt)
: returns the relative path from one path to another using only &quot;..&quot; to traverse up to the two paths' common ancestor.  If the target is omitted, returns the path to the source from the current working directory.

=== Path Type ===

Path instances inherit from the String prototype.

; [new] Path(path...) Path
: returns a Path object.  Path is a chainable shorthand for working with paths.  Path objects have no more or less authority to manipulate the file system that produces them.  If multiple arguments are passed to the Path constructor, they are joined to construct the corresponding path.  If an argument is an Array, as ascertained by &lt;code&gt;Array.isArray&lt;/code&gt;, it must conform to normal output of &lt;code&gt;split&lt;/code&gt;, meaning that if the first value is a drive or root, the components are joined absolutely, and otherwise they are joined relatively.

; path(path...) Path
: a shorthand for creating a new Path that does not use the &quot;new&quot; keyword, and also can be more easily applied variadically with the apply and call methods.

The path constructor accepts as its first argument either a String, Path, or Array.  If the path is an Array (as tested by Array.isArray, not merely typeof path == &quot;array&quot;), it must conform to the specification for values returned by &quot;fs.split&quot;.

Every path object has the members '''absolute''', '''base''', '''canonical''', '''directory''', '''normal''', and '''relative'''.
All of these return new Path objects constructed by converting the path to a string, passing it through the likewise named method of the file system API, and converting it back to a Path.  Thus, all of these methods are chainable.  In addition, '''join''' and '''resolve''' are variadic, so additional paths can be passed as arguments in either String, Path, or Array form.

Every path object has the members '''listDirectoryTreePaths''', '''listPaths''', and '''listTreePaths'''.  All of these return objects that provide Path objects constructed by converting the path to a string, passing it through the likewise named method of the file system API, and converting it back to a Path.

Every path object has the members '''copy''', '''copy''', '''copyTree''', '''discardAttribute''', '''exists''', '''extension''', '''getAttribute''', '''getAttributes''', '''isDirectory''', '''isFile''', '''isLink''', '''isReadable''', '''isWritable''', '''iterate''', '''iterateDirectoryTree''', '''iterateTree''', '''lastModified''', '''link''', '''linkExists''', '''list''', '''listDirectoryTree''', '''listTree''', '''makeDirectory''', '''makeTree''', '''move''', '''open''', '''read''', '''remove''', '''removeAttribute''', '''removeDirectory''', '''removeTree''', '''removeTree''', '''rename''', '''setAttribute''', '''size''', '''split''', '''symbolicLink''', '''touch''', and '''write'''.  All of these functions convert themselves to strings and pass the results through the likewise named method of the file system API.

In addition, paths implement:

; toString()
: converts the path to its String representation

; to(target)
: returns the path from this path to the target.  Equivalent to &lt;code&gt;Path(relative(this, target))&lt;/code&gt;.

; from(source)
: returns the path from the source to this path.  Equivalent to &lt;code&gt;Path(relative(source, this))&lt;/code&gt;.

; glob(pattern)
: returns an Array of path Strings that match the given pattern at this path.

; globPaths(pattern)
: returns an Array of Path objects that match a given pattern at this path.


= Notes =

* Path separator constants are deliberately omitted from this specification to encourage the use of the provided cross-platform methods.
* Full Posix stat functionality, including stat, has been left for an exercise for a separate specification.

== For Future Versions ==

* locks
* comprehensive stat access and modification
* ACLs
* temporary files and directories
* more open options: permissions, owner, groupOwner
* copy with metadata
* other [[API/file/Names|proposed names]].

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/a1b175c20ad61ed7 writ or write?]
* [http://groups.google.com/group/commonjs/browse_thread/thread/5ed547baaba11f6c Filesystem API - Hobgoblin of little minds in little bike sheds with little bicycles]
* [http://groups.google.com/group/commonjs/browse_thread/thread/eb721e00452c4d02 Filesystem API: stat]
* [http://groups.google.com/group/commonjs/browse_thread/thread/abef650ba0c4f76d Filesystem API - Path(path, &lt;nowiki&gt;[fs]&lt;/nowiki&gt;)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f71e34667e1d5bde Filesystem API, Pure-JS glob implementation]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c4af0c8d278fd34b Return value of return? Partial writing?]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c35d10239fade9ab Simplifying core filesystem methods]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem/Hierarchy</title>
    <id>41</id>
    <revision>
      <id>915</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[Filesystem API/Hierarchy]] to [[Filesystem/Hierarchy]]</comment>
      <text xml:space="preserve">= Filesystem Class Hierarchy =

This proposal aims to create a set of classes (in an OOP sense) which would add some structuring (and taxonomy) to the Filesystem API. I believe that this can (and should) be done prior to standardizing every available method, including their names, arguments, return values and exceptions thrown.

== Basics ==

Top-level class is a '''Path'''. This object (&lt;tt&gt;var path = new Path(&quot;/etc&quot;)&lt;/tt&gt;) represents a generic path in a filesystem hierarchy. We are not aware of the underlying representation's properties, type (file/dir/link/pipe/socket/whatever), existence etc. Path acts as an ancestor, offering methods which are 
commot to all fielsystem objects. For instance, we might have &lt;tt&gt;path.exists(), path.isFile(), path.stat(), path.join(&quot;/passwd&quot;), path.delete()&lt;/tt&gt; and so on.

Then, we have a '''File'''. This class extends Path by adding methods which are specific to files; most notable methods for creation, reading and writing. Similarly, we have a '''Directory''' - File's sibling - which adds (to the Path parent) methods useful for Directory traversal and creation.

One can freely extend this, for instance by creating a Symlink class - its parent would be File. Symlink might offer additional funcionality - methods &lt;tt&gt;symlink.follow(), symlink.edit()&lt;/tt&gt; etc.

Note that neither of these objects guarantees the existence of its underlying filesystem representation.

== Examples ==

# var data = new File(&quot;/etc/passwd&quot;).open(&quot;r&quot;).read();
# var data = new Directory(&quot;/etc&quot;).listFiles();
# var path = new Path(&quot;/home&quot;).join(&quot;ondras&quot;); &lt;br/&gt; assert(path.exists());
# var path = new Path(&quot;/a/b/c&quot;); &lt;br/&gt; if (path.isDirectory()) { doSomething(); }

== Troubles ==

There are still several points in this proposal which make me uncomfortable. Perhaps a different point of view or a discussion can make things clear in this area.

* It is unclear how should one convert between various Filesystem-related classes. Two solutions come to my mind:
*# var dir = new Path(&quot;/etc&quot;).toDirectory();
*# var dir = new Directory(new Path(&quot;/etc/&quot;));

Both are problematic. The first one states that a Path should offer toXXX() methods, which is incorrect - as a top class, Path should not depend on existence of any of its descendants. The second way, on the other hand, is less readable.

* It is unclear how moving, copying and removing should be implemented. In my original proposal, these are methods of Path object. However, as the real file/directory manipulation might be (in some way) specific to the object in question, it seems logical to have these implemented in each movable/copyable/removable class.</text>
    </revision>
  </page>
  <page>
    <title>Filesystem/Join</title>
    <id>42</id>
    <revision>
      <id>1132</id>
      <timestamp>2009-09-10T20:31:41Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">== Definition ==

== Unit Tests ==

== Show of Hands ==

'''A''': implicitly uses &quot;normal&quot; to normalize the result, so all empty, &quot;.&quot;, and &quot;..&quot; path components are resolved if possible.  This is our &quot;normal&quot; definition, which is distinct from &quot;canonical&quot; and &quot;absolute&quot; in that it does not consult the underlying storage or the current working directory.

''for'': &lt;code&gt;join(&quot;foo&quot;, &quot;..&quot;, &quot;bar&quot;) == &quot;bar&quot;&lt;/code&gt; and &lt;code&gt;join(&quot;..&quot;, &quot;foo&quot;) == &quot;../foo&quot;&lt;/code&gt;
* Kris Kowal

''against'': &lt;code&gt;join(&quot;foo&quot;, &quot;..&quot;, &quot;bar&quot;) == &quot;foo/../bar&quot;&lt;/code&gt;
* Ash Berlin
* Daniel Friesen
* Mário Valente
* Wes Garland
* Zachary Carter

'''B''': recognizes and follows absolute paths.

''for'': &lt;code&gt;join(&quot;foo&quot;, &quot;/bar&quot;) == &quot;/bar&quot;&lt;/code&gt; (Unix) &lt;code&gt;join(&quot;Foo&quot;, &quot;c:\\Bar&quot;) == &quot;c:\\Bar&quot;&lt;/code&gt; (Microsoft)
* Kris Kowal
* Wes Garland

''against'': &lt;code&gt;join(&quot;foo&quot;, &quot;/bar&quot;) == &quot;foo/bar&quot;&lt;/code&gt;
* Mário Valente
* Zachary Carter
* ''Daniel Friesen (fuzzy)''

[[Category:Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem/Names</title>
    <id>43</id>
    <revision>
      <id>926</id>
      <timestamp>2009-09-10T03:01:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">= API and Proposed Names =

The following sections are organized with a bullet point per function.  Each point includes a specification for the behavior of a given method, intended to be suitable for documentation.  Under each definition is a list of potential names for that function, and in bullets beneath that, everyone is encouraged to write their name under their preference.  Please feel to leave comments as well.

In the next section, &quot;General Preferences&quot;, there are several broad sweeping points about whether to use certain conventions in a consistent fashion.  All of the name options are intended to conform to the prevalent opinion among those elections.  For example, &quot;make&quot; and &quot;create&quot; and &quot;dir&quot; and &quot;directory&quot; are both general preference elections, so if you would prefer &quot;makeDir&quot; over &quot;createDirectory&quot;, please vote independently for &quot;make&quot; and &quot;dir&quot; in the general preferences.


== File System Object ==

The &quot;file&quot; module would conform to the File System API, as well as objects returned by &quot;chroot&quot;.  There is no definitive implementation of a FileSystem class, so &quot;chroot&quot; is the only way to construct new objects that conform to the FileSystem API.  In permissive platforms, the &quot;file&quot; module may have direct access to ambient authority through a foreign function interface, or may itself be a dynamically loaded module.  In secured platform, the &quot;file&quot; module must copy the properties of &quot;system.fs&quot; onto its exports.

In a secure sandbox, the following statements would be equivalent.

 require('file').open(foo)
 system.fs.open(foo)

Since &quot;fs&quot; must be frozen to be secure, there is no need for the &quot;file&quot; module to assemble aparatus for late binding to &quot;fs&quot; methods.

* whether a file exists at a given path: receives a path and returns whether that path, joined on the current working directory, corresponds to a file that exists.  If the file is a broken symbolic link, returns false.
** exists(path):
*** Kris Kowal
*** Wes Garland
*** (Python: os.path.exists, Ruby: exist?, exists?, Java: exists, JSExt: access, Spidermonkey: Helma: v8cgi: JSExt: EJScript: Synchronet: exists, jslibs: exist, PHP: file_exists)

* whether a symbolic link or file exists at a given path: receives a path and returns whether that path, joined on the current working directory, corresponds to a file, albeit a broken symbolic link, that exists.
** exists(path, true):
*** Wes Garland
*** Mario Valente
** linkExists(path):
*** Kris Kowal
** exists(path, &quot;link&quot;):
*** Kris Kowal (as a compromise)
** (Python: os.path.lexists)

* moves a file from a source to a target path.  Both paths are joined on the current working directory.
** move(source, target):
** (Ruby: move, Python: shutil.move, Java: File.renameTo, PHP: rename)

* renames a file: receives two paths.  The first is a path, joined on the current working directory, that refers to the file to rename.  The second argument is a path relative to the former file's fully qualified path.
** rename(path, name):
** should not be included in the spec:
*** Kris Kowal
** (Ruby: rename)

* copies a file from a source to a target path.  Both paths are joined on the current working directory.
** copy(source, target):
** (Ruby: copy, systemCopy, Python:PHP: copy, Unix: cp)

* copies a file and its recursive contents to a target path.  Both paths are joined on the current working directory.  If &quot;synbolicLinks&quot; is truthy, symbolic links in the source tree are represented as symbolic links in the new tree; if falsy, the contents of the linked files are copied to the new tree.  If ignore is given, it must be a relation that will receive as its arguments the directory being visited by copytree(), and a list of its contents. Since this is called recursively (or walking an equivalent iteration), the ignore relation will be called once for each directory that is copied. The relation must return a sequence of directory and file names relative to the current directory (i.e. a subset of the items in its second argument); these names will then be ignored in the copy process.
** copyTree(source, target, symbolicLinks = false, ignore = undefined)
** copy(source, target, &quot;recursive&quot;)
** copy(source, target, true)
** (Python: copytree)

* makes a directory at a given path in the base directory implied by the given path.  Throws an exception if the base directory does not exist, or if the given path already exists.
** makeDirectory(path):
*** Kris Kowal
** createDirectory(path):
*** Mario Valente
** mkdir(path)
*** Kevin Dangoor
** (Unix:PHP: mkdir)

* creates recursive directories.  Makes all intermediate-level directories needed to contain the leaf directory. Throws an exception if the leaf directory already exists or cannot be created. The default mode is 0777 (octal). On some systems, mode is ignored. Where it is used, the current umask value is first masked out.
** makePath(path):
*** Kris Kowal
** makeDirectory(path, true):
*** Wes Garland
** makeDirectory(path, &quot;recursive&quot;):
** makeDirectory(path, &quot;path&quot;):
*** Kris Kowal (as a compromise)
** makeTree(path)
** (Unix: mkdir -p, Ruby: makedirs, mkpath, Python: os.makedirs) 
** mkdirs(path)
*** Kevin Dangoor
** (PHP: mkdir(path, mode, true))

* removes a file.
** remove(path):
*** Kris Kowal
*** Tom Robinson
*** Kevin Dangoor
*** Wes Garland (as a compromise)
** unlink(path):
*** Wes Garland
** (Ruby: unlink, delete, Python: unlink, remove, Java: delete, Posix:PHP: unlink, Unix: rm, Spidermonkey: Helma: EJScript: Synchronet: remove, jslibs: Delete)

* removes a file or directory and its recursive contents.
** remove(path):
** remove(path, true):
** remove(path, &quot;recursive&quot;)
** removeRecursive(path)
** removeTree(path, ignoreErrors = false, onError = undefined)
** (Unix: rm -r, Python: rmtree)

* creates a hard link of the source path as the target path.  Both paths are joined on the current working directory.
** link(source, target):
*** uncontested
** (Python:Ruby:PHP: link, Unix: ln)

* creates a symbolic link on a given &quot;target&quot; file name.  The source path becomes the text of the symbolic link, which the underlying system will join on the containing directory when it's followed, while the target path is joined on the current working directory.
** symbolicLink(source, target):
*** Kris Kowal
** link(source, target, true):
*** Wes Garland
** link(source, target, &quot;symbolic&quot;):
*** Kris Kowal (as a compromise)
** (Ruby:Python:PHP: symlink, Unix: ln -s)

* creates an empty file at a given path in its implied base directory.  The path is resolved relative to the current working directory.  Accepts an optional ``Permissions`` object (or a duck-type thereof, or the, typically octal, numeric representation of permissions in Unix) that notes which permissions the file will be created with, assuming that those permissions are in the &quot;umask&quot;.
** create(path, [permissions]):
*** Mario Valente
** unnecessary:
*** Kris Kowal,
*** Wes Garland
** (Java: createNewFile, Posix: creat, Unix:PHP: touch)

* truncates a the file at a given path.  Accepts an optional length that default to zero.  The path is resolved on the current working directory.
** truncate(path, [length = 0]):
** omit entirely:
*** Kris Kowal
** (Ruby: truncate, Python:PHP: ftruncate applies to open files only)

* updates the stat/metadata of the file at a given path.  Accepts a stat object.  Implicitly updates the time that the file's metadata/stat was updated to the current time, regardless of the metadata modification time provided by the stat object.
*** Wes Garland
** update(path, stat):
** chstat(path, stat):
** setStat(path, stat):
** restat(path, stat):
** (a low-level alternative to Python's copy2 and copyStat)

* updates the modification time of the file at a given path.  Accepts an alternate modification time to set the file.  Also implicitly updates the time that the file's metadata/stat object was updated to the current time, regardless of the chosen modification time.
** touch(path, [date]):
*** Kris Kowal
** (Unix:PHP: touch)

* locks the file at a given path with either an exclusive or shared advisory lock.  The path is resolved on the current working directory.  Blocks until the lock is acquired, or if a timeout is defined, when that timeout occurs.
** lock(path, &quot;shared|exclusive&quot;, [timeout=undefined]):
*** Wes Garland
*** Kris Kowal
** lock(path, &quot;rw|&quot;)
** (Posix:Python: lock)

* attempts to acquire an advisory lock a file at a given path but does not block.  The path is resolved relative to the current working directory.  Does not block if the file is not lockable.  Returns whether the lock was obtained.
*** Wes Garland
** tryLock(path, &quot;shared|exclusive&quot;):
** lock(path, &quot;rw&quot;)
** (Python: lock, PHP: flock($handle))

* releases a lock for a given path.
** unlock(path):
*** Kris Kowal
** lock(path, &quot;unlock&quot;)
** lock(path, &quot;u&quot;)
** (Python: lock, PHP: flock($handle, LOCK_UN))

* retrieves an object that represents the metadata of a distinct file, for a given path.  The path is resolved relative to the current working directory.  The returned object has the properties described in the Stat API.
** stat(path):
*** Mario Valente
** (Python: os.stat, Ruby: File.stat, Posix:PHP: stat)

* retrieves an object that represents the metadata of a distinct file or symbolic link to a file at a given path.  The path is resolved relative to the current working directory.  The returned object has the properties described in the Stat API.
** stat(path, true):
*** Wes Garland
** linkStat(path):
*** Kris Kowal
** stat(path, &quot;link&quot;):
*** Kris Kowal (as a compromise)
** (Python: os.lstat, Ruby: File.lstat, PHP: lstat)

* returns the size of the corresponding file.
** size(path)
** (Python: size, Ruby: size?: Java: length, Posix: st_size, PHP: filesize)

* returns the total size of a tree of files.
** size(path) // as a special case for a directory
** size(path, &quot;recursive&quot;)
** recursiveSize(path)

* returns an IO object for accessing or manipulating the data in a file at a given path.  The path is resolved relative to the current working directory.  The given permissions object may be a Unix numeric representation of permissions, a Stat object, or any object that provides the members of Stat regarding permissions.
** open(path, &quot;+arwxc&quot;, permissions, encoding):
*** Mario Valente
*** Kris Kowal
** Mode:
*** +, update
*** a, append
*** r, read
*** w, write
*** x, exclusive (lock)
*** c, canon (nonblocking)
** (Java: FileStream classes, Python: open, file, Ruby: File.new, universal precedent among SSJS frameworks)
** open([path,] [mode,] {[path: path,] mode: &quot;+arxwc&quot;, permissions: permissions, encoding: encoding})&lt;br&gt;(keyword-style parameters, first parameter is path or keyword object containing path)
*** Aristid Breitkreuz
*** Kris Kowal

* return a Dir object for a given directory path.  The path is resolved relative to the current working directory.  The Dir object is an bidirectional iterator of a snapshot of the contents of the directory, and may be either a lazy Array or genuine array, depending on whether the underlying implementation can retrieve indicies on demand.
** list(path)
** (Python: os.listdir, Ruby: Dir, PHP: dir)

* returns an object that, like a Dir, supports the iterator protocol (next, prev) and the Array protocol (length, [index]) for all files that match a given glob pattern.
** The glob pattern may include any of the following productions:
*** ? - exactly one character in a path component
*** * - any number of characters in a path component
*** ** - any number of characters in a path
*** {a,b,c} - the letters a, b, or c, or any other union of paths.
** glob(pattern)
** (Ruby: Dir[])

* returns whether a given path matches a glob pattern.
** match(pattern, path)
** (Ruby: fnmatch)

* returns a new object that implements the file system API that uses the directory at the given path as its root.  Resolves the path relative to the current working directory.
** chroot(path)

== Paths ==

More properites of a FileSystem object.

* a string directing a path up to the parent of the current directory, usually '..'.
** PARENT
** (a function that gets an opaque reference to the actual parent node on the file system, as referenced by the directory's parent hard link, has been deliberately omitted to avoid leaking the capability to access that object from within a chroot file system)
** (Python: pardir)

* a string directing a path back to itself, usually '.'.
** SELF
** (Python: curdir)

* a string that contains the path separator, usually '/', '\', or ':'.
** SEPARATOR
** (Python: sep, Spidermonkey: separator, Ruby: SEPARATOR, Separator)

* a string that contains the alternate path separator, if it exists.  Otherwise, undefined.
** ALTERNATE_SEPARATOR
** (Python: altsep, Ruby: ALT_SEPARATOR)

* a string that contains the extension separator, usually '.'.
** EXTENSION_SEPRATOR
** (Python: extsep)

* whether the file system supports unicode file names
** SUPPORTS_UNICODE_FILE_NAMES

* accepts a variadic list of paths as arguments and follows each successive path from the current working directory, left to right, and returns the normalized path of the ultimate file or directory.  Paths that end with a directory separator refer to the contents of a directory as a place to continue resolving, whereas paths that do not end with a directory separator indicate that the next path should be followed from the directory containing that file.
** join([path, [path, [path, [...]]]])

* returns the path components for a given path
** split(path)

* takes a string and returns an escaped path component of that string, such that directory separators and other special characters do not partition it into multiple path components
** escape(string)
** (not precedented)

* returns the path of the directory containing a given path.
** dirName(path):
*** Kris Kowal
** dirname(path)
*** Wes Garland
** (Python: Unix: dirname)

* returns the last path component without its extension.  The extension begins after the first extension separator.
** baseName(path):
*** Kris Kowal
** basename(path):
*** Wes Garland
** (Python: Unix: basename)

* returns the extension of the given path.  The extension begins after the first extension separator.
** extension(path):
*** George Mosochovitis
*** Kris Kowal
*** Wes Garland
** (Ruby: extname)

* removes '.' path components and simplifies '..' paths, if possible for a given path.  If the file system is case sensitive, transforms all letters to lower-case to make them unambiguous.
** normal(path)
** (Python: normpath)

* returns the absolute path, starting with the root of this file system object, for the given path, resolved relative to the current working directory.  If the file system supports home directory aliases, absolute resolves those from the root of the file system.  The resulting path is in normal form.  On most systems, this is equivalent to epxanding any user directory alias, joining the path to the current working directory, and normalizing the result.
** absolute(path)
** (Python: abspath)

* returns the canonical path to a given abstract path.  Canonical paths are both absolute and intrinsic, such that all paths that refer to a given file (whether it exists or not) have the same corresponding canonical path.  This function may not communicate information about the true parent directories of files in chroot environments.  This function is equivalent to expanding an user directory alias, joining the given path to the current working directory, joining all symbolic links along the path, and normalizing the result.
** canonical(path)
** (Python: realpath)

* returns whether a given path has no self and parent path components.
** isNormal(path)

* returns whether the given path is normal and starts with the root of the file system.
** isAbsolute(path)
** (Python: isabs)

* returns whether the given path is the same as the corresponding cannonical path.
** isCanonical(path)

* returns whether the given paths both refer to the same intrinsic file.  Both paths are resolved relative to the working directory.
** same(path, path)


== Stat Object ==

* the Date that the file was last accessed.
** atime:
*** Tom Robinson
*** Kevin Dangoor
*** Ondrej Zara
** lastAccessed:
*** Kris Kowal
** (Python: getatime, Ruby: atime)

* the Date that the file was last modified.
** mtime:
*** Tom Robinson
*** Kevin Dangoor
*** Ondrej Zara
** lastModified:
*** Kris Kowal
*** Mario Valente
*** Daniel Friessen
** (Python: getmtime, Ruby: mtime, Java: Spidermonkey: Helma: lastModified, jslibs: modifyTime, EJScript: modified, Synchronet: date)

* the Date that the file's stat/metadata was last modified.
** ctime:
*** Tom Robinson
*** Kevin Dangoor
*** Ondrej Zara
** lastChanged:
*** Wes Garland
*** Kris Kowal
** (Ruby: ctime, Python: getctime)

* the Date that the file was created, if the underlying file system makes that datum available (most Unix systems do not store creation time, but Windows and some Unix varieties do).  Returns undefined if the underlying file system does not provide a time.
** created:
** creationTime:
** firstModified:
** omit entirely:
*** Kris Kowal
** (Spidermonkey: jslibs: creationTime, EJScript: create)

* a String name for the type of the file.  One of: &quot;file&quot;, &quot;directory&quot;, &quot;characterSpecial&quot;, &quot;blockSpecial&quot;, &quot;fifo&quot;, &quot;link&quot;, &quot;socket&quot;, or &quot;unknown&quot;
** type:
** kind:
** omit entirely:
*** Kris Kowal

* whether the corresponding object is a file (not a directory).
** isFile:
*** Kris Kowal

* whether the corresponding object is a directory
** isDirectory
** (Spidermonkey: isDir, Helma: isDir, JSExt: isdir)

* whether the corresponding object is a symbolic link
** isLink

* whether the corresponding object is a mount point
** isMountPoint:
** omit entirely:
*** Wes Garland
*** Ondrej Zara

* whether the corresponding object is a socket
** isSocket

* whether the corresponding object is a pipe
** isPipe
** isFifo

* whether the correpsonding object is a block device
** isBlockDevice

* the size of the corresponding object in bytes
** size
*** Ondrej Zara
** (jslibs: size, Helma: getLength, Spidermonkey: wxJS: EJScript: Synchronet: length)

* the name or id of the owner of the file (following symlinks)
** owner

* the name or id of the group owner of the file (following symlinks)
** groupOwner

* the name or id of the owner of the file or symbolic link
** linkOwner

* the name or id of the group owner of the file or symbolic link
** linkGroupOwner

* whether the owner of the process at the time of this stat object's construction is the same as the owner of this file.
** owned

* whether the corresponding object can be opened for reading by the current process owner
** isReadable

* whether the corresponding object can be opened for writing by the current process owner
** isWritable

* whether the corresponding object is an executable for the current process owner
** isExecutable

* whether the corresponding executable file will be forced to run as the owner of the file if any user executes it.
** executesAsOwner
** setuid

* whether the corresponding executable file wil be forced to run with its group owner if any user executes it.
** executesAsGroupOwner
** setgid

* whether the corresponding directory will permit anyone to create files in it, but only let the owner of a file delete it.
** sticky

* an object that represents the permissions granted to the owner of the file.
** This object would contain:
*** isReadable
*** isWritable
*** isExecutable
** ownerPermissions

* an object that represents the permissions granted to the group that owns the file.
** The object would contain:
*** isReadable
*** isWritable
*** isExecutable
** groupPermissions

* an object that represents the permissions granted to anyone who has no claim to the file.
** The object would contain:
*** isReadable
*** isWritable
*** isExecutable
** worldPermissions

* returns an object that represents the permissions granted to the user corresponding to a particular name or identifier.
** The returned object would contain:
*** isReadable
*** isWritable
*** isExecutable
** getPermissions(user)

* the inode/vnode number of the underlying object (optional)
** inode

* the device number of the underlying object (optional)
** device


== File Object ==

File objects can only be constructed by methods of FileSystem objects.  Different IO types might be returned for calls to open with different modes, generally following the protocol outlined in Python's PEP 3116.  


== IO Objects ==

* reads as many bytes as are available from an IO stream and returns the number of actually read bytes.
** read()

* reads as many bytes as are available but less than a given number from an IO stream and returns the number of actually read bytes.
** read(n)

* reads a line of characters from a line buffered IO object.  Returns a blank line on EOF.
** readLine()
** (Python: JSExt: readline, Spidermonkey: Helma: Synchronet: readln)

* returns an Array-like view of the lines in an IO stream, or simply an Array of Strings.
** readLines()
** (Python: readlines, JSExt: readlines, EJScript: getLines)

* returns the next line in the stream.  Throws a StopIteration exception on EOF.
** next()

* returns an iteration on the lines of the IO stream, which is simply itself since it implements &quot;next&quot;.
** iter()

* calls a relation with each line of input from the IO stream.
** forEach(relation)

* reads bytes into a buffer, up to as many as the length of the buffer, pending availablility.  Returns the number of bytes actually read.
** readInto(buffer)

* writes bytes to a stream.  Returns the number of bytes that were actually written.
** write(buffer)

* moves the position of the cursor in a random access IO stream.
** Accepts a code that determines whether to move the position relative to the beginning, end, or current position:
*** 0 or &quot;begin&quot;: beginning of file (default)
*** 1 or &quot;relative&quot;: current position
*** 2 or &quot;end&quot;: end of file
** seek(pos, whence)
** (universal precedent)

* returns the current position of the random access cursor for an IO stream.  The position may be a &quot;cookie&quot; object or a Number, depending on the IO type.
** tell()
** (wxJS: JSExt: Python: Ruby: tell)

* truncates the size of a file to the current cursor position or a given position, which must be either a &quot;cookie&quot; object or a Number, depending on the IO type.
** truncate(pos)
** (Ruby: truncate, Python: ftruncate)

* returns whether the cursor is at the end of the IO stream.
** eof()
*** Kris Kowal
** atEOF():
*** Wes Garland (non-commital)
** (Helma: wxJS: JSExt: Synchronet: eof)

* flushes buffers for an IO stream
** flush()
** (universal precedent)

* blocks until an advisory lock is acquired.  Throws an error if a lock cannot be acquired on the system.
** lock(&quot;exclusive|shared&quot;)

* tries to grab an advisory lock without blocking, and returns whether it succeeded.
** tryLock(&quot;exclusive|shared&quot;)
** (related to isOpen in many existing SSJS frameworks, but without a race condition hazard)

* releases an advisory lock.
** unlock()

* closes a stream
** close()

* whether the IO stream is readable
** isReadable

* whether the IO stream is writable
** isWritable

* whether the IO stream supports random access
** isSeekable

* whether the IO stream is attached to a virtual or real teletype.
** isTTY:
*** Wes Garland
** isTty:
*** Kris Kowal 

* the descriptor of the underlying file, an opaque reference to the file descriptor, or undefined if file descriptors are not supported.
** fileNo

* the underlying unbuffered IO stream, if it exists.  Otherwise undefined.
** raw

* creates a duplicate of the IO stream, with its own buffereing and cursor.
** copy()
*** Kris Kowal
** dup()


= Notes for Further Discussion =

* input, output, stdin, stdout, STDIN, STDOUT
* ...placed on environment or in a module?
* separation of knowledge of paths between file system and files
* currentDirectory, getCurrentDirectory
* temporary files and directories
* opening a temp file with an implied immediate exclusive lock
* dup and dup2 and other file-descriptor specific constructs for permissive environments.
* canRead, canWrite, poll, select
* taxonomy of IO classes
* default encoding for String, line-buffered IO


= General Preferences =

# make vs. create
#* make:
#** Mario Valente,
#** Wes Garland (but only for directories)
#** Kris Kowal (but only for directories)
#* create:
#** George Moschovitis,
#** Wes Garland (but only for files)
#** Kris Kowal (but only for files)
#** Ondrej Zara
# dir vs. directory
#* directory:
#** Tom Robinson,
#** Kevin Dangoor,
#** George Mosochovitis,
#** Wes Garland
#** Ondrej Zara
#* dir:
#** Mario Valente
# cur vs. current
#* current:
#** Tom Robinson,
#** Kevin Dangoor,
#** Wes Garland,
#** Kris Kowal,
#** Mario Valente
#** Ondrej Zara
#** George Moschovitis
#* cur:
# canonize, realize, normalize, qualify, cannon, real, normal, qualified, absolute, cannonicalize
#* remove . and ..:
#** normalize:
#*** Tom Robinson,
#*** Kevin Dangoor,
#*** Kris Kowal,
#*** George Mosochovitis
#** qualify:
#*** Wes Garland
#** expand:
#*** Ondrej Zara
#* remove . and .., start at /:
#** absolute:
#*** Tom Robinson,
#*** Kevin Dangoor,
#*** Kris Kowal,
#*** George Mosochovitis,
#*** Wes Garland,
#*** Mario Valente
#** qualified:
#*** Wes Garland
#** normalize:
#*** Ondrej Zara
#* remove . and .., start at /, follow symlinks:
#** canonical:
#*** Tom Robinson,
#*** Kevin Dangoor,
#*** Kris Kowal
#** absolute:
#*** George Mosochovitis,
#*** Wes Garland,
#*** Mario Valente,
#** real:
#*** Tom Robinson,
#*** Kevin Dangoor
#** qualified:
#*** Wes Garland
# constantCase, CONSTANT_CASE, kConstantCase
#* CONSTANT_CASE:
#** Tom Robinson,
#** Kevin Dangoor
#** Ondrej Zara
#** George Moschovitis
#* constantCase:
#** Kris Kowal,
#** Wes Garland,
#** Mario Valente,
# &quot;static&quot; methods
#* require(module).staticMethod:
#** Kris Kowal
#** Wes Garland
#** Mario Valente
#** Ondrej Zara
#* require(module).Klass.staticMethod:
#** Tom Robinson
#** George Mosochovitis
# properties, accessors, mutators
#* foo.setX(x); foo.getX()
#** For:
#** Against:
#* foo.setX(x); foo.X()
#** For:
#** Against:
#* no convention
#** For:
#** Against:
#* foo.x = x; foo.x
#** For:
#*** Davey Waterson
#*** Wes Garland
#*** Daniel Friesen
#*** Sam Phillips
#** Against:
#*** Tom Robinson
#*** Kris Kowal

= References =

; http://www.python.org/dev/peps/pep-3116/: PEP on new File IO
; http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html: Java File API
; http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileOutputStream.html: Java Output API
; http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileInputStream.html: Java Input API
; http://www.erights.org/javadoc/java/io/File.html: E Secure File API
; http://www.cs.berkeley.edu/~daw/joe-e/api/org/joe_e/file/Filesystem.html: Joe-E Secure File System API
; http://docs.python.org/library/os.path.html: Python Path API
; http://www.ruby-doc.org/core/classes/File.html: Ruby File API
; http://www.ruby-doc.org/core/classes/IO.html: Ruby IO API
; http://spreadsheets.google.com/pub?key=p9uiX8MUHeTiP0kPT591RUw: A matrix of existing CommonJS File API nomenclature and support

[[Category:Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem/Show of hands</title>
    <id>44</id>
    <revision>
      <id>2343</id>
      <timestamp>2010-03-13T21:48:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Reverted edits by [[Special:Contributions/Rezelyn|Rezelyn]] ([[User talk:Rezelyn|Talk]]) to last revision by [[User:Dantman|Dantman]]</comment>
      <text xml:space="preserve">;.write operations on a stream:
:A.1) May do partial writes and return the data that has not yet been read.
:A.2) May do partial writes and return the length of data that has been written.
:* Wes Garland
:B) Block until all the data has been written to the underlying layer (partial writes may be handled with a different method or options; unspecified atm).
:* Daniel Friesen
:* Kris Kowal
:* Tom Robinson
:* Kevin Dangoor
:* Joshaven Potter

=== Notes ===
* Kris Kowal thinks that B).write should return `this` to allow chaining.

[[Category:Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Future Efforts</title>
    <id>45</id>
    <revision>
      <id>1089</id>
      <timestamp>2009-09-10T20:14:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Future Efforts]] to [[Future Efforts]]</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>HTTP Client</title>
    <id>46</id>
    <revision>
      <id>2566</id>
      <timestamp>2010-04-06T19:36:24Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <comment>/* Requirements/Proposals */</comment>
      <text xml:space="preserve">= HTTP Client API =

Server side programs often need to grab information via HTTP. There should be an API that makes this as easy as possible.

There are certainly other protocols that deserve support, but each protocol has its own purpose and interface and will be documented separately if it will become part of the stdlib.

==  Requirements/Proposals ==

* [[HTTP Client/A|HTTPClient Proposal A]]
* [[HTTP Client/B|HTTPClient Proposal B]] based on XMLHttpRequest

== Prior Art ==

* [http://www.w3.org/TR/XMLHttpRequest/ XMLHttpRequest] is already the standard JS API for HTTP.
* [http://www.w3.org/TR/XMLHttpRequest2/ XMLHttpRequest level 2] is the Draft for the next version of this standard JS API.
* [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/ejs.io-Http.html Here] is an extended HTTP API from Ejscript.
* v8cgi has a [http://code.google.com/p/v8cgi/wiki/API_HTTP HTTP] class
* Helma has a ([http://helma.zumbrunn.com/reference/helma.Http.html HttpClient])
* Wakanda has [http://www.w3.org/TR/XMLHttpRequest/ XMLHttpRequest] with parts of  [http://www.w3.org/TR/XMLHttpRequest2/ XMLHttpRequest Level 2]
* Ajax.org O3 SSJS API has XMLHttpRequest
* XMLHttpRequest is being implemented for gpsee and flusspferd</text>
    </revision>
  </page>
  <page>
    <title>HTTP Client/A</title>
    <id>47</id>
    <revision>
      <id>1065</id>
      <timestamp>2009-09-10T19:59:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/HTTP Client/A]] to [[HTTP Client/A]]</comment>
      <text xml:space="preserve">Proposal A, Draft 1

'''Status: Proposal'''

The &quot;http-client&quot; module exposes an HTTPClient constructor that creates an HTTP Client object.

== Constructor: HTTPClient(settings) ==

If called as a simple function, then return a new HTTPClient(settings).

Set all protected members to the default values.

If a settings object is included, call this.set(settings).

== Object Methods ==

All methods return &quot;this&quot; except where otherwise specified.

=== set([settings object | key, value]) ===

Set the body, headers, method, or url, or any combination thereof in the settings object.  Attribute validity is enforced (see valid settings on members, below.)

=== setHeader(key, val) ===

Set a header on the header object in a case-insensitive manner.  That is, if the user sets &quot;content-type&quot;, and then later sets &quot;Content-Type&quot;, then the first setting is lost.

=== setHeaders(headers:Object) ===

Set a bunch of headers expressed as name-value pairs.

=== write(data:toByteString-able) ===

Append data to the outgoing request.  (That is, to the iterable body object.)

Implementers MAY require the body object to expose a push() method, and call this push() method to append data to the request.

=== connect() ===

Open the connection to the URL using the method supplied.  If the method or url is missing, throw an error.

After connecting, write() will have no effect.

Calling connect() SHOULD NOT block the application, but MUST initiate the HTTP request.

=== read() ===

Read the request and return a JSGI-style object consisting of &lt;code&gt;{status:Integer, headers:Objecct, body:Iterable&lt;ByteString&gt;}&lt;/code&gt;.

Calling read() SHOULD NOT block the application until the request is completed, but it MUST open the input stream such that the data can be read.

=== finish() ===

Alias for .connect().read()

== Static Methods ==

=== decode(response[, encoding]) ===

Return a response object where the body has been wrapped in a decoder middleware.

For example:

&lt;pre&gt;resp.body = {forEach : function (block) {
    raw.forEach(function (i) {
        block(i.decodeToString(encoding));
    });
}};&lt;/pre&gt;

Make a best-guess attempt to determine the appropriate encoding based on the response headers if no encoding is specified.  The ultimate fallback encoding SHOULD be UTF-8.  

=== unDecode(response) ===

Replace the decoded body with the original body.  This is useful when the decoded content is clearly invalid and the consumer wants to backtrack.

== Members ==

All members below are required and SHOULD be protected.

=== body ===

An iterable (that is &lt;code&gt;forEach&lt;/code&gt;-able) object where forEach iterates over items with a &lt;code&gt;toByteString&lt;/code&gt; method.

Implementers MAY require that the body member expose a &lt;code&gt;push&lt;/code&gt; method in order for the write function to operate properly.

Default value: []

=== headers ===

A hash of request headers.  Care SHOULD be taken to ensure that keys are added in a case-insensitive manner.

Default value: {&quot;X-Requested-With&quot; : &quot;CommonJS HTTP Client&quot;}

=== method ===

The request method as a string.

Default value: &quot;GET&quot;

=== url ===

URL as a string

Default value: none

== Example Implementation ==

* Isaac's Narwhal fork: [http://github.com/isaacs/narwhal/blob/master/lib/http-client.js code], [http://github.com/isaacs/narwhal-playground/blob/master/http-client.js usage], [http://github.com/isaacs/narwhal-playground/blob/master/http-client-blocking-test.js concurrent demonstration]</text>
    </revision>
  </page>
  <page>
    <title>High Level Tools</title>
    <id>48</id>
    <revision>
      <id>1077</id>
      <timestamp>2009-09-10T20:00:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/High Level Tools]] to [[High Level Tools]]</comment>
      <text xml:space="preserve">The point of everything above is to make it easier for higher level tools to be reliably built out of more reusable parts and for the higher level tools to work on more platforms with less redundant work.

(This is a fine place to link up higher level web application frameworks).</text>
    </revision>
  </page>
  <page>
    <title>IO</title>
    <id>49</id>
    <revision>
      <id>2543</id>
      <timestamp>2010-03-31T10:07:10Z</timestamp>
      <contributor>
        <username>Hannesw</username>
        <id>10</id>
      </contributor>
      <minor/>
      <text xml:space="preserve">'''STATUS: PROPOSALS, DISCUSSION'''

The purpose of this proposal is to create a unified interface for stream-like objects in JavaScript. This specification was originally part of the [[Filesystem|FileSystem API]] and has been extracted to provide a common API for other I/O related modules. 

== Proposals ==

* [[IO/A|I/O Proposal A]] - [[User:Hannesw|Hannes Wallnöfer]]
* [[IO/B|I/O Proposal B]] - [[User:Dantman|Daniel Friesen]]
* [[IO/C/Stream|IO Stream Proposal C]] - Michael O'Brien

== Inspirations and Prior Art == 

The [[Filesystem|FileSystem API]] page contains an extensive list of existing I/O related APIs.

== Discussion ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/d7661cde0b631bf I/O proposal first draft Options]
* [http://groups.google.com/group/commonjs/browse_thread/thread/6cce4e4730c35651 The case for a dedicated I/O spec]</text>
    </revision>
  </page>
  <page>
    <title>IO/A</title>
    <id>50</id>
    <revision>
      <id>1573</id>
      <timestamp>2009-10-04T12:08:06Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Notes */</comment>
      <text xml:space="preserve">''Second draft. See [[IO/A#Notes|Update Notes]] below for changes from first draft''

This document describes an interface for reading and writing stream of raw bytes, and classes built on top of it to provide string based reading and writing. 

This specification refers to the ByteString and ByteArray classes defined in the [[Binary/B]] proposal, but it should be easy to adapt it to any definition of binary buffers or arrays.

= Specification =

Platforms implementing this specification must provide a top level '''io''' module. The io module must export the classes and interfaces described below.

== Raw I/O ==

=== Stream ===

The Stream class implements a I/O stream for reading and writing raw bytes.

===== Constructor =====

Whether the Stream class provides a public constructor, and what the arguments of the constructor are, is not part of this specification. The process of creating actual Stream objects is implementation specific. 

Various built-in modules such as the [[Filesystem|file module]] will know how to build native Stream objects in a platform specific way. Application classes should be able to extend the Stream class through JavaScript prototype chaining. However, duck typing should also work for Stream objects, meaning that any object implementing the Stream interface ''should'' work for code expecting an io.Stream object.

===== Instance Properties =====

'''''Note''': the length and position properties are used to implement random access streams traditionally implemented using the tell()/seek()/truncate() protocol. The rationale for departing from that nomenclature is that this puts stream more in line with other core objects such as String and Array. Also, random access streams are not often used in day-to-day programming, so these properties may most commonly be used for in-memory stream implementations, where they should fit in nicely.''

;length Number
:The length of the stream, in bytes. This property is only defined for seekable streams, and is only writable for streams that are both seekable and writable. Decreasing the length property of a stream causes the stream to be truncated. Increasing the length of a stream causes the stream to be extended. The content of the extended section of the stream are not defined. Accessing this property may throw an error if the underlying operation did not succeed.

;position Number
:The position within the stream at which the next read or write operation occurs, in bytes. This property is only defined for seekable streams. Setting it to a new value moves the stream's positon to the given byte offset. Accessing this property may throw an error if the underlying operation did not succeed.

===== Instance Methods =====

;read([n Number]) ByteString
:Read up to n bytes from the stream, or until the end of the stream has been reached. In n is null, reads up to the block size of the underlying device, or up to 1024 bytes if the block size is not discernible.  If n is not specified, this method always reads the full stream until its end is reached. An empty ByteString is returned when the end of the stream has been reached. Throws an error if the operation could not be completed.

;readInto(buffer ByteArray, [begin Number], [end Number]) Number 
:Read bytes from the stream into the ByteArray buffer. This method does not increase the length of the ByteArray buffer. Returns the number of bytes read, or -1 if the end of the stream has been reached. '''''Note''': Could we safely return 0 on EOF?''

;skip(n Number) Number
:Try to skip over n bytes in the stream. Throws an error if the operation could not be completed.

;write(b Binary, [begin Number], [end Number])
:Write bytes from b to the stream. If begin and end are specified, only the range starting at begin and ending before end are written. Throws an error if the contents of b couldn't be written to the stream.

;copy(target Stream)
:reads from this stream with &lt;code&gt;read(null)&lt;/code&gt;, writing the results to the target stream and flushing, until the source has been exhausted.  Throws a '''TODO''' error if the target closes before the source has been exhausted.

;readable() Boolean
:Returns true if the stream supports reading, false otherwise.

;writable() Boolean
:Returns true if the stream supports writing, false otherwise.

;seekable() Boolean
:Returns true if the stream supports the length and position properties, false otherwise. '''''Note''': we're not impelementing seek(), so should we find another term for this, too? 'positionable' comes to mind, but feels slightly awkward.''

;closed() Boolean
:Returns true if the stream is closed, false otherwise.

;flush()
:Flushes the bytes written to the stream to the underlying medium. Throws an error if the operation did not succeed.

;close()
:Closes the stream, freeing the resources it is holding. Throws an error if the operation did not succeed.

== Text I/O ==

=== TextStream ===

The TextStream class wraps a raw stream and exposes a similar interface as the Stream class, but its write() method takes a string as first arguments and its read() method returns a string. Additionally, it defines the properties and methods listed below.

===== Constructor =====

;[new] TextStream(raw Stream, [options Object]) TextStream
:Build a TextStream around a raw byte stream. The options argument may contain the following properties:
* charset: a string containing the name of the encoding to use
* newline: a string containing the newline character sequence to use
* delimiter: a string containing the delimiter to use in print()

===== Instance Properties =====

;raw
:A readonly property containing the raw byte stream wrapped by this text stream.
;buffer
:A readonly property containing the buffer used internally by this text stream, if it is buffered.  This property may be undefined.

===== Instance Methods =====

; readLine() String
: Reads a line from the reader. If the end of the stream is reached before any data is gathered, returns an empty string. Otherwise, returns the line including the newline. Throws an error if the operation did not succeed.

; readLines() Array*String
: Returns an Array of Strings accumulated by calling readLine until an empty string turns up. Does not include the final empty string, and does include newline at the end of every line. Throws an error if the operation did not succeed.

; next() String throws StopIteration
: Returns the next line of input without the newline. Throws StopIteration if the end of stream is reached. Throws an error if the operation did not succeed.

; iterator() Iterator
: Returns the reader itself.

; writeLine(line String)
: Writes line followed by a newline. Throws an error if the operation did not succeed.

; print(...)
: writes a delimiter delimited array of values as Strings terminated with a newline, then flushes. Throws an error if the operation did not succeed.

;copy(target Stream)
:reads from this stream with &lt;code&gt;readLine()&lt;/code&gt;, writing the results to the target stream and flushing, until the source has been exhausted.  Throws a '''TODO''' error if the target closes before the source has been exhausted.

= Notes =

* This proposal does not describe non-blocking I/O, nor does it describe buffered I/O. These may be introduced in a later revision of the spec, possibly in conjunction with a Socket API. Platforms are free to implement non-blocking and buffered I/O in their own specific way.
* Text streams need read() for read-all ~KrisKowal
* Daniel Friesen recommended read(Infinity) instead of read(null), sounds good to me. ~KrisKowal

== Changes from First Draft ==

; Removed Memory based I/O section. 
: I realized how easy it is to build a stream interface to the existing binary specification, so in the interest of a simple spec I think it's best to leave that part to implementors for now.

; Removed IOError section but added notes about which methods can throw errors.
: Introducing a new error class in a module may be tricky as error classes should be global and immutable to allow instanceof checks. Instead, defining what methods can throw errors under what circumstances seems more important at this stage.

; Removed readAll() method
: Folded the functionality into read() being called without argument.

; write() no longer returns the number of bytes written
: If the method terminates without throwing an exception it means that all bytes passed to it were written to the stream.</text>
    </revision>
  </page>
  <page>
    <title>Infrastructure</title>
    <id>52</id>
    <revision>
      <id>1208</id>
      <timestamp>2009-09-12T02:30:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-CommonJS/ +)</comment>
      <text xml:space="preserve">* [[Packaging|Code packaging, installation and deployment]]
* [[Doctools|Documentation tools]]</text>
    </revision>
  </page>
  <page>
    <title>Introduction</title>
    <id>53</id>
    <revision>
      <id>839</id>
      <timestamp>2009-09-10T02:14:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Introduction]] to [[Introduction]]</comment>
      <text xml:space="preserve">Server side JavaScript has been around for a long time, and potentially offers some unique and interesting advantages over other languages because the same language is spoken by both client and server.

http://philip.greenspun.com/wtr/livewire.html

http://docs.sun.com/source/816-6411-10/contents.htm

Unfortunately, though, server side JavaScript is very fragmented. A script that accesses files can't be used without modification on both rhino and v8. Spidermonkey and JavaScriptCore can't both load in additional modules in the same way. A JavaScript web framework is very much tied to its interpreter and is often forced to create a bunch of APIs that Python, Ruby and Java programmers take for granted.

The goal for this project is to create a standard library that will ultimately allow web developers to choose among any number of web frameworks and tools and run that code on the platform that makes the most sense for their application.

This group/project was initially introduced in a blog posting: [http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/ &quot;What Server Side JavaScript Needs&quot;]

* [http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html#JavaScript Javascript @ &quot;The Universal Design Pattern&quot;]
* [http://developer.mozilla.org/En/Server-Side_JavaScript/Walkthrough Back to the Server: Server-Side JavaScript On The Rise]
* [http://steve-yegge.blogspot.com/2007/02/next-big-language.html The Next Big Language]
* [http://bannister.us/weblog/2006/12/19/revisiting-server-side-javascript/ Revisiting serverside Javascript]
* [http://softwareas.com/server-side-javascript-hope-and-opportunity Server-side Javascript: Hope and opportunity]
* [http://mv.asterisco.pt/cat.cgi?A%20Future%20Web%20Development%20Framework%20-%20Application%20Logic A Future Web Development Framework App Logic]</text>
    </revision>
  </page>
  <page>
    <title>Logging</title>
    <id>54</id>
    <revision>
      <id>1993</id>
      <timestamp>2010-01-15T11:00:01Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <comment>Wakanda use console.log</comment>
      <text xml:space="preserve">A standard logging API has proven to be useful in many languages. This is especially true for server side environments where things are often running unattended (unlike client side work, where you are personally actively using the code that is doing the logging).

== Prior Art ==

The standard logging API in the browser is one option:

  console.log(...);
  console.debug(...);
  ...

Current server-side APIs:

* [http://docs.persvr.org/documentation/server-side-js Persevere also uses this standard console API] for JavaScript logging.
I believe Jaxer may provide this API as well.
* [http://www.wakandasoftware.com Wakanda] use this standard console API
* Synchronet has a global log() method which allows logging of messages to consoles, files, etc. using the 8 standard Unix syslog severity levels: http://synchro.net/docs/jsobjs.html#global
* Blackbird offers a dead-simple way to log messages in JavaScript http://www.gscottolson.com/blackbirdjs/
* XBug the Javascript debugger http://www.xbug.co.uk/
* NitobiBug a browser-based JavaScript object logger and inspection tool http://www.nitobibug.com/
* [http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html Java Logging] is based on the pattern established by log4j to provide flexible logging.</text>
    </revision>
  </page>
  <page>
    <title>Modules</title>
    <id>55</id>
    <revision>
      <id>2873</id>
      <timestamp>2010-08-02T16:59:43Z</timestamp>
      <contributor>
        <username>Sallamar</username>
        <id>128</id>
      </contributor>
      <minor/>
      <comment>Removed a spam link</comment>
      <text xml:space="preserve">'''STATUS: [[/1.1|1.1]] RATIFIED'''

== Modules ==

To date, client side JavaScript has generally been able to get away with something as simple as the &lt;script&gt; tag and no standard way to do namespaces. On the server, it's a bit different because you're more likely to use more libraries and you can potentially load up a lot of code. Having a basic system for loading code and encouraging the use of namespaces to avoid unintentional interference will underlie everything else.

=== Specifications ===

* [[/1.0|1.0]]
* [[/1.1|1.1]] ([[/1.0|1.0]] + [[/Meta|Module Meta-object Amendment]]).
* [[/1.1.1|1.1.1]] relaxes details for &quot;main&quot; and enumerability requirements.
** version 1.1.1 will need spec tweaks and more work: there has been discussion/argument over the behaviour and formation of module.id, one side going for invariance based on path relative to search paths, the other going for absolute file path, since the top level id is dependent on the require.paths at the time of module load. There is also discussion about what we should and shouldn't allow as an argument to require, particularly about camelCase (which not many platforms mandate) and about file extensions.

=== Proposals ===

Several proposals were made.  There was convergence toward the [[Modules/SecurableModules|Securable Modules]] proposal, with several implementations passing the unit tests.

# [[Modules/GlobalFileLoading|Global File Loading]]
# [[Modules/GlobalObjectLoading|Global Object Loading]]
# [[Modules/PythonicModules|Pythonic Modules]]
# [[Modules/SecurableModules|Securable Modules]]

There are also proposals for amendments and supplements to these proposals:

# [[Modules/Meta]] ratified and incorporated into [[Modules/1.1]].
# [[Modules/Loaders]] for module loader specification proposals
# [[Modules/Transport]] for module transport format proposals (for a module format suitable for browser script injection)
# [[Modules/SetExports]] function for exporting something other than a plain object.
# [[Modules/Async/A]] proposes async loading.
# [[Modules/Metadata]] proposes JSON metadata.

We need proposals for:

# A module-relative &quot;resource&quot; object, like &lt;code&gt;module.resource(path).open(…)&lt;/code&gt;.
# To fix the module identifier domain.  The current specification restricts module identifiers to camelCase delimited by slashes, but this is hazardous in case-insensitve stores, and not restricted in practice.
# A page for discussing a system for injecting free variables from the exports of a foreign module
# &lt;code&gt;module.setExports(exports) exports Object&lt;/code&gt;

=== Prior Art ===

*  Spidermonkey (and Jaxer) and Rhino offer a [https://developer.mozilla.org/En/SpiderMonkey/Introduction_to_the_JavaScript_shell load] function, but does not have any specific pattern for namespacing.
* Dojo has a complete incremental loading facility in the form of [http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/functions-used-everywhere/dojo-require dojo.require] and a standard mechanism for declaring modules. dojo.require ensures that the module is loaded only once. It also manages dependecies between modules.
* The Jack project [http://github.com/tlrobinson/jack/blob/54a28398425287bddd9466955d5e8ea616eb8d47/core.js implements a simple &quot;require&quot; system].
* [http://docs.persvr.org/documentation/server-side-js Persevere uses &quot;require&quot;] (similar to Jack) for module loading.
* RingoJS implements a [http://ringojs.org/wiki/Modules%20and%20Scopes/ module system with per-module scopes] and import, include and require functions.
* jslibs bootstrapping jshost provides only basic code and loading module support, direct from file and either into the global namespace or a chosen namespace http://code.google.com/p/jslibs/wiki/jshost
* Advanced JavaScript Importing &amp; Loading Extension is the browser-independent extension that provides Javascript with namespace and dynamic script loading support ( http://ajile.iskitz.com/ )
* modulesjs an XHR JS module loader provides module loading, singleton modules ( http://modulesjs.com/ ) 
* [http://synchro.net/ Synchronet] provides a global load() method which allows a specified scope/sandbox object, passing arguments, and background/concurrent execution: http://synchro.net/docs/jsobjs.html#global
* [http://www.ejscript.org/ Ejscript] has a loadable module mechanism based on language extensions &quot;module&quot; and &quot;use module&quot; definitions. Modules can have scope, dependencies, incremental loading and optional backing native code.
* [http://torino.sourceforge.net Torino] implements a C-style &quot;#include&quot; preprocessor which is intended to provide a low-level loading mechanism on top of which more sophisticated module management schemes can be implemented in JavaScript.
* [http://wiki.eclipse.org/E4 Eclipse E4] is doing work using Rhino to support writing modular [http://wiki.eclipse.org/E4/JavaScript JavaScript bundles] that can  interoperate cleanly with the OSGi modularity layer used by Java plugins in the platform.

=== Related Discussions ===

* [http://groups.google.com/group/commonjs/browse_thread/thread/d761996c25769e6c a module system (difficult to agree)]
* [http://groups.google.com/group/commonjs/browse_frm/thread/b99a5b6eb9ed8a23 Concerns about the proposed module system(s)]
* [http://groups.google.com/group/commonjs/browse_frm/thread/2dcfbff6b6ba5928 do we need a Module object instead of require() function?]
* [http://groups.google.com/group/commonjs/browse_frm/thread/1abef605cf13c337 Are we agreed on require, in general?]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f2447ac0d593ad47 SecurableModules question]
* [http://groups.google.com/group/commonjs/browse_thread/thread/5dc7db5ceeb1422a Do you think require() should be implemented in JS?]
* [http://groups.google.com/group/commonjs/browse_thread/thread/d2dc85a2725992be Securable Modules show of hands]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c7016998d1087b5e Secureable Modules: &quot;exports&quot; vs &quot;this&quot;]
* [http://groups.google.com/group/commonjs/browse_thread/thread/e2258194f110eda2 SecurableModules: Namespacing, version numbers]
* [http://groups.google.com/group/commonjs/browse_thread/thread/d3dc1c0acd89dae5 Global Free Variable]
* [http://groups.google.com/group/commonjs/browse_thread/thread/54f089cc4a4bd69e Modules 1.2 Agenda]</text>
    </revision>
  </page>
  <page>
    <title>Modules/CompiledModules</title>
    <id>56</id>
    <revision>
      <id>2668</id>
      <timestamp>2010-04-16T12:13:11Z</timestamp>
      <contributor>
        <username>Jhuni</username>
        <id>106</id>
      </contributor>
      <comment>Standard identation is four spaces, not two, that way you can line up var statements.</comment>
      <text xml:space="preserve">&lt;source&gt; 
// ==================================================================
// browser code in development

// locked into on of these options
//
//  1) using a special XHR synchronous script loader and    
//      a) seeing poor error messages with strange line numbering
//         not corresponding with source code line numbering or
//      b) using a JavaScript interpreter written in JavaScript
//         to execute the code retrieved by the XHR. Line numbers
//         would then correspond to source code line numbers.
//         (Seems like an extreme solution.)
//
//  2) edit-compile-load-test cycle using the code below. Also
//     strange numbering in error messages that does not match
//     source files. Tools could make compile automatic but that
//     means tools are required and that is not the case in 
//     the current browser scripting world.


// ==================================================================
// compiled for production in browser

//
// library.js
//
var require = (function() {
  
    // memoized export objects
    var exportsObjects = {}

    // don't want outsider redefining &quot;require&quot; and don't want
    // to use arguments.callee so name the function here.
    var require = function(name) {
        if (exportsObject.hasOwnProperty(name)) {
            return exportsObject[name];
        }
        var exports = {};
        // memoize before executing module for cyclic dependencies
        exportsObject[name] = exports;
        modules[name](require, exports);
        return exports;
    };

    return require;
})();

var run = function(name) {
    require(name); // doesn't return exports
};

var modules = {};

//
// compiledModules.js
//
modules[&quot;math&quot;] = function(require, exports) {
    exports.add = function() {
        var sum = 0, i = 0, args = arguments, l = args.length;
        while (i &lt; l) {
            sum += args[i++];
        }
        return sum;
    };
};

modules[&quot;increment&quot;] = function(require, exports) {
    var add = require('math').add;
    exports.increment = function(val) {
        add(val, 1);
    };
};

modules[&quot;program&quot;] = function(require, exports) {
    var inc = require('increment').increment;
    var a = 1;
    inc(a); // 2
};

//
// html in document head
//
&lt;script src=&quot;library.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;compiledModules.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
    // You might not use use the window.onload property
    // but rather addEventListener/attachEvent.
    window.onload = function() {
        run(&quot;program&quot;);
    };
&lt;/script&gt;</text>
    </revision>
  </page>
  <page>
    <title>Modules/Environment</title>
    <id>57</id>
    <revision>
      <id>1210</id>
      <timestamp>2009-09-12T02:30:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-CommonJS/ +)</comment>
      <text xml:space="preserve">Moved to [[Modules/Loaders]].</text>
    </revision>
  </page>
  <page>
    <title>Modules/GlobalFileLoading</title>
    <id>58</id>
    <revision>
      <id>1819</id>
      <timestamp>2009-12-02T22:52:38Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Noted that this proposal is no longer being pursued.</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL, NO LONGER BEING PURSUED, SEE [[Modules]]'''

The following is a simple system based on loading files by filename. This is quite Ruby-like.

&lt;source&gt;
//
// Evaluate the content of the fully specified file 
// in the global scope. 
// 
load('/usr/local/lib/js/File.js')  

// 
// If no file extension is included '.js' is assumed 
// 
load('/usr/local/lib/js/File')  

// 
// Searching through the library path.  
// Suppose the path is 
// /home/peter/js:/usr/local/lib/js:/usr/lib/js 
//  
load('File')  

// 
// Use 'load' above only if this file has never been 
// loaded before. 
// 
load.once('File')  

//  
// Load a file relative to the current file's path. 
// '__DIR__' is a macro expanded to the file's absolute path 
// before the code is evaluated. It may be that __DIR__ is 
// expanded to be something like 
// 
//    /home/peter/src/foo-project  
// 
// This allows for one file to load many others distributed 
// in the same package. 
// 
//    web-framework.js 
//    web-framework/ 
//      routing.js 
//      templates.js 
//      orm.js 
// 
// This does not cross over to the browser as the browser does 
// not have macros. 
//
load(__DIR__+'subdir/foo'); 
&lt;/source&gt;
Remark: the __DIR__ macro is not necessary: the JS intepreter can as well do a chdir() to the directory of a script being loaded, effectively setting a new base path for consecutive relative includes.

Remark: I think chdir() is not a good option here because if one module does chdir to include other modules which also do chdir(), then chdir() is required before every individual &quot;load&quot;. Otherwise the current directory is basically unknown to any particular script. -- Peter Michaux

Remark: What about using the same schematics as CSS files? All references to external resources are always relative to the current file location. -- Jonas  

== sample code ==
&lt;source&gt;
// ==================================================================
// source code ------------------------------------------------------
 
//
// base.js
//
var LIB = {};

//
// math.js
//
require('base');
LIB.add = function() {
  var sum = arguments[0];
  for (var i=1; i&lt;arguments.length; i++) {
    sum += arguments[i];
  }
  return sum;
};

//
// increment.js
//
require('base');
require('math');
LIB.increment = function(val) {
  return LIB.add(val, 1);
};

//
// program.js
//
require('increment');
var a = 1;
LIB.inc(a); // 2

// ==================================================================
// browser code in development

//
// *Can* manually include all dependencies like the following.
// Other more complex techniques for manual dependency resolution
// can be used.
//
&lt;script type=&quot;text/javascript&quot;&gt;require=function(){}&lt;/script&gt;
&lt;script src=&quot;/js/src/base.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/js/src/math.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/js/src/increment.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/js/src/program.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;

// ===================================================================
// browser code in production

//
// Can just concatenate the source files and perhaps minify them.
// Other more complex techniques can be used.
//
&lt;script type=&quot;text/javascript&quot;&gt;require=function(){}&lt;/script&gt;
&lt;script src=&quot;/js/lib.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;/js/program.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;/source&gt;</text>
    </revision>
  </page>
  <page>
    <title>Modules/GlobalObjectLoading</title>
    <id>59</id>
    <revision>
      <id>1820</id>
      <timestamp>2009-12-02T22:57:03Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>Updated status.</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL, NO LONGER BEING PURSUED, SEE [[Modules]]'''

A system similar to the simple file loading as file content is still evaluated in the global scope; however, this system depends on a naming convention between file and object names. This makes it a bit more Java-like and is more heavily dependent on the library path. It removes the need to think about a file system and makes it possible to use the same system in the browser.

&lt;source&gt; 
// 
// Searching through the library path.  
// Suppose the path is 
// /home/peter/js:/usr/local/lib/js:/usr/lib/js 
// Then if can evaluate the content of the file 
// /usr/local/lib/js/io/File.js in the global scope 
// with
load('io.File')  

// 
// Use 'load' above only if this file has never been 
// loaded before. 
// 
load.once('io.File')
&lt;/source&gt;</text>
    </revision>
  </page>
  <page>
    <title>Modules/Loaders/A</title>
    <id>60</id>
    <revision>
      <id>1751</id>
      <timestamp>2009-11-22T03:20:45Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>moved [[Modules/Loaders]] to [[Modules/Loaders/A]]:&amp;#32;out of the way!</comment>
      <text xml:space="preserve">'''There has been no discussion of this proposal.'''

Sandboxes have a very simple design and do not benefit greatly from customization for particular sandbox varieties, apart from using more advanced data structures to map interesting module identifiers to their corresponding objects.  However, loaders perform a great deal of heavy lifting that can be customized for various kinds of secure and insecure sandboxes, with various kinds of storage and retrieval for module texts.  This proposal includes the names that a module author may be able to use for particular load implementations and the corresponding behavior and interface they can expect when using those member functions.

Any members of a specified object (including modules, or enumerated argument options) that are not reserved by the specification must be named with &quot;x&quot; as their first term and a vendor-specific label as their second term, like &quot;require.xChironCurryId&quot; or &quot;system.xCajaDomita&quot;.

== The Require Function/Object ==

* id: the &quot;require&quot; object MAY have an &quot;id&quot; member that must be the normalized identifier of the current module
* loader: the &quot;require&quot; object MAY have a &quot;loader&quot; member that is an interface to the object used by &quot;require&quot; to acquire module factory functions.  Tampering with this variable must not alter the behavior of &quot;require&quot;.
* main: the &quot;require&quot; object MAY have an &quot;main&quot; member that is the module ID of the module that was the entry point for this sandbox.  Thus the common Python idiom &lt;tt&gt;if __name__ == '__main__':&lt;/tt&gt; would be &lt;tt&gt;if (require.id == require.main)&lt;/tt&gt;, except that this strategy avoids the problem of double loading the main module if it's referred to elsewhere by its real name.
* isLoaded: returns whether a module exports object has been loaded for a given canonical module identifier.
* isInstance: returns whether an object is an instance of one of a module's named exports.  This is a convenient shortcut to avoid loading a module when, if the module has not been loaded as yet, the instance clearly cannot have been instantiated by one of its native exports.
* clear: forgets all loaded modules

== A Loader Object ==

* load: the &quot;loader&quot; object, if present, MUST have a &quot;load&quot; method that returns a module factory function.
** a module factory function MUST accept &quot;require&quot;, &quot;exports&quot;, and &quot;system&quot; as its arguments.
* fetch: a module loader, if present, must provide a &quot;fetch&quot; method that returns the text of a module for a given normalized, fully-qualified, absolute module identifier.
* evaluate: a module loader, if present, must provide an &quot;evaluate&quot; method that accepts a module text and returns a module factory function
** a module text MUST be a string that conforms to a JavaScript &quot;program&quot; construction.
* resolve: a module loader, if present, MUST provide a &quot;resolve&quot; method that accepts a module identifier (that may be a relative module identifier) and optionally a base module identifier (that must be an absolute module identifier) and returns the corresponding absolute identifier of the former.
* canonical: a module loader, if present, MUST provide a &quot;normalize&quot; method that accepts an absolute module identifier and returns that identifier in its canonical form.  &quot;canonical&quot; MAY be an identity relation.  &quot;canonical&quot; may return an opaque reference object to prevent information about the underlying file system from leaking into a sandbox.
* reload: forces a module factory to be refetched, reevaluated, and memoized.  Can be used by load polymorphically in response to notification that the underlying stored module text has been modified.
* clear: forgets all loaded module factories
* getPaths MAY be present in permissive sandboxes, but MUST not be present in a secure sandbox.  Returns the list of prioritized top-level module paths.
* setPaths MAY be present in permissive sandboxes, but MUST not be present in a secure sandbox.  Sets the prioritized list of top-level paths that the loader uses to find modules.
* getExtensions MAY be present in permissive sandbox, but MUST not be present in secure sandboxes.  Gets the list of prioritized file extensions that modules may have, including the dot prefix.
* setExtensions MAY be present in permissive sandbox, but MUST not be present in secure sandboxes.  Sets the list of prioritized file extensions that modules may have, including the dot prefix.</text>
    </revision>
  </page>
  <page>
    <title>Modules/Meta</title>
    <id>61</id>
    <revision>
      <id>1707</id>
      <timestamp>2009-10-16T05:08:44Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Contract */</comment>
      <text xml:space="preserve">'''STATUS: RATIFIED AND INTEGRATED IN [[Modules/1.1]]'''

== Contract ==

This proposal adds the following on top of what is already specified by [[Modules/SecurableModules]].

=== Module Context ===

# In a module, there must be a free variable &quot;module&quot;, that is an Object.
## The &quot;module&quot; object must have a read-only, don't delete &quot;id&quot; property that is the top-level &quot;id&quot; of the module. The &quot;id&quot; property must be such that &lt;tt&gt;require(module.id)&lt;/tt&gt; will return the exports object from which the &lt;tt&gt;module.id&lt;/tt&gt; originated. (That is to say module.id can be passed to another module, and requiring that must return the original module).
## The &quot;module&quot; object may have a &quot;uri&quot; String that is the fully-qualified URI to the resource from which the module was created.  The &quot;uri&quot; property must not exist in a sandbox.

# ''In a module, there is a free variable &quot;require&quot;, that is a function.''
## …
## …
## …
## …
## The &quot;require&quot; function may have a &quot;main&quot; property that is read-only, don't delete and represents the top-level &quot;module&quot; object of the program. If this property is provided, its must be referentially identical to the &quot;module&quot; object of the main program.
## The &quot;require&quot; function may have a &quot;paths&quot; attribute, that is a prioritized Array of path Strings, from high to low, of paths to top-level module directories.
### The &quot;paths&quot; property must not exist in &quot;sandbox&quot; (a secured module system).
### The &quot;paths&quot; attribute must be referentially identical in all modules.
### Replacing the &quot;paths&quot; object with an alternate object may have no affect.
### If the &quot;paths&quot; attribute exists, in-place modification of the contents of &quot;paths&quot; must be reflected by corresponding module search behavior.
### If the &quot;paths&quot; attribute exists, it may not be an exhaustive list of search paths, as the loader may internally look in other locations before or after the mentioned paths.
### If the &quot;paths&quot; attribute exists, it is the loader's prorogative to resolve, normalize, or canonicalize the paths provided.

== Discussion ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/6ad5c2c3b005cb3b/5a0f17e43d347673 RFC require.paths behaviour]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c3682135d72b1f8 Module meta data Proposal.] (resurrection of this discussion)</text>
    </revision>
  </page>
  <page>
    <title>Modules/PythonicModules</title>
    <id>62</id>
    <revision>
      <id>2148</id>
      <timestamp>2010-03-10T11:18:05Z</timestamp>
      <contributor>
        <username>Oberhamsi</username>
        <id>81</id>
      </contributor>
      <text xml:space="preserve">'''STATUS: PROPOSAL, NO LONGER BEING PURSUED, SEE [[Modules]]'''

= Pythonic Modules =

This proposal describes a module system similar to the one implemented in [http://github.com/ringo/ringojs/tree/master RingoJS]. I call it Pythonic Modules because it is heavily inspired by the way modules are [http://pytut.infogami.com/node8.html implemented in Python]. It provides protection against name collisions by isolating module scopes, while being reasonably easy to implement in a server or standalone JavaScript runtime.

I have written about this in [http://dev.helma.org/wiki/Modules+and+Scopes+in+Helma+NG/ other places], but I try to rephrase its essential properties here in a more general way. I will for the purpose of this proposal refer to a generic JavaScript runtime that implements the pythonic module system. Note that while our JavaScript runtime uses the file system to store and access its modules, this is no requirement of this proposal.

== Scripts are modules ==

For our JavaScript runtime, every script represents a module. This is true for all scripts, regardless of whether they are part of a core library or a user-written application. There is nothing special a script must contain in order to make it a module.

== Module names ==

Modules are managed by the JavaScript runtime by looking for files within one or more directories which we call module directories. A module name translates to a file name by adding the .js extension to it. Thus, when our JavaScript runtime tries to load a module named A, it will look for a file called A.js in its module directories. Modules that live in subdirectories of a module directory are accessed using a dotted module name where each element in the module name corresponds ot an element in the file path. For example, a module named A.B.C will cause our JavaScript runtime to search its module directories for a file called A/B/C.js.

== Every module has its own scope ==

This is maybe the most radical step away from JavaScript as we know it, since the shared global scope is one of JavaScript's more prominent features. But it is also one of the most critisized one, and one that will seriously hamper development of real large scale applications. As it turns out, giving each script its own top level scope is both easy and backwards compatible.

When our JavaScript runtime starts up, it creates the familiar global JavaScript object containing the Object, Array, Date, Math, etc. objects. However, whenever the JavaScript runtime loads a module, it doesn't use the global object but instead creates a new, empty JavaScript object to evaluate the module on. This object, which we call the module scope, has two important features: 

1. It represents a top-level scope, i.e. its parent scope is set to null.
2. It has the shared global object in its prototype chain.

This makes sure module code will never pollute the shared global object (or any other module scope, for that matter), because it is the top-most object in its scope chain, but can still see the standard global objects through the module scope's prototype chain. With this setup, modules code will never unintentionally pollute any other scope. Users of our JavaScript runtime can just write global functions and variables, even accidentally omitting the var keyword, without any risk of disturbing with other modules or global code.

== Importing modules ==

Since modules are shielded from each other, there must be a well-defined way for one module to load and make use of another module. Our JavaScript runtime provides one global require() function to allow one module to load and use another:
&lt;source&gt;
require('modulename')
&lt;/source&gt;

This causes our JavaScript runtime to load the module with the given name, evaluate it on a module scope, and return the module scope to the caller.

== Visibility of loaded modules ==

One great feature of the separated module scopes is protection against name collisions as described above. Another, maybe equally important feature is the fact that imported modules and module properties are only visible to the very modules that imported them. 

== Module loading and caching ==

Our JavaScript runtime keeps a map of loaded modules. Before a module is loaded, the runtime first checks whether the module has already been loaded before. If so, the existing module scope is reused. Our runtime also makes sure module scopes are registered in the loaded module map before evaluating them in order to be able to deal with cyclic imports.

== Programming Notes ==

All top-level variables inside the module are exported. Variables can be hidden by using the module pattern and ensuring the use of &quot;var&quot; so they are not exported.
&lt;source&gt;
(function() {
  var modulePrivate = 10;
  moduleExported=11;
})(); 
var otherModuleExported=12;
&lt;/source&gt;

== Open issues ==

A discussion on irc happened about the separator in the require argument. Should it be require('A.B') or require('A/B')? There are other options but these seemed to be the popular options.

As discussed on irc, the argument to require probably shouldn't have a file extension (e.g. &quot;.js&quot; or &quot;.so&quot;) because that ties to an implementation. The JavaScript code should not need to know how a library is implemented.

Should the module lookup path be mutable during program execution? Perhaps an array require.path could be mutated for this purpose. This may be tricky to implement and seems non-essential. Can this be postponed to a later edition of the spec so as not to slow things down?

Should the module automatically-tried extensions be mutable during program execution. Something like require.extensions=[&quot;dll&quot;,&quot;js&quot;] ?

Should there be a require.loaded array-valued property with all the loaded module names or scopes? This seems non-essential. Can this be postponed to a later edition of the spec so as not to slow things down?

What is the value of &quot;this&quot; when evaluated in the module scope?</text>
    </revision>
  </page>
  <page>
    <title>Modules/ScriptModules</title>
    <id>63</id>
    <revision>
      <id>2672</id>
      <timestamp>2010-04-16T12:41:15Z</timestamp>
      <contributor>
        <username>Jhuni</username>
        <id>106</id>
      </contributor>
      <text xml:space="preserve">== Browser Sharable as Written ==

It would be handy to be able to share modules &quot;as written&quot; with the browser by loading the source code with html script tags. I think the following source code allows this feature. The first and last lines of the modules would be idiomatic boilerplate for modules to be shared on both the client and server.

There are several ways to write the first and last lines. Some of them are shorter than below but give up some of the protection of the global namespace. The technique below only relies on the browser having the &quot;require.install&quot; property and the server not having it.
&lt;source&gt;
// ==================================================================
// source code

//
// math.js
//
(function(){

    var mod = function(require,exports) {

        exports.add = function() {
            var sum = 0, i = 0, args = arguments, l = args.length;
            while (i &lt; l) {
                sum += args[i++];
            }
            return sum;
        };

    };

    require.install ? require.install('math', mod) : mod(require, exports);

})();

//
// increment.js
//
(function(){

    var mod = function(require,exports) {

	var add = require('math').add;
	exports.increment = function(val) {
	    return add(val, 1);
	};
	
    };

    require.install ? require.install('increment', mod) : mod(require, exports);

})();

//
// program.js
//
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
&lt;/source&gt;

Below is a comparison of a module written two different ways.

First, the &quot;normal&quot; way for the browser that people are accustom to seeing these days. There are other ways to do it but this is certainly one way in an attempt to make an oranges-to-oranges comparison. 
&lt;source&gt;
// define the library in a file called asdf.js
// first and last lines are boilerplate 

var LIB = LIB || {};
LIB.asdf = (function() {

    var exports={};

    var c = 1;
    exports.a = function() {
        return c;
    };
    exports.b = 2;

    return exports;

})();

// use the library in the browser

LIB.asdf.a();

// use the library on the server

require('asdf').LIB.asdf.a();

// Use the library on the server or in browser.
// A module dependent on asdf would need to 
// be written like this or something similar.

(require ? require('asdf') : window).LIB.asdf.a();
&lt;/source&gt;

Now write the library so it can be used the same way in the browser and on the server where the server has securable module loading. Note the boilerplate is only a little longer and both versions of boilerplate include the name of the module once. The main three lines of the library are the same.
&lt;source&gt; 
// define the library in a file called asdf.js
// assume &quot;exports&quot; is not defined
// assume &quot;modules&quot; and &quot;require&quot; are defined
// first and last lines are boilerplate

(function(){

    var mod = function(require, exports) {

        var c = 1;
        exports.a = function() {
            return c;
        };
        exports.b = 2;

    };

    require.install ? require.install('asdf', mod) : mod(require, exports);

})();

// use the library in the browser or on the server

require('asdf').a();
&lt;/source&gt;</text>
    </revision>
  </page>
  <page>
    <title>Modules/1.0</title>
    <id>64</id>
    <revision>
      <id>2797</id>
      <timestamp>2010-05-27T09:05:09Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=superseded
|by=1.1
|standard=yes
|published=Website:Index/specs/modules/1.0
|implementations=Flusspferd, GPSEE, Narwhal=0.1, Persevere, RingoJS, SproutCore, node.js, v8cgi, CouchDB,Smart, Yabble, Wakanda
}}

This specification addresses how modules should be written in order to be interoperable among a class of module systems that can be both client and server side, secure or insecure, implemented today or supported by future systems with syntax extensions.  These modules are offered privacy of their top scope, facility for importing singleton objects from other modules, and exporting their own API.  By implication, this specification defines the minimum features that a module system must provide in order to support interoperable modules.

== Contract ==

=== Module Context ===

# In a module, there is a free variable &quot;require&quot;, that is a function.
## The &quot;require&quot; function accepts a module identifier.
## &quot;require&quot; returns the exported API of the foreign module.
## If there is a dependency cycle, the foreign module may not have finished executing at the time it is required by one of its transitive dependencies; in this case, the object returned by &quot;require&quot; must contain at least the exports that the foreign module has prepared before the call to require that led to the current module's execution.
## If the requested module cannot be returned, &quot;require&quot; must throw an error.
# In a module, there is a free variable called &quot;exports&quot;, that is an object that the module may add its API to as it executes.
# modules must use the &quot;exports&quot; object as the only means of exporting.

=== Module Identifiers ===

# A module identifier is a String of &quot;terms&quot; delimited by forward slashes.
# A term must be a camelCase identifier, &quot;.&quot;, or &quot;..&quot;.
# Module identifiers may not have file-name extensions like &quot;.js&quot;.
# Module identifiers may be &quot;relative&quot; or &quot;top-level&quot;.  A module identifier is &quot;relative&quot; if the first term is &quot;.&quot; or &quot;..&quot;.
# Top-level identifiers are resolved off the conceptual module name space root.
# Relative identifiers are resolved relative to the identifier of the module in which &quot;require&quot; is written and called.

=== Unspecified ===

This specification leaves the following important points of interoperability unspecified:

# Whether modules are stored with a database, file system, or factory functions, or are interchangeable with link libraries.
# Whether a PATH is supported by the module loader for resolving module identifiers.

== Unit Tests ==

* [http://code.google.com/p/interoperablejs/ Unit Tests at Google Code] by Kris Kowal
* [http://github.com/ashb/interoperablejs/tree/master Unit Tests Git Mirror] by Ash Berlin

== Sample Code ==

;math.js:
&lt;source&gt;
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i &lt; l) {
        sum += args[i++];
    }
    return sum;
};
&lt;/source&gt;

;increment.js:
&lt;source&gt;
var add = require('math').add;
exports.increment = function(val) {
    return add(val, 1);
};
&lt;/source&gt;

;program.js:
&lt;source&gt;
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
&lt;/source&gt;
&lt;noinclude&gt;
== Notes ==

* [[Modules/Secure|Secure Modules]]
* [[Modules/CompiledModules|Notes on compiling modules for browsers]]
* [[Modules/ScriptModules|On writing modules that also work as &lt;script&gt;s]]

== Amendment Proposals ==

# [[Modules/Loaders|Module Loaders]]
# [[Modules/Meta|Module Metaobject]]

== Implementations ==

Passing all compliance tests:
* Flusspferd (Spidermonkey / C++) http://flusspferd.org/
* Ondrej Zara's v8cgi for V8 http://code.google.com/p/v8cgi/
* Tom Robinson's narwhal for Rhino http://github.com/tlrobinson/narwhal/
* Wes Garland's GPSEE for Spidermonkey http://code.google.com/p/gpsee/
* Kris Kowal's chiron for browsers http://github.com/kriskowal/chiron/
* Hannes Wallnoefer's RingoJS for Rhino at http://github.com/ringo/ringojs
* Ben Collver's Trogl for v8 at http://bencollver.googlepages.com/trogl-1.zip
* Atul Varma's Pydertron for Python/Spidermonkey at http://hg.toolness.com/pydertron/raw-file/tip/docs.html
* Daniel Friesen's [http://lite.monkeyscript.org MonkeyScript Lite] for Rhino
* Irakli Gozalishvili's narwhal for XULRunner http://github.com/gozala/narwhal-xulrunner/
* James Brantly's Yabble for browsers http://github.com/jbrantly/yabble
* 4D's Wakanda (JavaScriptCore/SquirrelFish) http://www.wakandasoft.com

Fully implemented:
* Kris Zyp's Persevere for Rhino at http://www.persvr.org/

In development:
* nathan smith is implementing this for JScript and ASP at http://github.com/smith/interoperablejscript/tree/master
* mob is implementing this in Ejscript http://www.ejscript.org
* pmuellr posted a sample loader http://wiki.github.com/pmuellr/modjewel
&lt;/noinclude&gt;

== Related Documents ==

* Proposal to ECMA TC39: [http://docs.google.com/Doc?id=dfgxb7gk_34gpk37z9v&amp;hl=en Module System for ES-Harmony]
* Presentation to ECMA TC39: [http://docs.google.com/Presentation?docid=dcd8d5dk_0cs639jg8&amp;hl=en Modules]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Secure</title>
    <id>65</id>
    <revision>
      <id>1122</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Modules/Secure]] to [[Modules/Secure]]</comment>
      <text xml:space="preserve">To be usable in secured module loaders, a module must conform to additional constraints:

# A module must not write to any free variables or their transitive members.
# A module must not refer to any free variables apart from primordials (&quot;Object&quot;, &quot;Array&quot;, etc. as defined by ECMAScript), &quot;require&quot;, &quot;environment&quot;, and &quot;exports&quot;.
# A module must not tamper with (assign to, assign to members of, delete, or otherwise mutate) the transitive primordials.</text>
    </revision>
  </page>
  <page>
    <title>Packaging</title>
    <id>66</id>
    <revision>
      <id>1083</id>
      <timestamp>2009-09-10T20:02:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Packaging]] to [[Packaging]]</comment>
      <text xml:space="preserve">= Packaging, installation and deployment =

One of the most important parts of this project is to provide a repository for code releases and an easy way to install that code for development and production uses. Possibly the most successful example of this is Perl's CPAN. Python has its Cheeseshop (also called the Python Package Index) and Ruby has gems.

It is important to work alongside the Linux distro packaging mechanism, but for Windows, Mac users and people who want to run something that is not yet in their distro, having a language specific installation process is critical.</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Pending Business</title>
    <id>67</id>
    <revision>
      <id>931</id>
      <timestamp>2009-09-10T03:04:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[Status]]</comment>
      <text xml:space="preserve">#REDIRECT [[Status]]</text>
    </revision>
  </page>
  <page>
    <title>Process</title>
    <id>68</id>
    <revision>
      <id>1217</id>
      <timestamp>2009-09-12T02:42:14Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Automated text replacement  (-CommonJS/ +)</comment>
      <text xml:space="preserve">'''STATUS: RATIFIED'''

The goal of this project is to have something that people can run and build web frameworks and applications on.

The process needs to support that goal, plus the goal of having a specification that allows people to make other JS interpreters/platforms compatible.

There are two parts to the process:

# Creating the specs and code
# Handling disagreements

Number 1 is how things get done. Number 2 is how we ensure that number 1 is able to continue in face of inevitable disagreements.

* [[ProposalProcess|CommonJS Proposal Process]]

(to be continued...)

== Prior Art ==

* [http://www.python.org/dev/peps/pep-0001/ Python Enhancement Proposal] (PEP). This process is not completely applicable, because Python has a dictator that keeps things from spiraling out of control.
* [http://srfi.schemers.org/ Scheme Requests For Implementation]
* [http://en.wikipedia.org/wiki/Request_for_Comments#RFC_production_and_evolution Request for Comments] (RFC)
* [http://www.apache.org/foundation/voting.html Apache Voting]

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/280c8b0375783604 Organisation and Making Decisions]
* [http://groups.google.com/group/commonjs/browse_thread/thread/5271db92e9e22dbd A modest proposal for a simple proposal process]
* [http://groups.google.com/group/commonjs/browse_thread/thread/130b5ecd678befeb Spec medium]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f415d73c2cefa45e A proposal for modesty]</text>
    </revision>
  </page>
  <page>
    <title>Promise Manager</title>
    <id>69</id>
    <revision>
      <id>1845</id>
      <timestamp>2009-12-11T02:02:52Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <comment>/* Proposed API */</comment>
      <text xml:space="preserve">= Promise Manager =

Promise manager provides a convenience API for handling promises.

== Prior Art ==

* [https://vsci.hpl.hp.com/-/7fuxka/#s=yuwsw2qt3bde7b ref_send]. A promise manager.

== Proposed API ==
A top-level 'promise' module should export the functions defined here:

http://waterken.sourceforge.net/web_send/

In addition, a promise module should export:

; wait()
: This will block the execution of the current function while waiting for the Promise to be fulfilled, *if* the implementation and this Promise support this operation. If supported, the function will return the result of the resolved Promise when it is fulfilled. If the Promise is resolved with an error, than this function will throw the provided error object. If the concurrency model of the implementation or the Promise object does not support blocking, the &quot;wait&quot; property should be a null or undefined. This API is not intended to imply that implementations that provide a &quot;wait&quot; function are superior.

== Related Discussions ==

http://groups.google.com/group/commonjs/browse_thread/thread/e93f73ef97e88439/9cdb490abb8edfa6
http://groups.google.com/group/commonjs/browse_thread/thread/86fd52c9be191c4b</text>
    </revision>
  </page>
  <page>
    <title>Promises</title>
    <id>70</id>
    <revision>
      <id>2554</id>
      <timestamp>2010-04-05T23:20:51Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Proposals */</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL, DISCUSSION'''

= Promises =

Promises provide a well-defined interface for interacting with an object that represents the result of an action that is performed asynchronously, and may or may not be finished at any given point in time. By utilizing a standard interface, different components can return promises for asynchronous actions and consumers can utilize the promises in a predictable manner. Promises can also provide the fundamental entity to be leveraged for more syntactically convenient language-level extensions that assist with asynchronicity.

== Prior Art ==

* [http://docs.dojocampus.org/dojo/Deferred Dojo's Deferred] A form of promises that was inherited from MochiKit and Twisted.
* [http://waterken.sourceforge.net/web_send/#Q ref_send]. A promise manager.
* [http://wiki.erights.org/wiki/Object_Ref]. E reference API

== Proposals ==

* [[Promises/A]] by Kris Zyp
* [[Promises/B]] by Kris Kowal

== Requirements ==

* 1. if a function receives a promise as its input, that function must itself return a promise for its output.  Provide a simple mechanism that guarantees, in the face of programmer error, non-determinism, and malice:
* 1.1. that defends the function's internal consistency from attack by the provider of the input promise.
* 1.2. that defends the function's internal consistency from attack by the consumer of the output promise.
* 1.3 that defends each recipient of the output promise from each other recipient.
* 1.4 that prevents the input promise from being leaked to the output consumer.  The return value of this expression must never be the input or provide the consumer from gaining direct access to the input.

 function API(input) {
     return when(input, function (input) {
     });
 };

For example, a password checking API must be able to retain a reference to a remote table of password hashes and must never give the consumer direct access to any of those hashes.

 function PasswordChecker(accounts) {
     return function (user, password) {
         var passwordHash = Q.get(accounts, user);
         return when(passwordHash, function (passwordHash) {
             if (hash(password) === passwordHash)
                 return true;
         };
     };
 }

 // returns a password checking capability
 // but does not return access to the passwordHash
 return PasswordChecker(accounts);

* 1.4. when the input is resolved, and if it is discovered that there is additional unresolved input, permit the function to forward a new promise.
* 1.5. that permits the function to either forward the failure of its input, or recover from that failure by forwarding a resolved value, or recover by forwarding a new promise to eventually resolve or fail later. 

* 2. avoid interleaving hazards.
* 2.1. prevent promise consumers from giving promise providers direct use of their callbacks as in these counter-examples:

 var internalCounter = 0;
 
 // /!\ HAZARD: untrusted promise given direct access to a
 // function that has the capability to alter internal
 // state, either during the same turn or in any future turn
 promise(&quot;when&quot;, function () {
     internalCounter++;
 });
 
 // /!\ HAZARD: untrusted promise given direct access to a
 // function that has the capability to alter internal
 // state, either during the same turn or in any future turn
 promise.when(function () {
     internalCounter++;
 });
 
 // /!\ HAZARD: untrusted promise given direct access to a
 // function that has the capability to alter internal
 // state, either during the same turn or in any future turn
 promise.then(function () {
     internalCounter++;
 });
 
 ASSERT.equal(internalCounter, 0);

* 2.2. prevent promise providers from calling a consumer's internal callbacks in the same turn as they are registered.

 // /!\ HAZARD: untrusted promise given direct access to a
 // function that has the capability to alter internal
 // state, either during the same turn or in any future turn
 var internalCounter = 0;
 when(promise, function () {
     internalCounter++;
 });
 ASSERT.equal(internalCounter, 0);

* 2.3. prevent promise providers from calling a consumer's internal callback or errback more than once, ever.

 var internalCounter = 0;
 when(promise, function (value) {
     internalCounter++;
 }, function (error) {
     internalCounter++;
 });
 setTimeout(function () {
     ASSERT.ok(internalCounter == 0 || internalCounter == 1);
 }, forever);

* 3. Separate the concerns of &quot;resolving&quot; from &quot;observing resolution&quot;.
* 3.1 permit an API to safely produce a &quot;deferred&quot;, retain the &quot;resolver&quot; portion for itself, and distribute the &quot;promise&quot; component to any number of mutually suspicious consumers.
* 3.2 &quot;Competitive Races&quot;: permit an API to safely produce a &quot;deferred&quot;, retain the &quot;promise&quot; portion for itself, and distribute the &quot;resolver&quot; component to any number of mutually suspicious consumers.
* 4. provide a mechanism that permits a promise consumer to throw an exception in any turn where a suspicious promise attempts to resolve multiple times.
* 5. Provide support for arbitrary message passing to promises, including support for intercepting arbitrary messages for which no handler has been explicitly provided.


== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/e93f73ef97e88439/9cdb490abb8edfa6 Promise API Proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/d567d30e2bbea598 CommonJS Promises and the Q API]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c5a26c43640ede26 A Different Approach to Future/Promise]</text>
    </revision>
  </page>
  <page>
    <title>ProposalProcess</title>
    <id>71</id>
    <revision>
      <id>1125</id>
      <timestamp>2009-09-10T20:25:03Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/ProposalProcess]] to [[ProposalProcess]]</comment>
      <text xml:space="preserve">'''STATE: DISCUSSION'''

We adopt a [http://www.perlfoundation.org/perl5/index.cgi?jfdi JFDI] policy regarding adding proposals to CommonJS.

As long as the page makes the level of acceptance clear with a line at the top, it's not a problem.

== State 1: &quot;Proposed&quot; ==

&quot;Hay guys, I have an idea for a topic!&quot;

Don't say it, just do it.  Add a page to the wiki describing your proposal.

Bonus points if you can point at working code.  It's not always prudent to implement something complicated before discussing with the group, since it might be misguided and difficult, but at the very least, rough sketch/prototype/proof of concept often helps crystallize the discussion.

Congratulations.  You own the idea now.  You're responsible for maintaining the wiki page, counting votes, starting the discussion, etc.

If it's not worth it to you to do the work, then it's probably not important enough to be in the spec.  This ensures that all ideas need to get over a bit of a hump to get accepted.

== State 2: &quot;Discussion&quot; ==

&quot;Let's talk about my idea!&quot;

Send a message to [http://groups.google.com/group/commonjs CommonJS] with a link to the wiki page. We'll talk about it, build all kinds of bike sheds.

This should last at least a few days, or however long necessary to flesh out any dissenting opinions.  People start weighing in with their votes.

If you have an opinion, share it now.  If you don't care one way or the other, then stay out of it.

=== Silence is not consent. ===

''Some'' discussion must occur for the idea to progress to &quot;official accepted&quot; status.  If someone suggests something, and no one responds, then the idea remains open indefinitely.

If you suggest something, and no one else speaks up in favor of it, that doesn't mean it's a bad idea.  However, this is probably something that you should just put in your own application, and it most likely does not belong in the CommonJS specification.  This bit of inertia prevents us from building specifications no one wants.

The flip side of this: if someone suggests something, and you think it's a good idea, ''Speak up!''

=== Unanimity is Suspect ===

There may be cases when everyone involved in the discussion is in favor of the proposal.  This probably means that someone's voice isn't being heard.

In the case of a completely one-sided discussion, make some effort to figure out who might be against it, and try to ping them directly, or at least wait until they weigh in on it before considering the issue closed.  It could be that they didn't feel strongly in the first place, or that they've been swayed by the arguments from the other side.  But there was probably a reason for their initial resistance, and it should be heard.

== State 3: &quot;Decided&quot; ==

&quot;We're talking in circles and here are the major ideas:...&quot;

Someone count the votes, and we make a decision.  Update the wiki page to the latest decision.

Note that a simple vote count doesn't necessarily imply a decision.  If 15 people decide that it's a good idea to do something, and the 2 people who maintain that code rebut with valid reasons why it's impossible or impractical, then the 2 should outweigh the 15, and perhaps propose some kind of alternative to meet their needs.

== State 4: &quot;Implemented&quot; ==

At least a handful of the relevant projects have implemented the spec.  Add links to implementations to the wiki page.  At this point, it's considered final, and can only be changed by restarting this process.

A proposal ''only'' reaches this state by virtue of being implemented in more than one library.  At this point, it is considered a standard, and implementers can rest assured that it will not change without good reason.</text>
    </revision>
  </page>
  <page>
    <title>RDBMS</title>
    <id>72</id>
    <revision>
      <id>1051</id>
      <timestamp>2009-09-10T19:56:26Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/RDBMS]] to [[RDBMS]]</comment>
      <text xml:space="preserve">= Relational Database Interface =

Though there are many kinds of persistence engines available, relational databases are the most commonly deployed. Relational databases have a consistent data model and a reasonably consistent set of operations. This has allowed for the creation of a standard interface in many different languages.

If it's possible to interface with other types of databases using the same kind of interface, that is a win. However, the primary goal with this API is to provide access to relational databases.

== Prior Art ==

* JSDB is JavaScript for databases http://www.jsdb.org/
* SQueaL is an XML-based SQL Schema designed for defining databases http://alt.cellosoft.com/squeal.html
* Ejscript has a low level database access API and a high level &quot;Rails like&quot; ORM http://www.ejscript.org/products/ejs/doc/api/ejscript/ejs.db-classes.html The Record class is based on the Rails ActiveRecord class.
* Jester, REST in Javascript, http://www.thoughtbot.com/projects/jester
* JSONSQL http://www.trentrichardson.com/jsonsql/
* jslibs jssqlite module http://code.google.com/p/jslibs/wiki/jssqlite
* TaffyDB, a JS database for your browser http://taffydb.com/index.cfm
* JSMemCached JS memcached client http://code.google.com/p/jsmemcached-client/
* v8cgi has a [http://code.google.com/p/v8cgi/wiki/API#MySQL_functions MySQL] class
* [http://en.wikipedia.org/wiki/Java_Database_Connectivity JDBC]
* [http://www.python.org/dev/peps/pep-0249/ Python DBAPI]
* HTML5 defines a local database API http://dev.w3.org/html5/webstorage/#databases (supported by Safari)
* Google Gears database API http://code.google.com/intl/fr/apis/gears/api_database.html

== Other notes ==

I second that proposal.

I particuarly like the model CodeIgniter uses for the dbms interface: A common interface or abstract class that is then subclassed for each database implementation. This would allow some RDBMS implementations to be done by this project, but should allow for me (a third party) to use my own driver.

What are we gonna call our interface for connecting to a database? Options: RDBMS, DB, Connection, Database? 'DB' is short and rather to the point.

    DB : Class {
    
    DB : function (driver, host, username, password, database) // or the following constructor
    
    DB : function (driver, connectionString) // mcoquet: I rather like better passing in an object with the arguments instead of a string like so:
    
    DB : function (driver, connectionConfigObj) // ie: method (&quot;mysql&quot;, {host:&quot;bla.com&quot;,port:&quot;3306&quot;,user:&quot;username&quot;,pass:&quot;mypass&quot;})
    
    query : function (sql) // returns a JS object
    
    execute : function (sql)
    
    version : function ()
    
    close : function()
    
    }

I haven't defined any sort of ResultSet object because I'm left to understand that a ResultSet class merely (or often) provides a pretty interface for looping through the results and getting some other minor meta data. Most of this functionality can be achieved by providing a simple structured Javascript object. For example:

    myResultSet: {
    
    meta: ['id', 'name', 'age'],
    
    data: [
    
    { id: 1, name: 'Yunero', age: 22 },
    
    { id: 2, name: 'Abbadon', age: 45 },
    
    { id: 3, name: 'Luna', age: 31 }
    
    ]
    
    }

Is there much else a recordset needs?

The DB interface is slim to say the least; Often drivers and classes have all sorts of helper methods; In the case of an RDBMS we could add all sorts of methods for update, select, delete, creating/manipulating database schema,.. but often is the case that the more that gets added - the more politics and ideals are gonna slow it down. Should there be more to this design? Perhaps the DB interface above should be more function overloaded?

The prepared statement style of querying (passing a string with &quot;?&quot; placeholders, and additional arguments filling in the placeholders) is a good way of preventing SQL injection. Should it support that syntax?


== ORMs ==

Object relational mappers would use the interface defined here, but are still an area of active exploration and not one to standardize at this time.

* ActiveRecord.js, ORM in Javascript http://www.activerecordjs.org/
* Ejscript Record ORM http://www.ejscript.org/products/ejs/doc/api/ejscript/ejs.db-classes.html</text>
    </revision>
  </page>
  <page>
    <title>Random Links</title>
    <id>73</id>
    <revision>
      <id>1079</id>
      <timestamp>2009-09-10T20:00:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Random Links]] to [[Random Links]]</comment>
      <text xml:space="preserve">http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/

http://www.blueskyonmars.com/2009/01/30/server-javascript-wiki-and-irc/

http://ajaxian.com/archives/what-server-side-javascript-needs-join-in

http://www.blueskyonmars.com/2009/02/05/serverjs-one-week-into-building-a-better-javascript/

http://pmuellr.blogspot.com/2009/02/its-alive-javascript-modules.html

http://peter.michaux.ca/articles/a-bright-future-for-standardized-server-side-javascript</text>
    </revision>
  </page>
  <page>
    <title>Runtime Services</title>
    <id>74</id>
    <revision>
      <id>2112</id>
      <timestamp>2010-02-18T21:30:50Z</timestamp>
      <contributor>
        <username>Ruediger</username>
        <id>75</id>
      </contributor>
      <text xml:space="preserve">= Language and Runtime Services =

This API provides information about the JavaScript interpreter and its environment.

== Prior Art ==

* [http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/index.html Ejscript] has an &quot;ejs.sys&quot; module that provides a set of classes for system level activities such as Debug control, GC management, Memory resource utilization and command execution
* The JSAPI is the C API for the SpiderMonkey JavaScript engine https://developer.mozilla.org/En/SpiderMonkey/JSAPI_Reference
* [http://flusspferd.org/docs/js/flusspferd%20core/flusspferd.html Flusspferd's flusspferd module]
* Python's [http://docs.python.org/library/sys.html sys module] has some of this kind of information for Python.</text>
    </revision>
  </page>
  <page>
    <title>Sockets</title>
    <id>75</id>
    <revision>
      <id>1747</id>
      <timestamp>2009-11-16T11:47:19Z</timestamp>
      <contributor>
        <username>Paraboul</username>
        <id>36</id>
      </contributor>
      <comment>/* Prior Art */</comment>
      <text xml:space="preserve">== Requirements/Proposals ==

* [[Sockets/A]] Proposal
* [[IO/B/Socket]] of the [[IO/B]] proposal

== Questionnaires and show of hands ==

* Summary/Comparison of current Socket APIs used by JS engines: [http://spreadsheets.google.com/pub?key=tYP9b4a7U5ezmh1ivHURJXg CommonJS Socket Object Survey]
* [[/Show of hands/]]

== Prior Art ==

*  NSPR Socket Manipulation Functions https://developer.mozilla.org/en/NSPR_API_Reference/I%2f%2fO_Functions#Socket_Manipulation_Functions
* W3 WebSocket interface http://dev.w3.org/html5/spec/Overview.html#network
* v8cgi has a [http://code.google.com/p/v8cgi/wiki/API#Socket_functions Socket] class
* jslibs jsio module This module is based on Netscape Portable Runtime (NSPR) that provides a platform-neutral API for system level and libc like functions. http://code.google.com/p/jslibs/wiki/jsio
* Synchronet provides a Socket class that supports TCP and UDP sockets and provides a fairly complete wrapper for the Berkeley Sockets API: http://synchro.net/docs/jsobjs.html#Socket
* Ejscript provides a Socket class too for TCP and UPP. See: http://www.ejscript.org/products/ejs/doc/api/gen/ejscript/ejs.io-Socket.html 
* [http://jaxer.org/ Jaxer] provides a [http://github.com/aptana/Jaxer/blob/master/server/framework/IO/Socket.js Socket implementation].
* [http://www.ape-project.org/ APE] provides a high level socket API : http://www.ape-project.org/wiki/index.php/How_to_build_a_serverside_JS_module#Sockets

=== Inspiration  ===

* some free time, a couple of Cokes and wanting CommonJS implementations of File and Socket ASAP

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/f415d73c2cefa45e/81461f32e8d22303 A proposal for modesty]
* [http://groups.google.com/group/commonjs/browse_thread/thread/6cce4e4730c35651/29d855b960ab640c The case for a dedicated I/O spec]</text>
    </revision>
  </page>
  <page>
    <title>Status</title>
    <id>76</id>
    <revision>
      <id>1989</id>
      <timestamp>2010-01-15T04:54:41Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Resolutions */ fixed chronological order</comment>
      <text xml:space="preserve">This page summarizes the group's status.

== Require Discussion ==

* [[Binary|Binary Proposal Ratification]]
* [[Filesystem/A#Todo|Filesystem Proposal Todo List]]
* [[Encodings|Encodings API Proposal Ratification]]
* [[System|System Module Additional Proposed Names]]
* [[Modules/Loaders|Standard Module Loader API]] (not ready for discussion, pending rewrite - KrisKowal)
* C Runtime Linkage API Proposals
* C Module API Proposals
* Unit Testing Extensions, Gearing Toward QUnit DSL Compatibility

== Discussion ==

* [[Filesystem/A/0|Filesystem Proposal A/0]] (low-level file system proposal)

== Show of Hands ==

== Resolutions ==

* [[Packages/1.0]] (ratified)
* [[Unit_Testing/1.0]] (ratified)
* [[System/1.0]] (ratified)
* [[Modules/1.1]] Meta Object Amendment (ratified)
* [[Modules/1.0]] (ratified)

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/602310411fa74f4d August, 2009]</text>
    </revision>
  </page>
  <page>
    <title>System/1.0</title>
    <id>77</id>
    <revision>
      <id>2801</id>
      <timestamp>2010-05-27T09:12:04Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=implementations
|standard=yes
|implementations=Flusspferd, GPSEE, NarwhalRhino=0.2, NarwhalNode=0.5, NarwhalJSC=0.2, RingoJS, SproutCore, v8cgi, Wakanda
}}

= System Interface =

All platforms must support a module, &quot;system&quot;, that MUST contain the following attributes.

* stdin: the standard input stream, an object with the same API as a file opened with the mode &quot;r&quot; with no encoding.
* stdout: the standard output stream, an object with the same API as a file opened with the mode &quot;w&quot; with no encoding.
* stderr: the standard error stream, an object with the same API as a file opened with the mode &quot;w&quot; with no encoding.
* env: an Object containing posix-style or CGI environment variables.
* args: an Array containing the command line arguments for the invoking arguments, not including the interpreter/engine but including the path to the program as it was executed. See also the [[Command Line|Command Line page]].

Any names not mentioned here or amended into this specification later should begin with &quot;x&quot; and a vendor-specific label as a prefix, like system.xCajaDomita.  This will permit the future standardization of additional names as needed. Please request additional standard names below.

= Compliant Implementations =

* [http://github.com/tlrobinson/narwhal/ Narwhal]
* [http://flusspferd.org/ Flusspferd] (in 0.7)
* [http://github.com/ringo/ringojs/ RingoJS] (in 0.4)
* [http://code.google.com/p/v8cgi/ v8cgi]

= Proposals for Future Versions =

The following names have been proposed but not ratified for inclusion in the System proposal.

The &quot;system&quot; module MAY export the following functions, that if preset MUST behave as specified.

* print: a function that forwards its thisp and arguments to &quot;system.stdout.print&quot; with lazy binding (meaning that, if system.stdout is replaced, print MUST forward to the new stdout).

* log: a function that accepts a &quot;message&quot; and an optional &quot;label&quot; String.
** The label MAY be one of &quot;log&quot;, &quot;debug&quot;, &quot;warn&quot;, &quot;error&quot;, &quot;pass&quot;, &quot;fail&quot;.
** Any other, unspecified label MUST be in lower-case and begin with &quot;x&quot; and a vendor-specific label like &quot;x-v8cgi-database&quot;.
** Still not sure that this belongs system. (There are lots of flavours of logging: log(&quot;x&quot;, &quot;debug&quot;) vs log.debug(&quot;x&quot;). Also prefixed logging (by namespace) doesn't work with this form) [[User:Ashb|Ashb]]

* platform: a string with its vendor-specific platform name.
** Is this meant to be the OS name or the commonjs project name (&quot;flusspferd&quot;,&quot;gpsee&quot;,&quot;narwhal&quot; etc)? [[User:Ashb|Ashb]]

* global: the &quot;system&quot; MAY contain a reference to the global object.

* command: an array containing argv[0] and any subsequent arguments that would be relevant for &quot;Usage:&quot; lines.  argv[0] would be removed from system.args.  [http://groups.google.com/group/commonjs/browse_thread/thread/6d1063937b0b0a3c] Supporters: KrisKowal, ChristophDorn, AshBerlin, DonnyViszneki

* Split &quot;env&quot;, &quot;args&quot;, and &quot;command&quot; into one module, so stdio can be alternately imported as synchronous or asynchronous in another module.

== Removed proposals ==

* fs: a file default file system root object conforming to the File System API

* print (proposal A): The &quot;system&quot; MAY have a &quot;print&quot; function that accepts a &quot;message&quot; and an optional &quot;label&quot; String.
** The label MAY be one of &quot;log&quot;, &quot;warn&quot;, &quot;error&quot;, &quot;pass&quot;, &quot;fail&quot;.
** Any other, unspecified label MUST be in lower-case and begin with &quot;x&quot; and a vendor-specific label like &quot;x-v8cgi-database&quot;.
** '''Counter-argument''' This is infact not printing, but logging. 1) there is lots of logging frameworks, 2) it probably doesn't belong on sys, certainl not called ''print''
*** '''Counter-argument''' However, ''print'' has meant to write a line to stdout in many languages.  That it would frequently be used for logging in non-stdio contexts is not necessarily relevant.

= Show of Hands =

[[System/ArchivedShowOfHands]]

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/4f6c16e2f4c14c25/7c10fe164ead35c0?lnk=gst Module System feedback]
* [http://groups.google.com/group/commonjs/browse_thread/thread/749c3777f62cf34 System API Proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/6d1063937b0b0a3c System command routing]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/System/AmendmentProposals</title>
    <id>78</id>
    <revision>
      <id>1124</id>
      <timestamp>2009-09-10T20:24:46Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[System]]</comment>
      <text xml:space="preserve">#REDIRECT [[System]]</text>
    </revision>
  </page>
  <page>
    <title>System/1.0/ArchivedShowOfHands</title>
    <id>79</id>
    <revision>
      <id>1700</id>
      <timestamp>2009-10-16T04:56:52Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>moved [[System/ArchivedShowOfHands]] to [[System/1.0/ArchivedShowOfHands]]</comment>
      <text xml:space="preserve">= Archived &quot;Show of Hands&quot; =

== Archived 2009-06-18 ==

module or free variable:
* Z as a free variable
** Kris Kowal
** Ihab Awad
* Y as a module
** Hannes Wallnoefer
** Peter Michaux
** Chris Zumbrunn
** Robert Thurnher
** Aristid Breitkreuz
** Ash Berlin

== Archived 2009-05-28 ==

arguments:
* A arguments
** Ondrej Zara
** Wes Garland
** Daniel Friesen
** Ash Berlin
* B args
** Tom Robinson,
**  Kevin Dangoor, 
** Hannes Wallnoefer, 
** Michael O'Brien, 
** Chris Zumbrunn,
** Robert Thurnher
** George Moschovitis
* C argv
** Tom Robinson
** Kris Kowal

environment:
* 1 env
** Ondrej Zara
** Tom Robinson
** Kris Kowal
** Kevin Dangoor
** Hannes Wallnoefer
** Michael O'Brien
** Chris Zumbrunn
** Robert Thurnher
** George Moschovitis
** Ash Berlin
* 2 environ
* 3 environment
** Wes Garland

system:
* I sys
** Tom Robinson,
** Kris Kowal
** Aristid Breitkreuz
* II System
** Ondrej Zara
* III system
** Ondrej Zara, 
** Kevin Dangoor, 
** Hannes Wallnoefer, 
** Chris Zumbrunn, 
** Robert Thurnher
** George Moschovitis
** Ash Berlin

[[Category:Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Target Platforms</title>
    <id>80</id>
    <revision>
      <id>843</id>
      <timestamp>2009-09-10T02:14:58Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[CommonJS/Target Platforms]] to [[Target Platforms]]</comment>
      <text xml:space="preserve">There are four main open source JavaScript interpreters today: Rhino, Spidermonkey, v8 and JavaScriptCore. Our goal is that libraries and applications that use the APIs defined here (and nothing else platform specific) will run unmodified on all four of these interpreters.

http://developer.mozilla.org/en/SpiderMonkey

http://code.google.com/p/v8/

http://trac.webkit.org/wiki/SquirrelFish

http://www.mozilla.org/rhino/

Some other JS engines:

http://www.ejscript.org/

http://esxx.org/

http://en.wikipedia.org/wiki/List_of_JavaScript_engines

== Code Volunteers ==

=== Rhino ===

*  Chris Zumbrunn ( http://zumbrunn.com/ , chris@zumbrunn.com ) - in the context of Helma 1.x, Apache Sling and Helma NG
* Peter Michaux (http://peter.michaux.ca/, petermichaux@gmail.com)
* Kris Zyp (http://www.sitepen.com, kris@sitepen.com implementing in Persevere: http://www.persvr.org/)
* Robert Thurnher (http://soup.robert42.com, r.thurnher@gmail.com)

=== Spidermonkey ===

* Mário Valente ( http://mv.asterisco.pt/ , mfvalente@gmail.com )
* Wes Garland ( http://www.page.ca/, wes@page.ca )
* Davey Waterson (geekfreak AT gmail)

=== V8 ===
* Lorenzo Pastrana (http://www.happyendfilms.com/#/profile:3, pastrana at ultraflat dot net)

=== JavaScriptCore ===

=== Ejscript ===

* Michael O'Brien (http://www.ejscript.org/, mob@embedthis.com)</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing</title>
    <id>81</id>
    <revision>
      <id>2778</id>
      <timestamp>2010-05-22T16:58:01Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Specifications and Proposals */ NodeJS calls for notOk</comment>
      <text xml:space="preserve">'''STATUS: 1.0 RATIFIED, AMENDMENT PROPOSALS PENDING'''

= Unit testing =

Automated tests are an important part of software development today. Providing a standard test library will help encourage more people to write more tests. Additionally, the API specification will likely be written in the form of tests, so this component will be needed by the CommonJS project itself.

Testing involves both an API for easily defining tests and running assertions, plus a tool (or tools) for locating and running the tests.

== Specifications and Proposals ==

* [[/1.0|1.0]] '''ratified'''

Known spec bugs in version 1.0:

* Not self-consistent: &lt;code&gt;&lt;pre&gt;assert.equal(4,new Number(4));&lt;/pre&gt;&lt;pre&gt;assert.deepEqual(4, new Number(4));&lt;/pre&gt;&lt;/code&gt;
* Not self-consistent: &lt;code&gt;&lt;pre&gt;assert.equal(/a/, /a/g);&lt;/pre&gt;&lt;pre&gt;assert.deepEqual(/a/, /a/g);&lt;/pre&gt;&lt;/code&gt;
* 7.4 talks about checking prototype properties, not the internal [&amp;#91;Prototype]] itself (&lt;tt&gt;__proto__&lt;/tt&gt; or &lt;tt&gt;Object.getPrototypeOf&lt;/tt&gt;)
* Does not handle string equivalence, specifically that strings in deep equivalence calls must be identical, not equal after coercion.
* &lt;code&gt;assert.throws&lt;/code&gt; has to be written &lt;code&gt;assert['throws']&lt;/code&gt; in some implementations to get around protected keywords or JSLint
* There's a call for &quot;assert.equal&quot; to either be strict or &quot;fixed&quot; for some value of correctness for equality comparison.  [http://groups.google.com/group/commonjs/browse_thread/thread/f2069b1ef5bf4c67]
* The NodeJS mailing list calls for &quot;assert.ifError&quot;, &quot;assert.noError&quot;, or &quot;assert.notOk&quot; [http://groups.google.com/group/nodejs/browse_thread/thread/674dbb3b1dccdf7a]

== Prior Art ==

* [http://jsunit.berlios.de/ JsUnit] - browser, native, Ant, and Maven based test runners
* [http://code.google.com/p/rhinounit/ rhinounit] - Ant based test runner
* JavaScript Assertion Unit -
* [http://docs.jquery.com/QUnit QUnit] jQuery's unit testing framework, browser based
* [http://download.dojotoolkit.org/current-stable/dojo-release-1.2.3/util/doh/ DOH]  JavaScript unit testing framework (used by Dojo, but without Dojo dependencies), supports browsers and stand-alone JavaScript environments.
* JSSpec is a Javascript BDD(Behavior Driven Development) framework. http://code.google.com/p/jsspec/
* JSpec is a minimalistic JavaScript behavior driven development framework http://github.com/visionmedia/jspec/tree/master
* Better Javascript testing through ScrewUnit http://pivotallabs.com/users/nick/bl...ough-screwunit
* Mochitest is an [https://developer.mozilla.org/En/Mozilla_automated_testing automated testing framework] built on top of the MochiKit JavaScript libraries https://developer.mozilla.org/en/Mochitest
* Yahoo! UI Library: YUI Test http://developer.yahoo.com/yui/yuitest/
* JSMock is a fully featured Mock Object library for JavaScript that provides the necessary tools to do effective interactive based testing. http://jsmock.sourceforge.net/
* JSLitmus is a lightweight tool for creating ad-hoc JavaScript benchmark tests. http://www.broofa.com/Tools/JSLitmus/
* Jack is a toolkit for mocking JavaScript objects and functions. http://boss.bekk.no/display/BOSS/Jack
* MockMe for JavaScript http://johanneslink.net/projects/mockme.html
* qMock is a standalone, lightweight mocking framework that facilitates integration testing for JavaScript programs. http://code.google.com/p/qmock/
* TDD JS with JsMock http://www.pathf.com/blogs/2006/11/tdd_and_javascr/
* Test Driven Javascript http://www.testdrivenjavascript.com/Practice/5.aspx
* jsUnity is a lightweight JavaScript testing framework that is context-agnostic http://jsunity.com/
* JsUnitTest is based off unittest.js from prototypejs, except this library has no dependencies http://jsunittest.com
* Inspec BDD style test framework http://github.com/aq1018/inspec</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing/1.0</title>
    <id>82</id>
    <revision>
      <id>2833</id>
      <timestamp>2010-06-22T21:25:55Z</timestamp>
      <contributor>
        <username>Hannesw</username>
        <id>10</id>
      </contributor>
      <minor/>
      <comment>Add RingoJS to implementations</comment>
      <text xml:space="preserve">{{Spec
|status=approved by discussion participants
|specification=yes
|participants=Tom Robinson, Ash Berlin, George Moschovitis, Chris Zumbrunn, Hannes Wallnöfer, Kris Kowal, Kevin Dangoor, Ates Goral, and Davey Waterson
|discussion=http://groups.google.com/group/commonjs/browse_thread/thread/2952de9982fc2b55
|implementations=Flusspferd, Narwhal=0.2, SproutCore, node.js, v8cgi, Wakanda, RingoJS
}}

= Specification =

1.0

== Assert ==

1. The &lt;tt&gt;assert&lt;/tt&gt; module provides functions that throw &lt;tt&gt;AssertionError&lt;/tt&gt;'s when particular conditions are not met.  The &lt;tt&gt;assert&lt;/tt&gt; module must conform to the following interface.

&lt;source&gt;var assert = require(&quot;assert&quot;);&lt;/source&gt;

2. The AssertionError is defined in &lt;tt&gt;assert&lt;/tt&gt;.

&lt;source&gt;
new assert.AssertionError({message: message, actual: actual, expected: expected})
assert.AssertionError instanceof Error
&lt;/source&gt;

At present only the three keys mentioned above are used and understood by the spec. Implementations or sub modules can pass other keys to the AssertionError's constructor - they will  be ignored.

3. All of the following functions must throw an &lt;tt&gt;AssertionError&lt;/tt&gt; when a corresponding condition is not met, with a message that may be undefined if not provided.  All assertion methods provide both the actual and expected values to the assertion error for display purposes.

4. Pure assertion tests whether a value is truthy, as determined by &lt;code&gt;!!guard&lt;/code&gt;.

&lt;source&gt;assert.ok(guard, message_opt);&lt;/source&gt;

This statement is equivalent to &lt;code&gt;assert.equal(guard, true, message_opt);&lt;/code&gt;.  To test strictly for the value &lt;code&gt;true&lt;/code&gt;, use &lt;code&gt;assert.strictEqual(guard, true, message_opt);&lt;/code&gt;.

5. The equality assertion tests shallow, coercive equality with &lt;code&gt;==&lt;/code&gt;.

&lt;source&gt;assert.equal(actual, expected, message_opt);&lt;/source&gt;

6. The non-equality assertion tests for whether two objects are not equal with &lt;code&gt;!=&lt;/code&gt;

&lt;source&gt;assert.notEqual(actual, expected, message_opt);&lt;/source&gt;

7. The equivalence assertion tests a deep equality relation.  

* 7.1. All identical values are equivalent, as determined by &lt;tt&gt;===&lt;/tt&gt;.
* 7.2. If the expected value is a Date object, the actual value is equivalent if it is also a Date object that refers to the same time.
* 7.3. Other pairs that do not both pass &lt;tt&gt;typeof value == &quot;object&quot;&lt;/tt&gt;, equivalence is determined by &lt;tt&gt;==&lt;/tt&gt;.
* 7.4. For all other &lt;tt&gt;Object&lt;/tt&gt; pairs, including &lt;tt&gt;Array&lt;/tt&gt; objects, equivalence is determined by having the same number of owned properties (as verified with &lt;tt&gt;Object.prototype.hasOwnProperty.call&lt;/tt&gt;), the same set of keys (although not necessarily the same order), equivalent values for every corresponding key, and an identical &quot;prototype&quot; property.  Note: this accounts for both named and indexed properties on Arrays.

&lt;source&gt;assert.deepEqual(actual, expected, message_opt);&lt;/source&gt;

8. The non-equivalence assertion tests for any deep inequality.

&lt;source&gt;assert.notDeepEqual(actual, expected, message_opt);&lt;/source&gt;

9. The strict equality assertion tests strict equality, as determined by &lt;tt&gt;===&lt;/tt&gt;.

&lt;source&gt;assert.strictEqual(actual, expected, message_opt);&lt;/source&gt;

10. The strict non-equality assertion tests for strict inequality, as determined by &lt;tt&gt;!==&lt;/tt&gt;.

&lt;source&gt;assert.notStrictEqual(actual, expected, message_opt);&lt;/source&gt;

11. Expected to throw an error:

&lt;source&gt;assert.throws(block, Error_opt, message_opt);&lt;/source&gt;

== Test ==

12. The &quot;test&quot; module provides a &quot;run&quot; method that runs unit tests and catalogs their results.  The &quot;run&quot; method must return the total number of failures, suitable for use as a process exit status code.  The idiom for a self-running test module program would be:

&lt;source&gt;
if (module === require.main) 
    require(&quot;test&quot;).run(exports); 
&lt;/source&gt;

13. &lt;tt&gt;run&lt;/tt&gt; must accept any &lt;tt&gt;Object&lt;/tt&gt;, usually a unit test module's exports.  &quot;run&quot; will scan the object for all functions and object properties that have names that begin with but are not equal to &quot;test&quot;, and other properties for specific flags.  Sub-objects with names that start with but are not equal to &quot;test&quot; will be run as sub-tests.  

A future version of this specification may add a mechanism for changing the mode of test functions from fail-fast (where failed assertions throw) to fail-slow (where failed assertions just log/print) via a &lt;tt&gt;logger&lt;/tt&gt; argument or similar, but in the interim, this is implementation specific.

&lt;source&gt;
// ./sub-test
exports.testPatience = function () {
    require('os').sleep(1000);
};
&lt;/source&gt;

&lt;source&gt;
// ./test
exports.testSubTest = require(&quot;./sub-test&quot;);
&lt;/source&gt;

14. Test names may be any String that begins with &quot;test&quot;, not necessarily respecting a case convention.

&lt;source&gt;
[
    [{&quot;a&quot;: 10}, {&quot;a&quot;: 10}],
    [[1, 2, 3], [1, 2, 3]]
].forEach(function (pair) {
     exports['test ' + pair[0].toSource()] = function () {
         assert.equal.apply(assert, pair);
     };
});

exports[&quot;test behaviour X&quot;] = function() {
    behaviour.X()
}
&lt;/source&gt;

= Notes =

== Custom Assert Modules ==

The assertions defined above will not be to everyone's taste style wise (or infact behaviour wise.) Authors are free to define their own assertion methods in new modules as desired. To make it possible to combine assertions from different modules in one test suite, all assert methods must throw a &lt;tt&gt;AssertionError&lt;/tt&gt; (or something that is an &lt;tt&gt;instanceof AssertionError&lt;/tt&gt;).

Below is an example of how a custom assert module could be defined:

&lt;source&gt;
// file: my-check.js
exports.check = function(actual) {
    return {
        is: function(expect, message) {
            if (actual != expect)
                throw new AssertionError({actual: actual, expected: expected, message: message});
        },
    }
}
&lt;/source&gt;

&lt;source&gt;
// This would be used as follows:
var check = require(&quot;my-check&quot;).check;
exports.testSomething = function() {
    var sq = Math.pow(3, 2);
    check(sq).is(9, &quot;3 squared is 9&quot;);
}
&lt;/source&gt;

If future versions of this spec add a logger mechanism (with the intent of making it so that a failed assertion doesn't abort the above case) then the implementation above for &lt;tt&gt;check.is&lt;/tt&gt; will need to be updated.

== Implementations ==

# Narwhal, implemented by Zachary Carter. http://github.com/280north/narwhal/blob/master/lib/assert.js and http://github.com/280north/narwhal/blob/master/lib/test.js
# Flusspferd, based largely on the Narwhal version.
# SproutCore CoreTest - for the browser http://github.com/sproutit/core_test
# v8cgi (from r766)
# Wakanda

== Unit Tests ==

# http://github.com/commonjs/commonjs/tree/master/tests/unit-testing/1.0/

== Show of Hands ==

[[Unit_Testing/A/Voting]]

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/2952de9982fc2b55 Unit Testing 1.0 Candidate]
* [http://groups.google.com/group/commonjs/browse_thread/thread/77abf61133d26c22 Recount on Unit Testing API (was: Vote: use QUnit API or Unit Testing/A)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/236024c7269bc9ec Vote: use QUnit API or Unit Testing/A]
* [http://groups.google.com/group/commonjs/browse_thread/thread/bf1e7ce55320f0b8 Revisiting &quot;include&quot; (was: QUnit and CommonJS)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/269253f5b713c5c5 QUnit and CommonJS]
* [http://groups.google.com/group/commonjs/browse_thread/thread/daee7099261d8d9a Unit Testing A Show of Hands III]
* [http://groups.google.com/group/commonjs/browse_thread/thread/77ca421f63017b3f Unit Testing Show of Hands II]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a0db8fb0a815a6fe Unit Testing, Testing for Missing &quot;var&quot;s.]
* [http://groups.google.com/group/commonjs/browse_thread/thread/07c69484abc8a560 Unit Testing Show of Hands]</text>
    </revision>
  </page>
  <page>
    <title>JSGI</title>
    <id>83</id>
    <revision>
      <id>1964</id>
      <timestamp>2010-01-12T01:35:07Z</timestamp>
      <contributor>
        <username>Pbannister</username>
        <id>65</id>
      </contributor>
      <text xml:space="preserve">'''STATUS: RATIFIED, FURTHER DISCUSSION'''

= Web server to application interface =

A well-defined interface for connecting web applications to web servers is a very powerful thing. This approach has enabled applications written with any Java framework, for example, to be deployed behind and Java server (&quot;servlet container&quot;). Additionally, the standard interface allows the creation of &quot;middleware&quot;, or software that sits in between the server and the application. There are many useful applications for middleware (automatic application of site wide styling, caching and sessions, security).

== Prior Art ==

* [http://ken.coar.org/cgi/ Common Gateway Interface (CGI)]. The base from most everything later derives. See [http://www.ietf.org/rfc/rfc3875 RFC 3875]. Still used widely, not performant.
* [http://www.fastcgi.com/ FastCGI]. A performant minimal and very stable variant of CGI. Allows use of existing CGI code with minimal change. Note [http://www.iis.net/expand/FastCGI FastCGI in IIS] support is very important to some folk.
* [http://en.wikipedia.org/wiki/Java_Servlet Java Servlets]. One of the first language-specific interfaces.
* [http://www.python.org/dev/peps/pep-0333/ Web Server Gateway Interface] (Python). Very successful interface, but experience has shown that it's not 100% ideal.
* [http://rack.rubyforge.org/ Ruby Rack]. An up and coming standard in Ruby that looks a lot like WSGI 2.0.
* The Jack project provides a WSGI/Rack-like standard interface to webservers in JavaScript: http://jackjs.org 
* Comparison of current WebServer APIs used by JS engines:
**[http://tr.im/http_ssjs_api HTTP incoming request JS APIs]

== Proposed API ==

* 0.2: Proposal for JSGI specification: http://jackjs.org/jsgi-spec.html [ratified]
* 0.3: &lt;strike&gt;[[/Level0/A|Level 0, Draft 1]]&lt;/strike&gt;
* 0.3: [[/Level0/A/Draft2|Level 0, Draft 2]]

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/43372363c819859b &quot;Obviously stupid JS WSGI gateway&quot;]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c548608ef3053303 JSGI Level 0 Proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a1b8d29fb2436bc7 outstanding jsgi spec issues]
* [http://groups.google.com/group/commonjs/browse_thread/thread/9c5d5712ef0d2e8d JSGI | Problem with response headers and middleware]
* [http://groups.google.com/group/commonjs/browse_thread/thread/4c964dfeac6240e4 ATTN Jack users: JSGI spec change, response array changed to object]
* [http://groups.google.com/group/commonjs/browse_thread/thread/b8365ffff2f4d634 JSGI Response change proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/7662580bb89fa991 another small jsgi request...]</text>
    </revision>
  </page>
  <page>
    <title>XMPP</title>
    <id>84</id>
    <revision>
      <id>2851</id>
      <timestamp>2010-07-14T03:47:56Z</timestamp>
      <contributor>
        <username>Astro</username>
        <id>125</id>
      </contributor>
      <comment>/* Prior Art */ xmppjs &amp; node-xmpp</comment>
      <text xml:space="preserve">= Jabber (XMPP) =

The Jabber protocol is a popular, open protocol for real-time messaging and presence notification.

== Prior Art ==

* Xmpp4Js is an XMPP client library written in pure Javascript http://xmpp4js.sourceforge.net/
* JSJaC - JavaScript Jabber/XMPP Client Library http://blog.jwchat.org/jsjac/
* Strophe - Javscript XMPP client library with excellent protocol support http://code.stanziq.com/strophe/
* xmppjs — Strophe for components on node.js: http://github.com/mwild1/xmppjs
* node-xmpp — Asynchronous XMPP client/component library for node.js: http://github.com/astro/node-xmpp/</text>
    </revision>
  </page>
  <page>
    <title>I18n</title>
    <id>85</id>
    <revision>
      <id>1298</id>
      <timestamp>2009-09-17T10:39:41Z</timestamp>
      <contributor>
        <username>Bryanwb</username>
        <id>12</id>
      </contributor>
      <text xml:space="preserve">{{DISPLAYTITLE:i18n}}
i18n is an important need for web applications. JavaScript already has unicode string support, but the ability to localize information is important as well.

Standardizing this might be difficult, but would likely be worthwhile because every high level web framework could use the same formats for string catalogs and the same API for currency display, etc.

[[i18n Proposal A]]

== Prior Art ==

* [http://www-01.ibm.com/software/globalization/icu/index.jsp ICU]
* [http://babel.edgewall.org/ Babel]
* Dojo has a variation of require called requireLocalization which loads a JSON bundle based on locale and offers a string substitution utility.  Dojo also [http://bugs.dojotoolkit.org/browser/util/trunk/buildscripts/cldr transforms] a subset of the XML from [http://unicode.org/cldr Unicode CLDR], the same repository which drives [http://www-01.ibm.com/software/globalization/icu/index.jsp ICU], into something [http://bugs.dojotoolkit.org/browser/dojo/trunk/cldr JSON-like].  Dojo then implements its own Javascript based utilities on top of that for culturally-sensitive parsing and formatting.</text>
    </revision>
  </page>
  <page>
    <title>Main Page</title>
    <id>88</id>
    <revision>
      <id>813</id>
      <timestamp>2009-09-09T22:50:36Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[CommonJS]]</comment>
      <text xml:space="preserve">#REDIRECT [[CommonJS]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS</title>
    <id>89</id>
    <revision>
      <id>616</id>
      <timestamp>2009-09-09T22:29:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[ServerJS]] to [[CommonJS]]:&amp;#32;Subpages needed to be enabled</comment>
      <text xml:space="preserve">#REDIRECT [[CommonJS]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API</title>
    <id>90</id>
    <revision>
      <id>1006</id>
      <timestamp>2009-09-10T03:16:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/ProposalK</title>
    <id>91</id>
    <revision>
      <id>1005</id>
      <timestamp>2009-09-10T03:16:47Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/binary</title>
    <id>92</id>
    <revision>
      <id>1011</id>
      <timestamp>2009-09-10T03:17:48Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/binary]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/binary/ProposalK</title>
    <id>93</id>
    <revision>
      <id>1004</id>
      <timestamp>2009-09-10T03:16:37Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/binary/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/console</title>
    <id>94</id>
    <revision>
      <id>1012</id>
      <timestamp>2009-09-10T03:17:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/console]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/dict/ProposalK</title>
    <id>95</id>
    <revision>
      <id>1003</id>
      <timestamp>2009-09-10T03:16:27Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/dict/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/file</title>
    <id>96</id>
    <revision>
      <id>1002</id>
      <timestamp>2009-09-10T03:16:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/file]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/file/Names</title>
    <id>97</id>
    <revision>
      <id>933</id>
      <timestamp>2009-09-10T03:06:15Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Names]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/file/ProposalK</title>
    <id>98</id>
    <revision>
      <id>1013</id>
      <timestamp>2009-09-10T03:18:07Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/file/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/io/ProposalK</title>
    <id>99</id>
    <revision>
      <id>1008</id>
      <timestamp>2009-09-10T03:17:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/io/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/iter/ProposalK</title>
    <id>100</id>
    <revision>
      <id>1009</id>
      <timestamp>2009-09-10T03:17:27Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/iter/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/list/ProposalK</title>
    <id>101</id>
    <revision>
      <id>1007</id>
      <timestamp>2009-09-10T03:17:07Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/list/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/posix/ProposalK</title>
    <id>102</id>
    <revision>
      <id>1014</id>
      <timestamp>2009-09-10T03:18:18Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/posix/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/set/ProposalK</title>
    <id>103</id>
    <revision>
      <id>1016</id>
      <timestamp>2009-09-10T03:18:37Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/set/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/system</title>
    <id>104</id>
    <revision>
      <id>1015</id>
      <timestamp>2009-09-10T03:18:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/system]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/API/url/ProposalK</title>
    <id>105</id>
    <revision>
      <id>1010</id>
      <timestamp>2009-09-10T03:17:37Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/url/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary</title>
    <id>106</id>
    <revision>
      <id>943</id>
      <timestamp>2009-09-10T03:08:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary/A</title>
    <id>107</id>
    <revision>
      <id>949</id>
      <timestamp>2009-09-10T03:09:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/A]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary/B</title>
    <id>108</id>
    <revision>
      <id>1161</id>
      <timestamp>2009-09-10T20:44:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/B]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary/C</title>
    <id>109</id>
    <revision>
      <id>1162</id>
      <timestamp>2009-09-10T20:44:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary/C/Essay</title>
    <id>110</id>
    <revision>
      <id>954</id>
      <timestamp>2009-09-10T03:09:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C/Essay]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary/C/Show of hands</title>
    <id>111</id>
    <revision>
      <id>960</id>
      <timestamp>2009-09-10T03:10:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C/Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Binary/C/Unpacking</title>
    <id>112</id>
    <revision>
      <id>950</id>
      <timestamp>2009-09-10T03:09:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C/Unpacking]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/C API</title>
    <id>113</id>
    <revision>
      <id>1158</id>
      <timestamp>2009-09-10T20:43:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[C API]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Coding Standards</title>
    <id>114</id>
    <revision>
      <id>937</id>
      <timestamp>2009-09-10T03:07:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Coding Standards]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Command Line</title>
    <id>115</id>
    <revision>
      <id>1154</id>
      <timestamp>2009-09-10T20:42:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Command Line]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Concurrency</title>
    <id>116</id>
    <revision>
      <id>1165</id>
      <timestamp>2009-09-10T20:44:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Concurrency]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Current Efforts</title>
    <id>117</id>
    <revision>
      <id>1172</id>
      <timestamp>2009-09-10T20:45:53Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[CommonJS]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/DateTime</title>
    <id>118</id>
    <revision>
      <id>1169</id>
      <timestamp>2009-09-10T20:45:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[DateTime]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Doctools</title>
    <id>119</id>
    <revision>
      <id>1152</id>
      <timestamp>2009-09-10T20:42:23Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Doctools]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Email</title>
    <id>120</id>
    <revision>
      <id>1174</id>
      <timestamp>2009-09-10T20:46:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Email]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Encodings</title>
    <id>121</id>
    <revision>
      <id>959</id>
      <timestamp>2009-09-10T03:10:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Encodings]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Encodings/OldClass</title>
    <id>122</id>
    <revision>
      <id>940</id>
      <timestamp>2009-09-10T03:07:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Encodings/OldClass]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Existing APIs</title>
    <id>123</id>
    <revision>
      <id>1167</id>
      <timestamp>2009-09-10T20:45:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Existing APIs]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/FAQ</title>
    <id>124</id>
    <revision>
      <id>939</id>
      <timestamp>2009-09-10T03:07:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[FAQ]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/File/A</title>
    <id>125</id>
    <revision>
      <id>1143</id>
      <timestamp>2009-09-10T20:40:51Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/A]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Filesystem API</title>
    <id>126</id>
    <revision>
      <id>962</id>
      <timestamp>2009-09-10T03:11:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Filesystem API/A</title>
    <id>127</id>
    <revision>
      <id>956</id>
      <timestamp>2009-09-10T03:10:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/A]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Filesystem API/Hierarchy</title>
    <id>128</id>
    <revision>
      <id>934</id>
      <timestamp>2009-09-10T03:06:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Hierarchy]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Filesystem API/Join</title>
    <id>129</id>
    <revision>
      <id>961</id>
      <timestamp>2009-09-10T03:10:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Join]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Filesystem API/Names</title>
    <id>130</id>
    <revision>
      <id>948</id>
      <timestamp>2009-09-10T03:08:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Names]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Filesystem API/Show of hands</title>
    <id>131</id>
    <revision>
      <id>951</id>
      <timestamp>2009-09-10T03:09:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Future Efforts</title>
    <id>132</id>
    <revision>
      <id>1159</id>
      <timestamp>2009-09-10T20:43:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Future Efforts]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/HTTP Client</title>
    <id>133</id>
    <revision>
      <id>1160</id>
      <timestamp>2009-09-10T20:43:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[HTTP Client]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/HTTP Client/A</title>
    <id>134</id>
    <revision>
      <id>1171</id>
      <timestamp>2009-09-10T20:45:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[HTTP Client/A]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/High Level Tools</title>
    <id>135</id>
    <revision>
      <id>1147</id>
      <timestamp>2009-09-10T20:41:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[High Level Tools]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/IO</title>
    <id>136</id>
    <revision>
      <id>935</id>
      <timestamp>2009-09-10T03:06:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[IO]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/IO/A</title>
    <id>137</id>
    <revision>
      <id>947</id>
      <timestamp>2009-09-10T03:08:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[IO/A]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Infrastructure</title>
    <id>139</id>
    <revision>
      <id>1137</id>
      <timestamp>2009-09-10T20:39:49Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Infrastructure]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Introduction</title>
    <id>140</id>
    <revision>
      <id>952</id>
      <timestamp>2009-09-10T03:09:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Introduction]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Logging</title>
    <id>141</id>
    <revision>
      <id>1177</id>
      <timestamp>2009-09-10T20:46:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Logging]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules</title>
    <id>142</id>
    <revision>
      <id>942</id>
      <timestamp>2009-09-10T03:07:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/CompiledModules</title>
    <id>143</id>
    <revision>
      <id>1149</id>
      <timestamp>2009-09-10T20:41:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/CompiledModules]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/Environment</title>
    <id>144</id>
    <revision>
      <id>1155</id>
      <timestamp>2009-09-10T20:42:53Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Environment]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/GlobalFileLoading</title>
    <id>145</id>
    <revision>
      <id>1148</id>
      <timestamp>2009-09-10T20:41:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/GlobalFileLoading]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/GlobalObjectLoading</title>
    <id>146</id>
    <revision>
      <id>1145</id>
      <timestamp>2009-09-10T20:41:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/GlobalObjectLoading]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/Loaders</title>
    <id>147</id>
    <revision>
      <id>1142</id>
      <timestamp>2009-09-10T20:40:41Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Loaders]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/Meta</title>
    <id>148</id>
    <revision>
      <id>1139</id>
      <timestamp>2009-09-10T20:40:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Meta]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/PythonicModules</title>
    <id>149</id>
    <revision>
      <id>1178</id>
      <timestamp>2009-09-10T20:46:53Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/PythonicModules]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/ScriptModules</title>
    <id>150</id>
    <revision>
      <id>1138</id>
      <timestamp>2009-09-10T20:40:01Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/ScriptModules]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/SecurableModules</title>
    <id>151</id>
    <revision>
      <id>1144</id>
      <timestamp>2009-09-10T20:41:01Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/SecurableModules]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Modules/Secure</title>
    <id>152</id>
    <revision>
      <id>1166</id>
      <timestamp>2009-09-10T20:44:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Secure]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Packaging</title>
    <id>153</id>
    <revision>
      <id>1156</id>
      <timestamp>2009-09-10T20:43:03Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Packaging]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Pending Business</title>
    <id>154</id>
    <revision>
      <id>945</id>
      <timestamp>2009-09-10T03:08:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Status]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Process</title>
    <id>155</id>
    <revision>
      <id>944</id>
      <timestamp>2009-09-10T03:08:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Process]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Promise Manager</title>
    <id>156</id>
    <revision>
      <id>1151</id>
      <timestamp>2009-09-10T20:42:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Promise Manager]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Promises</title>
    <id>157</id>
    <revision>
      <id>1170</id>
      <timestamp>2009-09-10T20:45:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Promises]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/ProposalProcess</title>
    <id>158</id>
    <revision>
      <id>1141</id>
      <timestamp>2009-09-10T20:40:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[ProposalProcess]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/RDBMS</title>
    <id>159</id>
    <revision>
      <id>1175</id>
      <timestamp>2009-09-10T20:46:23Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[RDBMS]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Random Links</title>
    <id>160</id>
    <revision>
      <id>1153</id>
      <timestamp>2009-09-10T20:42:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Random Links]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Runtime Services</title>
    <id>161</id>
    <revision>
      <id>1173</id>
      <timestamp>2009-09-10T20:46:03Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Runtime Services]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Sockets</title>
    <id>162</id>
    <revision>
      <id>1163</id>
      <timestamp>2009-09-10T20:44:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Sockets]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Status</title>
    <id>163</id>
    <revision>
      <id>953</id>
      <timestamp>2009-09-10T03:09:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Status]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/System</title>
    <id>164</id>
    <revision>
      <id>957</id>
      <timestamp>2009-09-10T03:10:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[System]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/System/AmendmentProposals</title>
    <id>165</id>
    <revision>
      <id>1164</id>
      <timestamp>2009-09-10T20:44:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[System]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/System/ArchivedShowOfHands</title>
    <id>166</id>
    <revision>
      <id>1176</id>
      <timestamp>2009-09-10T20:46:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[System/ArchivedShowOfHands]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Target Platforms</title>
    <id>167</id>
    <revision>
      <id>936</id>
      <timestamp>2009-09-10T03:06:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Target Platforms]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Unit Testing</title>
    <id>168</id>
    <revision>
      <id>1150</id>
      <timestamp>2009-09-10T20:42:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Unit Testing]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/Unit Testing/A</title>
    <id>169</id>
    <revision>
      <id>1140</id>
      <timestamp>2009-09-10T20:40:21Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Unit Testing/A]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/WSGI</title>
    <id>170</id>
    <revision>
      <id>1250</id>
      <timestamp>2009-09-12T04:54:50Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[JSGI]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/XMPP</title>
    <id>171</id>
    <revision>
      <id>1157</id>
      <timestamp>2009-09-10T20:43:16Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[XMPP]]</text>
    </revision>
  </page>
  <page>
    <title>ServerJS/i18n</title>
    <id>172</id>
    <revision>
      <id>1168</id>
      <timestamp>2009-09-10T20:45:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[I18n]]</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Mainpage</title>
    <id>173</id>
    <revision>
      <id>814</id>
      <timestamp>2009-09-09T22:50:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'CommonJS'</comment>
      <text xml:space="preserve">CommonJS</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/FAQ</title>
    <id>174</id>
    <revision>
      <id>816</id>
      <timestamp>2009-09-09T22:51:46Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/FAQ]] to [[FAQ]]</comment>
      <text xml:space="preserve">#REDIRECT [[FAQ]]</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Sidebar</title>
    <id>175</id>
    <revision>
      <id>2477</id>
      <timestamp>2010-03-19T09:12:01Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">* SEARCH
* navigation
** mainpage|mainpage
** implementations|implementations
** FAQ|FAQ
** http://groups.google.com/group/commonjs|Mailing List
** irc://irc.freenode.net/commonjs|IRC
** http://log.serverjs.org/mochabot/join|IRC Via Mochabot
** http://log.server-side-javascript.org/mochabot/|IRC Logs
** recentchanges-url|recentchanges
** randompage-url|randompage
* TOOLBOX
* LANGUAGES</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Common.css</title>
    <id>176</id>
    <revision>
      <id>2442</id>
      <timestamp>2010-03-19T06:57:24Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">div.mw-geshi {
  padding: 1em;
  margin:1em 0;
  border: 1px dashed #2fab6f;
}

.allpagesredirect a {
  background: url('http://wiki.commonjs.org/images/Allpagesredirect.gif') center left no-repeat;
  padding-left: 13px;
  font-style: italic;
  font-size: 90%;
  color: grey;
}

.hands {
  background: #f3f3f3 url('http://wiki.commonjs.org/images/Hands.png') top left;
  padding: 1em;
  margin: 1em 0;
  border: 1px dashed #2eabbc;
}

.hint {
  background-color: #eee;
  padding: .3em;
  margin: .2em 0;
  border: 1px dotted #ccc;
}

#firstHeading .website_link {
  float: right;
  font-size: .5em;
  text-shadow: grey 2px 2px 1px;
}

table.wikitable {
    margin: 1em 1em 1em 0;
    background: #f9f9f9;
    border: 1px #aaa solid;
    border-collapse: collapse;
}
table.wikitable th, .wikitable td {
    border: 1px #aaa solid;
    padding: 0.2em;
}
table.wikitable th {
    background: #f2f2f2;
    text-align: center;
}
table.wikitable caption {
    font-weight: bold;
}</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Introduction</title>
    <id>177</id>
    <revision>
      <id>840</id>
      <timestamp>2009-09-10T02:14:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Introduction]] to [[Introduction]]</comment>
      <text xml:space="preserve">#REDIRECT [[Introduction]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Process</title>
    <id>178</id>
    <revision>
      <id>842</id>
      <timestamp>2009-09-10T02:14:55Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Process]] to [[Process]]</comment>
      <text xml:space="preserve">#REDIRECT [[Process]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Target Platforms</title>
    <id>179</id>
    <revision>
      <id>844</id>
      <timestamp>2009-09-10T02:14:58Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Target Platforms]] to [[Target Platforms]]</comment>
      <text xml:space="preserve">#REDIRECT [[Target Platforms]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Coding Standards</title>
    <id>180</id>
    <revision>
      <id>846</id>
      <timestamp>2009-09-10T02:15:01Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Coding Standards]] to [[Coding Standards]]</comment>
      <text xml:space="preserve">#REDIRECT [[Coding Standards]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Stream/Level1</title>
    <id>181</id>
    <revision>
      <id>1660</id>
      <timestamp>2009-10-08T10:58:25Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">This proposal defines the '''''Stream''''' class portion of [[IO/B]].

Please also see [[Binary/C]] and [[IO/B/Stream/Level0]].

== Preamble ==
This proposal defines a Stream class which is completely generic. New types of
streams can be made JavaScript side either by using the raw IO interface defined
by IO/B/Raw, or by subclassing stream and borrowing methods directly defined
on another stream. (The former permits streams built on other data sources which
only require a simple raw api, and the latter permits Stream subclasses which
simply munge data or arguments for certain methods or add new ones)

The Stream class is intended to be extremely abstract makes no assumption to the
capabilities of the underlying source of the data; Almost every operation works
the same whether the stream is binary or text. Capabilities are duck-typed onto
the Stream instead of defining separate types of streams. Access to a binary
layer below a text layer is not assumed as streams may be implemented for any
data source, and some of those data sources (Like a Stream that works on a StringBuffer)
will already be text and thus will not support dual-layer text wrapped streaming.

== Terminology ==
;contentConstructor: ''See [[Binary/C]].''
;sequence: ''See [[Binary/C]].''
;''#'' units: A length measured in the relevant unit (Byte or Characters) for the given sequence type of the stream.

== Class api ==

;new Stream(Object def);
:''(Only required by the base Stream class)''
:Creates a new generic stream instance using &lt;code&gt;def&lt;/code&gt; as a object defining what the stream can do and how to do it using the [[../Raw|Raw io api]].

;s.contentConstructor -&gt; Function;
:contentConstructor MUST return either &lt;code&gt;Blob&lt;/code&gt; or &lt;code&gt;String&lt;/code&gt; to indicate the underlying type of the stream content.

;s.canRead -&gt; boolean;
;s.canWrite -&gt; boolean;
:''(canRead MAY not be present if the stream is not readable)''
:''(canWrite MAY not be present if the stream is not writeable)''
:Boolean getters indicating the readable state of the stream.
:* canRead/canWrite should be false if read/write is not able to read/write data right away.
:* canRead/canWrite should be true if read/write will return with data right away.
:* canRead MUST NOT be false if EOF has been reached and read will return an EOF indication right away.
:* canRead/canWrite MUST assume things are not blocked and return true if the underlying io api does not provide a mechanism to get this information.

;s.seenEOF -&gt; boolean;
:Boolean property indicating if EOF has been reached.
:* .seenEOF must NOT be true before .read has returned an EOF indicator.

;s.position -&gt; uint;
:The current position within the stream.
:* If &lt;code&gt;position&lt;/code&gt; is so large that the number cannot be accurately represented (&lt;code&gt;p == p+1&lt;/code&gt; is true) then &lt;code&gt;position&lt;/code&gt; MUST return &lt;code&gt;Infinity&lt;/code&gt;.
:* &lt;code&gt;position&lt;/code&gt; is measured in the same units as the type of sequence specified by .contentConstructor;
:* &lt;code&gt;position&lt;/code&gt; MUST work even when Stream is constructed without a position: key.
:** This may be implemented by incrementing an internal position counter with lengths as .reads, .writes, .skips, etc... are performed, and modifying it along with a .seek where .tell should also include information that can reconstruct .the .position inside of an opaque cookie.

;s.read() -&gt; ''Sequence'';
;s.read(uint max) -&gt; ''Sequence'';
:''(MUST not be present if the stream is not readable)''
:Reads data from the stream.
:* .read MUST ONLY return sequences of the same type as .contentConstructor;
:* If ''max'' is 0, negative or not a integer a TypeError SHOULD be thrown.
:** 0 MAY be given a different error message as rather than being an invalid number the issue is you cannot read nothing.
:* ''max'' is measured in the same units as the type of sequence specified by .contentConstructor;
:* If ''max'' is omitted then .read buffers the entire stream then returns it's contents.
:* If ''max'' is specified then .read will do a partial read.
:** The resulting data MAY be of length ''max'' OR less than ''max'' but MUST have a length greater than 0.
:* If EOF has been reached then .read should return an empty sequence of length 0.
:* If max is &lt;code&gt;null&lt;/code&gt; it should be set to 1 (?narwhal)

;s.skip(uint max) -&gt; uint;
:&lt;del&gt;''(MUST not be present if the stream is not readable)''&lt;/del&gt;
:Skips over data as if reading from the stream.
:* If ''max'' is 0, negative or not a integer a TypeError SHOULD be thrown.
:** 0 MAY be given a different error message as rather than being an invalid number the issue is you cannot skip nothing.
:* ''max'' is measured in the same units as the type of sequence specified by .contentConstructor;
:* .skip does partial skips behaving similarly to .read;
:* .skip returns the number of units skipped in the skip. This number must be greater than 0.
:* If EOF has been reached then .skip should return 0.
:* .skip MUST be implemented on a readable stream even if not available in the underlying layer (it should use .read and discard the data if it needs to).

;s.write(''Sequence''|Buffer|''OpaqueRange'' data) -&gt; ???;
:''(MUST not be present if the stream is not writable)''
:Writes data to the stream.
:* .write must fully write the data, it may not do partial writes.
:* .write SHOULD attempt try to memcopy data.

;s.writePartial(''Sequence''|Buffer|''OpaqueRange'' data, [offset=0]) -&gt; uint;
:Writes data to the stream without blocking to wait for all the chunks to go through.
:* .write MUST write at least 1 unit of data or block till it is permitted to write.
:* .write returns the length of the data it wrote into the stream. The return value may be combined together and used as the offset to further calls.

;s.tell() -&gt; ''OpaqueCookie''|uint;
:Returns the location within the stream in a format that can be used later by .seek
:* If this returns a Number it MUST be an integer indicating the location within the stream measured in the same units as the type of sequence specified by .contentConstructor;
:** Therefore, if this returns a number it should be the same as &lt;code&gt;position&lt;/code&gt;.
:* An OpaqueCookie MUST contain enough information for .seek to later return to this location within the data and set .position back to the current state.
:* An OpaqueCookie returned by this function is only valid for this stream.
:* An OpaqueCookie returned by this function is invalid if a write has been made to a position in the stream before the location specified by this OpaqueCookie.

;s.seek(''OpaqueCookie''|uint to);
:''(MUST not be present if the stream is not seekable)''
:Seeks to another location within the file.
:* This method MUST accept any valid value outputted by .tell on the same stream.
:* If an OpaqueCookie is used as input and a write was made to a location before the location specified by that OpaqueCookie in between the time .tell was called and .seek is called behaviour is not defined and will likely break.

;s.rewind();
:''(MUST not be present if the stream is not seekable)''
:Seeks to the very beginning of the stream.

;s.flush();
:Flushes data which may be buffered in this or an underlying stream
:* If the underlying stream does not have a way to flush then this will be a no-op function.

;s.close();
:Closes the stream preventing any further reads or writes.
:* This must remove any .read, .write, or .seek present on the stream object.

== Requirements ==
Stream's constructor MUST be implemented such that &lt;code&gt;Stream.call(this, def);&lt;/code&gt;
within a function that has a .prototype that inherits from Stream.prototype will
modify the object specified by &lt;code&gt;this&lt;/code&gt; instead of constructing a new object.

This requirement is defined so that subclasses of Stream may be made using the
simple stub:
&lt;source&gt;
function StreamSubclass(o) {
	Stream.call(this, o);
}
StreamSubclass.prototype = new Stream();
&lt;/source&gt;

== Notes and comment bait ==
* Should we specify that the OpaqueCookie returned by .tell should respond to &gt; and &lt; calls (this can fairly easily be made to work using .valueOf)</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Stream/Level0</title>
    <id>182</id>
    <revision>
      <id>1659</id>
      <timestamp>2009-10-08T10:58:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">This proposal defines the raw io interface portion of [[IO/B]].

Please also see [[Binary/C]] and [[IO/B/Stream/Level1]].

== Preamble ==
IO/B's streams are inspired by the InputStream/OutputStreams and Reader/Writers
inside of Java's io system in which most classes only require you overload a
method or two to provide the functionality for the rest of the methods in the class.

IO/B/Stream defines the API for generic stream classes.
This spec defines a raw io JS API which may reside on Object, be it a literal or a subclass.
JavaScript side is may be simpler to just use an object Literal, but there is nothing
stoping JavaScript or the underlying host language (C/C++/Java depending on the interpreter)
from instead defining a new class type to handle raw IO for a specific type of data source.

Every method in this api is optional, except for the contentConstructor which is required.
Some operations are broken up into complementary methods. The Stream API MUST
work arround missing methods by using the complementary method as a fallback.
(For example, if readInto is implemented but not readChunk then to read just a
chunk the Stream API must use readInto on a buffer then extract the chunk from there).
If all methods from a set are missing then that signifies that the stream does not
support a feature (ie: if readChunk and readInto are both missing, then read is not supported)

The stream api makes no assumptions or requirements about the underlying data
source of the stream. It may or may not be read buffered, and may or may not
be write buffered, but SHOULD implement .flush to flush data if it is buffered.
It may or may not use resources that can be closed but should use .close to clean up after itself.

== The API ==

;s.contentConstructor -&gt; Function;
:contentConstructor MUST return either &lt;code&gt;Blob&lt;/code&gt; or &lt;code&gt;String&lt;/code&gt; to indicate the underlying type of the stream content.

;s.read(Buffer buf, uint offset, uint max) -&gt; uint;
:Read data from the stream into a buffer.
:* .read may only return 0 when EOF has been reached.
:* &lt;code&gt;offset&lt;/code&gt; denotes an offset within &lt;code&gt;buf&lt;/code&gt; to start inserting at.
:* &lt;code&gt;max&lt;/code&gt; is measured in the same units as the type of sequence specified by .contentConstructor;
:* .skip returns the number of units skipped in the skip. This number must be greater than 0.
:* This SHOULD attempt to memcopy from data right into the buffer.

;s.skip(uint max);
:Skip over a length of data in the stream as if it were read.
:* APIs using this MUST not call .skip with anything other than a &lt;code&gt;max&lt;/code&gt; integer greater than (NOT equal to) 0.
:* .skip may only return 0 when EOF has been reached.
:* &lt;code&gt;max&lt;/code&gt; is measured in the same units as the type of sequence specified by .contentConstructor;
:* .skip does partial skips behaving similarly to .read;
:* .skip returns the number of units skipped in the skip. This number must be greater than 0.

;s.write(''Sequence''|Buffer|''OpaqueRange'' data) -&gt; uint;
:Write data from a sequence or buffer into a stream. Returns the amount of data from the data that was written.
:* This SHOULD attempt to memcopy from data from the data source.

;s.flush();
:Flushes any write buffered data in this layer or any underlying data layer forcing it to be written.

;s.tell() -&gt; ''OpaqueCookie''|uint;
:Return the current location within the stream.
:* If this returns a number it MUST be an integer indicating the location within the stream measured in the same units as the type of sequence specified by .contentConstructor;
:* An OpaqueCookie MUST contain enough information for .seek to later return to this absolute location.
:** This means that for a text layer backed by a binary position your OpaqueCookie MUST contain at least both the binary index AND the text index.
:* An OpaqueCookie returned by this function is only valid for this stream.
:* An OpaqueCookie returned by this function is invalid if a write has been made to a position in the stream before the location specified by this OpaqueCookie.

;s.seek(''OpaqueCookie''|uint to) -&gt; uint;
:Seeks to another location within the file.
:* This method MUST accept any valid number or opaque cookie outputted by .tell on the same stream.
:* If an OpaqueCookie is used as input and a write was made to a location before the location specified by that OpaqueCookie in between the time .tell was called and .seek is called behaviour is not defined and will likely break.
:* .seek MUST return the new location in the stream measured int the same units as the type of sequence specified by .contentConstructor;
:* If .seek and .tell make use of ''OpaqueCookie''s rather than numbers .seek MUST as a special case accept the number 0 in order to rewind to the beginning of the stream.

;s.close();
:Closes the stream. If this stream object uses any resources .close MUST be implemented to close or destroy those resources.
:Implementations SHOULD try to call .close if the raw stream class is about to be destroyed.

== Rationales ==
* Data sources may not always be binary (such as a stream that uses a string, string buffer, or other string api) so this api is written to work abstractly over either binary or textual data.
* Data may not be stored in the same sequence type as it outputs (such as a text stream reading from a file which is binary), which do not have a 1 to 1 correspondence for this reason we use an ''OpaqueCookie'' sometimes so we can have an absolute location in both units at the same time.
** We do NOT specify this as ''OpaqueCookie'' on text mode because it's possible to have textual backings that are fine with working with character based indexes.

== ToDo ==
* Identifying when read/write/etc... will block.
* Do locks fit at this level?
* truncate</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/IO</title>
    <id>183</id>
    <revision>
      <id>851</id>
      <timestamp>2009-09-10T02:35:44Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/IO]] to [[IO]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/IO/A</title>
    <id>184</id>
    <revision>
      <id>853</id>
      <timestamp>2009-09-10T02:35:44Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/IO/A]] to [[IO/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/A]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/IO/B/Raw</title>
    <id>185</id>
    <revision>
      <id>855</id>
      <timestamp>2009-09-10T02:35:44Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/IO/B/Raw]] to [[IO/B/Raw]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Raw]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/IO/B/Stream</title>
    <id>186</id>
    <revision>
      <id>857</id>
      <timestamp>2009-09-10T02:35:44Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/IO/B/Stream]] to [[IO/B/Stream]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Stream]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B</title>
    <id>187</id>
    <revision>
      <id>1372</id>
      <timestamp>2009-09-20T02:13:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">''Unfinished, in drafting''

IO/B defines an alternate proposal to [[IO/A]].

Focuses in IO/B are:
* Abstract handling of binary and textual data
* Flexibility and ease in defining new Stream types without needing to implement the entire complex api.
* Streaming as a generic system which can apply to any sort of data source (file, socket, buffers, etc...)

IO/B is broken up into separate sections:
* [[/Buffer/]] - &lt;code&gt;require('io/buffer');&lt;/code&gt; Buffer, StringBuffer, and BlobBuffer split out from [[Binary/C]]
* [[/Filesystem/Level0/]] - Level 0 &lt;code&gt;require('io/filesystem/raw');&lt;/code&gt; - Low level native access to the filesystem used to implement higher layers of filesystem access.
* [[/Filesystem/Level1/]] - Level 1 &lt;code&gt;require('io/filesystem');&lt;/code&gt; - ...
* [[/Stream/Level0/]] - Level 0, api only (there is nothing to implement at this level) - Raw method base api used to give Stream access to data sources at the most basic level
* [[/Stream/Level1/]] - Level 1 &lt;code&gt;require('io/stream');&lt;/code&gt; - Implementable in pure JS
* [[/Socket/]] - Level 1 &lt;code&gt;require('io/socket');&lt;/code&gt; - ...</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Encodings</title>
    <id>189</id>
    <revision>
      <id>864</id>
      <timestamp>2009-09-10T02:47:05Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Encodings]] to [[Encodings]]</comment>
      <text xml:space="preserve">#REDIRECT [[Encodings]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Encodings/OldClass</title>
    <id>190</id>
    <revision>
      <id>866</id>
      <timestamp>2009-09-10T02:47:06Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Encodings/OldClass]] to [[Encodings/OldClass]]</comment>
      <text xml:space="preserve">#REDIRECT [[Encodings/OldClass]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary</title>
    <id>192</id>
    <revision>
      <id>870</id>
      <timestamp>2009-09-10T02:48:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Binary]] to [[Binary]] over redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Binary]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary/A</title>
    <id>193</id>
    <revision>
      <id>872</id>
      <timestamp>2009-09-10T02:48:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Binary/A]] to [[Binary/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/A]]</text>
    </revision>
  </page>
  <page>
    <title>Binary/C</title>
    <id>195</id>
    <revision>
      <id>1278</id>
      <timestamp>2009-09-15T01:53:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">:''See also: the [[/Show of hands/]] as well as the [[/Unpacking/]] and [[/Essay/]] portions which were removed.''
This proposal was written by Daniel Friesen as an alternative to the [[Binary/B]] proposal,
it is accompanied by [[IO/B/Buffer]].

This proposal extends the Blob type that a number of existing Server-side JavaScript implementations use, and a Buffer type reflecting the StringBuffer/StringBuilder within Java.

Instead of Binary/B's ByteArray, Binary/C defers to [[IO/B/Buffer]] to provide buffers.

One goal of this proposal is interoperability between Strings and Blobs. That is, like Binary/B, this proposal aims to permit a class of generic algorithms that can operate on both Blob and String through a generic intersection between their API's. However, this proposal avoids things that seem counter-intuitive, like putting .charAt on a Blob, a byte collection. Instead, this proposal augments String with a .valueAt so that method can be used generically on both Blob and String and defers to IO/B/Buffer to provide a Buffer system which works on either type.

This proposal and IO/B/Buffer is based off of API's drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).

== Terms and reading notes ==
To avoid confusion and ambiguity these are the basic definitions of terms used
within this document.
;List
:A type which groups a series of items in a specific order.
;Sequence
:A type of list which manages a list of fixed-unit pieces of data.
:These units of data are normally either bytes or characters. &quot;Sequence&quot; is basically a term which refers generically to both Strings, Blobs/ByteStrings, and mutable counterparts like Buffer and whatnot.
;Array
:A type of list which manages a list of items. These items are not related to one another in any way other than their inclusion in the list and do not need to be of the same type.
:A key importance is an Array is a loose collection of items, these items do not have any sort of fixed unit to them.
;memcopy
:Where used memcopy is used it refers to the technique of copying memory as directly as possible from one source to another. At the very least this refers to copying from A to B without creating an intermediate Blob.

Where &quot;as if by&quot; is used in the spec the result is meant, the algorithm should not be affected by changes to the class' prototype.

== Differences between a Sequence and an Array ==
While this may not be the case in lower level languages, JavaScript's API does
make a clear distinction between strings and arrays.

;Units
:A Sequence is built up of a list of single unit items. Whilst an Array is built up of unitless items, the array does nothing but point to objects, it contains nothing itself. The sequence &quot;abc&quot; is made up of 3 units { a, b, c } whilst [1,&quot;asdf&quot;,3,{}] is made up of 4 items { 1, &quot;asdf&quot;, 3, {} } with no relation to each other and no fixed units as we see two separate numbers in there, a 4 unit sequence inside of it, and an object which could have an indefinite hierarchy.
;Spillover
:Depending on whether the type is a Sequence or an Array type functions such as .indexOf may &quot;spill&quot; or &quot;overflow&quot; over multiple items. Sequences spill, while Arrays do not spill. There is a subtle difference in the api between the two.
:* sequence.indexOf(sequence, [offset]);
:* array.indexOf(item, [offset]);
:When using .indexOf on a sequence you give it another sequence. indexOf does not look for just a single item, but a sequence of items within that sequence. Contrasted to this, when using .indexOf on an array it ONLY looks for a single item and the search is unaffected by adjacent items.
:This is apparent from how &lt;code&gt;&quot;foobarbaz&quot;.index(&quot;bar&quot;);&lt;/code&gt; returns the index of &quot;bar&quot; despite the fact that 'b', 'a', and 'r' are 3 units within this 9 unit long sequence (in this 1 unit being 1 character). While contrasted to this &lt;code&gt;[1,2,3,4,5].indexOf([2,3,4]);&lt;/code&gt; does NOT return the location of the 2, 3, and 4 inside this array. The reason for this being that indexOf on an array is a single item operation, it does not spill lookup over into the following items.
;Pushing and Popping
:Another point which does not get emphasised because strings are immutable in JavaScript and thus don't need methods to mutate them as Arrays do, is the semantics of .push, .pop, etc...
:.pop() and .shift() remove ONE item from an array and return it.
:As well given one argument .push() and .unshift() add ONE item to an array.
:The key point here is [1,2,3].push([4,5,6]); does NOT turn the array into [1,2,3,4,5,6] it just adds the [4,5,6] as a sub array as so [123,[456]].
:You can give multiple arguments to these methods, but then you are no longer working with your lists in the same way.
:
:There is another name which does fit this kind of operation, &quot;Append&quot; (Side note, Wrench.js does add .append to Array). Using [1,2,3].append([4,5,6]); DOES push 4, 5, and 6 onto the array creating the array [1,2,3,4,5,6].

== The API ==
The two tiers of the api for this spec define two new classes. Blob (Fluspferd, Google, jslibs have all used this name, it's a fairly long-standing name and normally works similarly) and Buffer, and two subclasses of Buffer, StringBuffer and BlobBuffer.

{{hands|=It is up to an implementation whether they wish to make Blob and Buffer native global objects, or seclude them inside of a binary module. Whether they are made global or not if the implementation implements require() then &lt;code&gt;require('binary');&lt;/code&gt; must return an object containing Blob and Buffer as keys, even if the binary module is simply a module containing &lt;code&gt;exports.Blob = Blob; exports.Buffer = Buffer;&lt;/code&gt;.}}

=== Blob ===
Blob is the binary counterpart to String, it has a slightly different API but has many similarities. A Blob is an immutable representation of a sequence of 8bit bytes.

Most of the blob methods work on blobish data, rather than flat blobs. This means that the argument is treated as if it were passed through Blob(), thus .indexOf(255); is the same as if you had done .indexOf(Blob(255)), so you do not need to explicitly convert everything into a blob.

Note that unlike String, Blob is not defined as a primitive datatype by ECMA, this means that typeof will never return 'blob' and all blobs will be objects unlike strings which are normally primitives. Blob works with and without the new constructor and acts the same. It is recommended to use the `Blob()` form 

;[new] Blob();
:Construct an empty blob
;[new] Blob(number);
:Construct a single unit blob, converting the number a byte. If the item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.
;[new] Blob(arrayOfNumbers);
:Construct an blob the same length as the array, converting numbers 0..255 into bytes. If any item is outside that range, not a number, or not an integer (has a decimal point) a TypeError should be thrown.
;[new] Blob(blob);
:Passes the blob through.
;[new] Blob(string, toCharset);
:Construct a new blob with the binary contents of a string. The string will be encoded from the native UTF-16 charset into the charset specified by the &lt;code&gt;toCharset&lt;/code&gt; argument and represented in the new blob in 8bit bytes.

;Blob.fromByteCode(code);
;Blob.fromCode(code);
:Returns a new blob using a numeric byte code within the range 0..255.

;blob.contentConstructor;
:Returns Blob to indicate this has binary content.

;blob.length;
:Returns the length of the blob. This is immutable.

;blob.byteCodeAt(index);
;blob.codeAt(index); (@level1)
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.

;blob.concat(otherBlob, ...);
:Combines the content of multiple blobs together and returns a new blob.

;blob.slice(begin, end);
:Extracts a section of the blob and returns a new blob containing it as the contents. (This should behave the same as string.slice and array.slice)

;blob.indexOf(blob, offset=0);
;blob.lastIndexOf(blob, offset=0);
:Returns the index within the calling blob object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.

;blob.byteAt(index);
;blob.valueAt(index);
:Extracts a single byte from the blob and returns a new blob object containing only it.

;blob.split();
;blob.split(separator);
;blob.split(separator, limit);
:Splits the blob based on a sequence of bytes ({0 0 0 255 0 0} split by 255 would become [{0 0 0}, {0 0}]) and returns an array of blobs. This is the same as string.split except it does not support regular expressions. Like string.split this supports sequences of more than one unit (ie: You may split {0 0 255 0 0 255 3 0} by the blob {255 0} and get [{0 0}, {0 255 3 0}])

;blob.toBlob([fromCharset, toCharset]);
:If passed with no argument returns the same blob.
:If passed with two charset arguments transcodes the data from one charset to the other and returns the data as a new blob.
:Note that if a single argument is passed to this method it should throw a TypeError to prevent gotchas where someone runs .toBlob(charset) on a blob instead of a string where it is relevant.

;blob.toString();
:Returns a debug representation like &quot;[Blob length=2]&quot;, where 2 is the length of the blob. Alternative debug representations are valid too, as long as (A) this method will never fail, (B) the length is included, (C) It is not only the representation of an implicitly converted string.

;blob.toString(fromCharset);
:Converts the binary data in the blob from the charset specified by &lt;code&gt;fromCharset&lt;/code&gt; to the native UTF-16 charset and returns a new string with that content.

;blob.toArray();
:Returns an array containing the bytes as numbers as if by &lt;code&gt;[ blob.byteCodeAt(i) for ( i in blob ) ]&lt;/code&gt;.

;blob.toArray(fromCharset);
:Returns an array containing the decoded Unicode code points as if by &lt;code&gt;var str = blob.toString(fromCharset); [ str.charCodeAt(i) for ( i in str ) ]&lt;/code&gt;.

;blob.toSource();
:This method is optional, it should be included if the interpreter being used supports .toSource() on it's various objects and types.
:Returns a representation of the blob in the format &quot;(Blob([]))&quot; or &quot;(new Blob([]))&quot;. If the blob has content in it the string should contain integers 0..255 representing the blob such that if evaluated (calling the correct Blob function) would return a blob with the same content.

=== String ''extensions'' ===

;string.contentConstructor;
:Returns String to indicate this has text content.

;string.toBlob(toCharset);
:Converts a UTF-16 string into the specified charset and returns a blob containing that binary data.

;string.valueAt(index);
:An alias for string.charAt(index);
:The point of this prototype is so that (string or blob).valueAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charAt and blobs to maintain .byteAt without returning unintuitive results while still allowing a method of working abstractly without relying on things like (str or blob)[index] which may not be implemented in some engines.

;string.codeAt(index);
:An alias for string.charCodeAt(index);
:The point of this prototype is so that (string or blob).codeAt(index); may be used independently of whether the sequence is a string or a blob. This will allow strings to maintain .charCodeAt and blobs to maintain .byteCodeAt without returning unintuitive results.

;String.fromCode(code);
:And alias for String.fromCharCode(code);
:The point of this prototype is so that (String or Blob).fromCode(code); may be used on .contentConstructor independently of whether the sequence is a string or a blob. This will allow calls to .codeAt to be returned to blob or string format abstractly.

== Abstract API ==
One of the primary focuses was interoperability between Strings and Blobs so that abstract algorithms could be written which work on either strings or blobs.

The entire Buffer api in IO/B/Buffer designed for this purpose, and the following methods on String and Blob are usable in abstract programming:
* seq.length;
* seq.contentConstructor (can be used as seq.contentConstructor() to return an empty seq of the same type)
* seq.valueAt(idx); // Sequence at index
* seq.codeAt(idx); // Number at index
* seq.valueOf(); // Returns the same seq (on a buffer returns the equiv Blob or String)
* seq.indexOf(seq, [off]); and seq.lastIndexOf(seq, [off]); // finding the location of a subsequence
* seq.concat(...seq); // combining sequences together
* seq.slice(begin, end); // extracting a portion of a sequence
* seq.split(sep, [limit]); // split up a sequence using another sequence as a separator
* ''Sequence''.fromCode(code); // return a single byte or single character based on a numeric code (Turning seq.codeAt(idx) back into a sequence)

== Textual casting ==
This spec does not define any implementation requirements on it's own on the Blob(string, charset); and blob.toString(charset); methods. However it expects that they will behave the same as the [[encodings]] spec defines in regards to transcoding, character sets, and errors.

== Notes ==
* A high priority in this proposal was String/Blob interoperability. While implicit string conversion was avoided it was important to make sure there was a api which could abstractly work with a sequence of data ignorant of whether the data was a string or a blob.
** .valueAt was added to string so that there was a common method for both blobs and strings without implementing a counterintuitive .charAt on blob. Note that as a result you can actually check .charAt vs .byteAt and string will only have .charAt, while blob will only have .byteAt.
* Some experimentation with .valueOf needs to be done. .valueOf has type hinting (the first argument is a string hint of what type may be converted to, operators like &gt; and &lt; make use of it as well as a few other cases). It would be nice to see if it's possible to use the native &lt; and &gt; operators to compare blobs on their binary order.
* For now things like .eq/equals, .lt, gt, etc... have been omited. Do note that Rhino actually implements .equals on String already. Also if we do add these things to blobs we should probably implement the same on strings.

== Relevant discussion ==
* http://groups.google.com/group/commonjs/browse_thread/thread/3b0a3a20a67987d8</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary/C/Essay</title>
    <id>196</id>
    <revision>
      <id>878</id>
      <timestamp>2009-09-10T02:48:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Binary/C/Essay]] to [[Binary/C/Essay]]</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C/Essay]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary/C/Show of hands</title>
    <id>197</id>
    <revision>
      <id>880</id>
      <timestamp>2009-09-10T02:48:09Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Binary/C/Show of hands]] to [[Binary/C/Show of hands]]</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C/Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary/C/Unpacking</title>
    <id>198</id>
    <revision>
      <id>882</id>
      <timestamp>2009-09-10T02:48:09Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Binary/C/Unpacking]] to [[Binary/C/Unpacking]]</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C/Unpacking]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/System</title>
    <id>201</id>
    <revision>
      <id>891</id>
      <timestamp>2009-09-10T02:55:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/System]] to [[System]]</comment>
      <text xml:space="preserve">#REDIRECT [[System]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Status</title>
    <id>202</id>
    <revision>
      <id>893</id>
      <timestamp>2009-09-10T02:55:15Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Status]] to [[Status]]</comment>
      <text xml:space="preserve">#REDIRECT [[Status]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Filesystem API</title>
    <id>205</id>
    <revision>
      <id>938</id>
      <timestamp>2009-09-10T03:07:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Filesystem API/A</title>
    <id>206</id>
    <revision>
      <id>941</id>
      <timestamp>2009-09-10T03:07:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/A]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Filesystem API/Hierarchy</title>
    <id>207</id>
    <revision>
      <id>964</id>
      <timestamp>2009-09-10T03:11:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Hierarchy]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Filesystem API/Join</title>
    <id>208</id>
    <revision>
      <id>946</id>
      <timestamp>2009-09-10T03:08:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Join]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Filesystem API/Names</title>
    <id>209</id>
    <revision>
      <id>955</id>
      <timestamp>2009-09-10T03:10:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Names]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Filesystem API/Show of hands</title>
    <id>210</id>
    <revision>
      <id>963</id>
      <timestamp>2009-09-10T03:11:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem API</title>
    <id>211</id>
    <revision>
      <id>912</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Filesystem API]] to [[Filesystem]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem API/A</title>
    <id>212</id>
    <revision>
      <id>914</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Filesystem API/A]] to [[Filesystem/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/A]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem API/Hierarchy</title>
    <id>213</id>
    <revision>
      <id>916</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Filesystem API/Hierarchy]] to [[Filesystem/Hierarchy]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Hierarchy]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem API/Join</title>
    <id>214</id>
    <revision>
      <id>918</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Filesystem API/Join]] to [[Filesystem/Join]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Join]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem API/Names</title>
    <id>215</id>
    <revision>
      <id>920</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Filesystem API/Names]] to [[Filesystem/Names]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Names]]</text>
    </revision>
  </page>
  <page>
    <title>Filesystem API/Show of hands</title>
    <id>216</id>
    <revision>
      <id>922</id>
      <timestamp>2009-09-10T02:59:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Filesystem API/Show of hands]] to [[Filesystem/Show of hands]]</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Show of hands]]</text>
    </revision>
  </page>
  <page>
    <title>Category:Show of hands</title>
    <id>217</id>
    <revision>
      <id>928</id>
      <timestamp>2009-09-10T03:02:23Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">All show of hands pages on the wiki.

[[Category:CommonJS]]</text>
    </revision>
  </page>
  <page>
    <title>Template:Old</title>
    <id>218</id>
    <revision>
      <id>966</id>
      <timestamp>2009-09-10T03:13:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '&lt;div style=&quot;padding: 5px; margin: 2px 10px 7px; background-color: #ccc; text-align: center;&quot;&gt; This page and pages under it have become old and lost favor to other pages. &lt;/div&gt;'</comment>
      <text xml:space="preserve">&lt;div style=&quot;padding: 5px; margin: 2px 10px 7px; background-color: #ccc; text-align: center;&quot;&gt;
This page and pages under it have become old and lost favor to other pages.
&lt;/div&gt;</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API</title>
    <id>219</id>
    <revision>
      <id>968</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API]] to [[OldAPI]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/ProposalK</title>
    <id>220</id>
    <revision>
      <id>970</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/ProposalK]] to [[OldAPI/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/binary</title>
    <id>221</id>
    <revision>
      <id>972</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/binary]] to [[OldAPI/binary]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/binary]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/binary/ProposalK</title>
    <id>222</id>
    <revision>
      <id>974</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/binary/ProposalK]] to [[OldAPI/binary/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/binary/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/console</title>
    <id>223</id>
    <revision>
      <id>976</id>
      <timestamp>2009-09-10T03:13:56Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/console]] to [[OldAPI/console]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/console]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/dict/ProposalK</title>
    <id>224</id>
    <revision>
      <id>978</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/dict/ProposalK]] to [[OldAPI/dict/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/dict/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/file</title>
    <id>225</id>
    <revision>
      <id>980</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/file]] to [[OldAPI/file]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/file]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/file/Names</title>
    <id>226</id>
    <revision>
      <id>1001</id>
      <timestamp>2009-09-10T03:16:06Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Filesystem/Names]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/file/ProposalK</title>
    <id>227</id>
    <revision>
      <id>984</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/file/ProposalK]] to [[OldAPI/file/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/file/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/io/ProposalK</title>
    <id>228</id>
    <revision>
      <id>986</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/io/ProposalK]] to [[OldAPI/io/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/io/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/iter/ProposalK</title>
    <id>229</id>
    <revision>
      <id>988</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/iter/ProposalK]] to [[OldAPI/iter/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/iter/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/list/ProposalK</title>
    <id>230</id>
    <revision>
      <id>990</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/list/ProposalK]] to [[OldAPI/list/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/list/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/posix/ProposalK</title>
    <id>231</id>
    <revision>
      <id>992</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/posix/ProposalK]] to [[OldAPI/posix/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/posix/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/set/ProposalK</title>
    <id>232</id>
    <revision>
      <id>994</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/set/ProposalK]] to [[OldAPI/set/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/set/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/system</title>
    <id>233</id>
    <revision>
      <id>996</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/system]] to [[OldAPI/system]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/system]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/API/url/ProposalK</title>
    <id>234</id>
    <revision>
      <id>998</id>
      <timestamp>2009-09-10T03:13:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/API/url/ProposalK]] to [[OldAPI/url/ProposalK]]</comment>
      <text xml:space="preserve">#REDIRECT [[OldAPI/url/ProposalK]]</text>
    </revision>
  </page>
  <page>
    <title>Dumps</title>
    <id>235</id>
    <revision>
      <id>1019</id>
      <timestamp>2009-09-10T03:47:10Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">Dumps of the wiki can be found at http://wiki.commonjs.org/dumps/.

* [http://wiki.commonjs.org/pages.xml pages.xml]: A dump of only current revisions of pages in the main namespace with redirects omitted. Use this for archives and browseable dumps of the wiki.
* [http://wiki.commonjs.org/current.xml current.xml]: A dump of the most recent revisions of all pages. Use this for bots.
* [http://wiki.commonjs.org/full.xml fullxml]: A dump of all revisions of all pages. Use this for full wiki backups.</text>
    </revision>
  </page>
  <page>
    <title>Template:Hands</title>
    <id>236</id>
    <revision>
      <id>1025</id>
      <timestamp>2009-09-10T16:37:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;div class=hands title=&quot;This block is waiting on a show of hands&quot;&gt;{{{1|{{{ }}}}}}&lt;/div&gt;</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary/C</title>
    <id>237</id>
    <revision>
      <id>1028</id>
      <timestamp>2009-09-10T17:01:29Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Binary/C]] to [[Binary/C]]:&amp;#32;History merge</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/C]]</text>
    </revision>
  </page>
  <page>
    <title>Binary/C/Level 1</title>
    <id>238</id>
    <revision>
      <id>1036</id>
      <timestamp>2009-09-10T17:56:37Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;source&gt;
// -*- coding: UTF-8 -*-
/**
 * CommonJS Binary/C (Level 1) supplementary library
 */

Blob.fromCode =
Blob.fromByteCode = function(code) {
  if(typeof code === &quot;number&quot;)
    throw new TypeError(&quot;Byte codes must be numbers&quot;);
  return new Blob(code);
};
Blob.prototype.contentConstructor = Blob;
Blob.prototype.codeAt = Blob.prototype.byteCodeAt;
Blob.prototype.byteAt =
Blob.prototype.valueAt = function(index) {
  return Blob(this.byteCodeAt(index));
};
Blob.prototype.split = function split(separator, limit) {
  if ( typeof limit !== &quot;number&quot; )
    limit = Infinity;
  // @todo
};
Blob.prototype.toBlob = function toBlob(fromCharset, toCharset) {
  if ( arguments.length === 0 )
    return this;
  if ( arguments.length === 1 )
    throw new TypeError(&quot;blob.toBlob passed with one argument. blob.toBlob was likely confused with string.toBlob&quot;);
  return require('encodings').convert(fromCharset, toCharset, this);
};
Blob.prototype.toString = function toString(fromCharset) {
  if ( arguments.length === 0 )
    return &quot;[Blob length=&quot; + this.length + &quot;]&quot;;
  return require('encodings').convertToString(fromCharset, this);
};
Blob.prototype.toArray = function toArray(fromCharset) {
  if ( fromCharset )
    var str = this.toString(fromCharset);
    var arr = new Array(this.length);
    for(var i = 0, l = str.length; i&lt;l; ++i)
      arr[i] = str.charCodeAt(i);
    return arr;
  } else {
    var arr = new Array(this.length);
    for(var i = 0, l = this.length; i&lt;l; ++i)
      arr[i] = this.byteCodeAt(i);
    return arr;
  }
};
Blob.prototype.toSource = function toSource() {
  return &quot;(new Blob([&quot;+this.toArray().join(', ')+&quot;]))&quot;;
};

StringBuffer.prototype.contentConstructor = String;
BlobBuffer.prototype.contentConstructor = Blob;
Buffer.prototype.valueAt = function(index) {
  return this.contentConstructor.fromCode(this.codeAt(index));
};
Buffer.prototype.append = function append(data) {
  this.insert(data, Infinity);
};
Buffer.prototype.insert = function insert(data, index) {
  this.splice(index, 0, data);
};
Buffer.prototype.clear = function clear(start, length) {
  this.fill(start, length, this.contentConstructor.fromCode(0));
};
Buffer.prototype.fill = function fill(start, length, seq) {
  // @todo
};
Buffer.prototype.replace = function remove(data, offset) {
  // @todo
};
Buffer.prototype.remove = function remove(offset, length) {
  return this.splice(offset, length);
};
Buffer.prototype.split = function split(separator, limit) {
  // @todo
};

String.fromCode = String.fromCharCode;
String.prototype.contentConstructor = String;
String.prototype.toBlob = function toBlob(toCharset) {
  return require('encodings').convertFromString(toCharset, this.valueOf());
};
String.prototype.valueAt = String.prototype.charAt;
String.prototype.codeAt = String.prototype.charCodeAt;
&lt;/source&gt;</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/C API</title>
    <id>239</id>
    <revision>
      <id>1042</id>
      <timestamp>2009-09-10T19:55:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/C API]] to [[C API]]</comment>
      <text xml:space="preserve">#REDIRECT [[C API]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Runtime Services</title>
    <id>240</id>
    <revision>
      <id>1044</id>
      <timestamp>2009-09-10T19:56:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Runtime Services]] to [[Runtime Services]]</comment>
      <text xml:space="preserve">#REDIRECT [[Runtime Services]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Sockets</title>
    <id>241</id>
    <revision>
      <id>1046</id>
      <timestamp>2009-09-10T19:56:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Sockets]] to [[Sockets]]</comment>
      <text xml:space="preserve">#REDIRECT [[Sockets]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Command Line</title>
    <id>242</id>
    <revision>
      <id>1048</id>
      <timestamp>2009-09-10T19:56:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Command Line]] to [[Command Line]]</comment>
      <text xml:space="preserve">#REDIRECT [[Command Line]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Logging</title>
    <id>243</id>
    <revision>
      <id>1050</id>
      <timestamp>2009-09-10T19:56:23Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Logging]] to [[Logging]]</comment>
      <text xml:space="preserve">#REDIRECT [[Logging]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/RDBMS</title>
    <id>244</id>
    <revision>
      <id>1052</id>
      <timestamp>2009-09-10T19:56:26Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/RDBMS]] to [[RDBMS]]</comment>
      <text xml:space="preserve">#REDIRECT [[RDBMS]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/WSGI</title>
    <id>245</id>
    <revision>
      <id>1249</id>
      <timestamp>2009-09-12T04:54:38Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Robot: Fixing double redirect</comment>
      <text xml:space="preserve">#REDIRECT [[JSGI]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Concurrency</title>
    <id>246</id>
    <revision>
      <id>1056</id>
      <timestamp>2009-09-10T19:56:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Concurrency]] to [[Concurrency]]</comment>
      <text xml:space="preserve">#REDIRECT [[Concurrency]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Promises</title>
    <id>247</id>
    <revision>
      <id>1058</id>
      <timestamp>2009-09-10T19:56:35Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Promises]] to [[Promises]]</comment>
      <text xml:space="preserve">#REDIRECT [[Promises]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Unit Testing</title>
    <id>248</id>
    <revision>
      <id>1060</id>
      <timestamp>2009-09-10T19:56:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Unit Testing]] to [[Unit Testing]]</comment>
      <text xml:space="preserve">#REDIRECT [[Unit Testing]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Unit Testing/A</title>
    <id>249</id>
    <revision>
      <id>1062</id>
      <timestamp>2009-09-10T19:56:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Unit Testing/A]] to [[Unit Testing/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[Unit Testing/A]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/HTTP Client</title>
    <id>250</id>
    <revision>
      <id>1064</id>
      <timestamp>2009-09-10T19:59:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/HTTP Client]] to [[HTTP Client]]</comment>
      <text xml:space="preserve">#REDIRECT [[HTTP Client]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/HTTP Client/A</title>
    <id>251</id>
    <revision>
      <id>1066</id>
      <timestamp>2009-09-10T19:59:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/HTTP Client/A]] to [[HTTP Client/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[HTTP Client/A]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Email</title>
    <id>252</id>
    <revision>
      <id>1068</id>
      <timestamp>2009-09-10T19:59:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Email]] to [[Email]]</comment>
      <text xml:space="preserve">#REDIRECT [[Email]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/XMPP</title>
    <id>253</id>
    <revision>
      <id>1070</id>
      <timestamp>2009-09-10T19:59:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/XMPP]] to [[XMPP]]</comment>
      <text xml:space="preserve">#REDIRECT [[XMPP]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/i18n</title>
    <id>254</id>
    <revision>
      <id>1072</id>
      <timestamp>2009-09-10T19:59:59Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/i18n]] to [[I18n]]</comment>
      <text xml:space="preserve">#REDIRECT [[I18n]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Promise Manager</title>
    <id>255</id>
    <revision>
      <id>1074</id>
      <timestamp>2009-09-10T20:00:03Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Promise Manager]] to [[Promise Manager]]</comment>
      <text xml:space="preserve">#REDIRECT [[Promise Manager]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Infrastructure</title>
    <id>256</id>
    <revision>
      <id>1076</id>
      <timestamp>2009-09-10T20:00:38Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Infrastructure]] to [[Infrastructure]]</comment>
      <text xml:space="preserve">#REDIRECT [[Infrastructure]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/High Level Tools</title>
    <id>257</id>
    <revision>
      <id>1078</id>
      <timestamp>2009-09-10T20:00:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/High Level Tools]] to [[High Level Tools]]</comment>
      <text xml:space="preserve">#REDIRECT [[High Level Tools]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Random Links</title>
    <id>258</id>
    <revision>
      <id>1080</id>
      <timestamp>2009-09-10T20:00:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Random Links]] to [[Random Links]]</comment>
      <text xml:space="preserve">#REDIRECT [[Random Links]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Existing APIs</title>
    <id>259</id>
    <revision>
      <id>1082</id>
      <timestamp>2009-09-10T20:00:55Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Existing APIs]] to [[Existing APIs]]</comment>
      <text xml:space="preserve">#REDIRECT [[Existing APIs]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Packaging</title>
    <id>260</id>
    <revision>
      <id>1084</id>
      <timestamp>2009-09-10T20:02:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Packaging]] to [[Packaging]]</comment>
      <text xml:space="preserve">#REDIRECT [[Packaging]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Doctools</title>
    <id>261</id>
    <revision>
      <id>1086</id>
      <timestamp>2009-09-10T20:02:34Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Doctools]] to [[Doctools]]</comment>
      <text xml:space="preserve">#REDIRECT [[Doctools]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Binary/B</title>
    <id>262</id>
    <revision>
      <id>1088</id>
      <timestamp>2009-09-10T20:04:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[Binary/B]]</comment>
      <text xml:space="preserve">#REDIRECT [[Binary/B]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Future Efforts</title>
    <id>263</id>
    <revision>
      <id>1090</id>
      <timestamp>2009-09-10T20:14:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Future Efforts]] to [[Future Efforts]]</comment>
      <text xml:space="preserve">#REDIRECT [[Future Efforts]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/DateTime</title>
    <id>264</id>
    <revision>
      <id>1094</id>
      <timestamp>2009-09-10T20:15:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/DateTime]] to [[DateTime]]</comment>
      <text xml:space="preserve">#REDIRECT [[DateTime]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Current Efforts</title>
    <id>265</id>
    <revision>
      <id>1098</id>
      <timestamp>2009-09-10T20:18:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Current Efforts]] to [[CommonJS]]:&amp;#32;Merge histories</comment>
      <text xml:space="preserve">#REDIRECT [[CommonJS]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules</title>
    <id>267</id>
    <revision>
      <id>1103</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules]] to [[Modules]] over redirect</comment>
      <text xml:space="preserve">#REDIRECT [[Modules]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/CompiledModules</title>
    <id>268</id>
    <revision>
      <id>1105</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/CompiledModules]] to [[Modules/CompiledModules]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/CompiledModules]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/Environment</title>
    <id>269</id>
    <revision>
      <id>1107</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/Environment]] to [[Modules/Environment]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Environment]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/GlobalFileLoading</title>
    <id>270</id>
    <revision>
      <id>1109</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/GlobalFileLoading]] to [[Modules/GlobalFileLoading]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/GlobalFileLoading]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/GlobalObjectLoading</title>
    <id>271</id>
    <revision>
      <id>1111</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/GlobalObjectLoading]] to [[Modules/GlobalObjectLoading]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/GlobalObjectLoading]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/Loaders</title>
    <id>272</id>
    <revision>
      <id>1113</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/Loaders]] to [[Modules/Loaders]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Loaders]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/Meta</title>
    <id>273</id>
    <revision>
      <id>1115</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/Meta]] to [[Modules/Meta]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Meta]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/PythonicModules</title>
    <id>274</id>
    <revision>
      <id>1117</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/PythonicModules]] to [[Modules/PythonicModules]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/PythonicModules]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/ScriptModules</title>
    <id>275</id>
    <revision>
      <id>1119</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/ScriptModules]] to [[Modules/ScriptModules]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/ScriptModules]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/SecurableModules</title>
    <id>276</id>
    <revision>
      <id>1121</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/SecurableModules]] to [[Modules/SecurableModules]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/SecurableModules]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/Modules/Secure</title>
    <id>277</id>
    <revision>
      <id>1123</id>
      <timestamp>2009-09-10T20:22:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/Modules/Secure]] to [[Modules/Secure]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Secure]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/ProposalProcess</title>
    <id>278</id>
    <revision>
      <id>1126</id>
      <timestamp>2009-09-10T20:25:03Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/ProposalProcess]] to [[ProposalProcess]]</comment>
      <text xml:space="preserve">#REDIRECT [[ProposalProcess]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/System/ArchivedShowOfHands</title>
    <id>279</id>
    <revision>
      <id>1128</id>
      <timestamp>2009-09-10T20:25:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/System/ArchivedShowOfHands]] to [[System/ArchivedShowOfHands]]</comment>
      <text xml:space="preserve">#REDIRECT [[System/ArchivedShowOfHands]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS/IO/B</title>
    <id>280</id>
    <revision>
      <id>1130</id>
      <timestamp>2009-09-10T20:25:30Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[CommonJS/IO/B]] to [[IO/B]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B]]</text>
    </revision>
  </page>
  <page>
    <title>File:Wiki.png</title>
    <id>281</id>
    <revision>
      <id>1180</id>
      <timestamp>2009-09-10T21:37:59Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Wiki.png]]&quot;: This will control the logo ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>Global</title>
    <id>282</id>
    <revision>
      <id>1251</id>
      <timestamp>2009-09-12T05:02:15Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>fleshed out a description of the problem and discussed solutions.</comment>
      <text xml:space="preserve">'''STATUS: DISCUSSION'''

JavaScript runs on many engines with many variations of the standard global primordial objects, like &lt;code&gt;Object&lt;/code&gt;, &lt;code&gt;Array&lt;/code&gt;, and &lt;code&gt;Date&lt;/code&gt;.  Interoperable modules must be able to run on a wide variety of engines.  To facilitate code sharing for components of a standard library and interoperable packaged libraries, each of these platforms need to make certain guarantees, a contract between library and engine.

== Proposals ==

There have been no formal proposals.  The discussed directions are informally:

# ECMAScript 5.  In so far as few engines support ES5 even partially, all present engine would fall short of compliance, with the intent of asymptotically approaching compliance by implementing ES5 or stubs that close the gap.
# All those parts of ECMAScript 5 that are possible to emulate on most engines.  For this proposal to be viable, someone will need to formalize the list of ES5 methods that would need to be emulated or stubbed in order to maintain compliance, and in what ways they may fail to function, like enumerability on object properties.  Also, certain facilities of the languages would have to be forbidden to interoperable modules, like for name loops on Arrays.

== Relevant Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/3cd154d53e312a65 Baseline ECMA version]
* [http://groups.google.com/group/commonjs/browse_thread/thread/28acc7ed8855f537 Date.format proposal]</text>
    </revision>
  </page>
  <page>
    <title>Packages/A</title>
    <id>284</id>
    <revision>
      <id>1903</id>
      <timestamp>2009-12-18T11:01:47Z</timestamp>
      <contributor>
        <username>Fgm</username>
        <id>53</id>
      </contributor>
      <minor/>
      <comment>/* The default package */ typo</comment>
      <text xml:space="preserve">'''STATUS: DISCUSSION'''

This is a stub.  Please fill me in.

Regarding layout, metadata, management, catalogs, sources, loader extensions.

== Design goals ==

* The [[Modules/SecurableModules]] specification must be supported.

* The pattern of installing modules on a &lt;tt&gt;PATH&lt;/tt&gt;-like structure, where there exists a knowledgeable administrator maintaining that &lt;tt&gt;PATH&lt;/tt&gt;, must be supported.

* Modules may be installed by existing tools, including those provided by operating system vendors, like &lt;code&gt;apt-get&lt;/code&gt;.

* Running code must be able to cause modules hitherto unknown to the system to be installed from the network and loaded on the fly.

* Any namespace of modules must avoid name collisions even in the cases of (a) completely independent authors who have no pre-arranged cooperation; or (b) malicious authors who wish to mount a &quot;substitution attack&quot; by providing faulty modules under a previously used name.

* Running code must be able to load, into the same CommonJS sandbox, more than one &quot;version&quot; of the &quot;same&quot; module, for reasonable definitions of &quot;version&quot; and &quot;same&quot;. In other words, if CommonJS bakes in a module versioning scheme, it must not require that only one version be running in the same JavaScript VM, or even in the same sandbox.

* It is preferable for CommonJS to not have a baked-in versioning scheme.

* It must be possible to support CommonJS clients who have limited bandwidth or storage space.

* The common case of module inclusion must be implementable synchronously; it must not require callbacks or promises.

== Definition of a package ==

A ''package'' is a container holding a directory structure of JavaScript ''module''s, where each ''module'' is a contiguous piece of program text satisfying the ECMAScript &lt;tt&gt;Program&lt;/tt&gt; production. In the following diagram, we show an example of a package and introduce our graphical notation.

[[File:Packages-0.png]]

The diagram shows one module, &lt;tt&gt;hashSet&lt;/tt&gt;, &lt;tt&gt;require&lt;/tt&gt;-ing another, &lt;tt&gt;hashMap&lt;/tt&gt;, from the same package. To &lt;tt&gt;require&lt;/tt&gt; a module from the same package, a module specifies its relative path within the package directory structure, as described under &lt;b&gt;Module Identifiers&lt;/b&gt; in [[Modules/SecurableModules]].

== Package files ==

A ''package file'' is the interoperable exchange format for packages. Each package file is an archive (ZIP or TGZ) of a directory structure. For example, the following shows a typical, small package file:

[[File:Packages-file.png]]

Note the &lt;tt&gt;manifest.json&lt;/tt&gt; file at the top (the contents of which we will discuss later), and the &lt;tt&gt;lib&lt;/tt&gt; directory which contains a singly rooted hierarchy of CommonJS modules, each of which is a JavaScript file with an extension &lt;tt&gt;*.js&lt;/tt&gt;.

== The default package ==

A CommonJS installation is endowed by the system administrator or other out-of-band container with a repository of modules organized in a ''logical'' single-rooted hierarchy, similarly to a &lt;tt&gt;PYTHONPATH&lt;/tt&gt;. These modules are part of the so-called ''default'' package. 

The default package is a local, logical construct and is not represented via an interoperable package file.

A CommonJS installation may choose to run various tasks (e.g., command line shells) as though they were each a module in the default package.

The modules in the default package are populated by initial installation of a CommonJS system; by operating system tools (such as &lt;tt&gt;apt-get&lt;/tt&gt;); and by direct administrator involvement (such as editing environment variables and adding directories in the right places). The implementation of the default package, and the ways in which it is maintained, is outside the scope of CommonJS. However, CommonJS may specify some particular modules, with standardized paths, as minimal CommonJS requirements that must exist in the default package.

In the following example, the default package is implemented as an ordered list of root directories containing JavaScript files. Imagine that &lt;tt&gt;/usr/local/commonjs/lib/&lt;/tt&gt; was installed using &lt;tt&gt;apt-get&lt;/tt&gt;, and &lt;tt&gt;/usr/local/commonjs/site-lib/&lt;/tt&gt; contains local edits made by the Unix user. Note how standard PATH-like behavior, where the local &lt;tt&gt;strHash.js&lt;/tt&gt; overrides the system-provided one, can be implemented easily.

[[File:Packages-1.png]]

== Package descriptors ==

A ''package descriptor'' is a set of instructions to the CommonJS runtime identifying a specific package file required by a client. It answers the questions:

* Where can the CommonJS runtime find the package file; and

* How can the runtime verify that it has fetched the correct one?

The following describes a package available as a zipfile in two different locations, and asks that its checksum be verified:

  {
    locate: [
      'http://allmysoftware.com/archive/bar/bar_2.4.8.zip',
      'http://barsoft.com/distros/bar_2.4.8.zip'
    ],
    verify: [
      {
        checksum: '24f7c8cbf635f4c03bad2dde7bf07531',
        algorithm: 'md5'
      }
    ]
  }

and the following provides a public key fingerprint, thus asking the CommonJS runtime to verify that the retrieved content has been signed by the corresponding private key:

  {
    locate: [
      'http://foosoft.com/public/latest/foo.zip'
    ],
    verify: [
      {
        signature: 'c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87'
        algorithm: 'rsa-sha1'
      }
    ]
  }

== Issuing &lt;tt&gt;require&lt;/tt&gt; from the default package ==

In the following example, a module in the default package &lt;tt&gt;require.async()&lt;/tt&gt;s a module specifying a module descriptor as the first argument. The local CommonJS runtime may or may not already have a copy of &lt;tt&gt;fontUtils.zip&lt;/tt&gt;, but the application writer does not have to worry about that. The call is nonblocking, via &lt;tt&gt;require.async()&lt;/tt&gt;, so the CommonJS runtime can issue a remote request for &lt;tt&gt;fontUtils.zip&lt;/tt&gt; and satisfy the request whenever the data is downloaded and the signature verified. Also, the runtime may report any failures as part of the result of &lt;tt&gt;require.async()&lt;/tt&gt;, and &lt;tt&gt;windowSystem.js&lt;/tt&gt; can arrange to react to these failures.

[[File:Packages-2.png]]

In general, any &lt;tt&gt;require&lt;/tt&gt;s from a module in the default package to a module in another package must specify the target package descriptor in this manner, and be asynchronous (thus using &lt;tt&gt;require.async&lt;/tt&gt;).

== Issuing &lt;tt&gt;require&lt;/tt&gt; targeting the default package ==

A module in any package can &lt;tt&gt;require&lt;/tt&gt; a module from the default package using the 2-argument form of &lt;tt&gt;require&lt;/tt&gt; where the first argument is the string &lt;tt&gt;'default'&lt;/tt&gt;. Access to the default package may or may not be permitted by the local CommonJS implementation but, if it is, this &lt;tt&gt;require&lt;/tt&gt; will succeed:

[[File:Packages-3.png]]

It's important to note that no &quot;search path&quot; exists between packages. Therefore, if the module in &lt;tt&gt;fontUtils.zip&lt;/tt&gt; failed to specify the package &lt;tt&gt;'default'&lt;/tt&gt;, it would get nothing:

[[File:Packages-3.5.png]]

== General &lt;tt&gt;require&lt;/tt&gt; between packages ==

In the most common case where a module to &lt;tt&gt;require&lt;/tt&gt;s a module from another package:

* The client package includes, in its &lt;tt&gt;manifest.json&lt;/tt&gt;, a descriptor for the target package, and assigns that descriptor to a local alias; and

* The client module mentions that alias in the 2-argument form of the &lt;tt&gt;require&lt;/tt&gt; function.

In the following example, package &lt;tt&gt;fontUtils.zip&lt;/tt&gt; assigns an alias &lt;tt&gt;'bez'&lt;/tt&gt; to some foreign package, and a module then uses it in &lt;tt&gt;require&lt;/tt&gt;.

[[File:Packages-5.png]]

Note that a synchronous &lt;tt&gt;require&lt;/tt&gt; is possible here, since the CommonJS runtime has a place to stand to introspect on &lt;tt&gt;fontUtils.zip&lt;/tt&gt;, prefetch its dependencies, and only run the &lt;tt&gt;courier.js&lt;/tt&gt; module of &lt;tt&gt;fontUtils.zip&lt;/tt&gt; when it has fetched the dependency &lt;tt&gt;curve.js&lt;/tt&gt;.

== Additional notes ==

[[File:Packages-misc.png]]

== Discussion ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/9f73afe65dc33df7 modules packaging]</text>
    </revision>
  </page>
  <page>
    <title>WSGI</title>
    <id>285</id>
    <revision>
      <id>1224</id>
      <timestamp>2009-09-12T04:09:34Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[WSGI]] to [[JSGI]]</comment>
      <text xml:space="preserve">#REDIRECT [[JSGI]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Raw</title>
    <id>286</id>
    <revision>
      <id>1265</id>
      <timestamp>2009-09-13T08:18:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[IO/B/Raw]] to [[IO/B/Stream/Raw]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Stream/Raw]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Filesystem/Level0</title>
    <id>287</id>
    <revision>
      <id>1665</id>
      <timestamp>2009-10-08T11:43:43Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>leaf -&gt; node</comment>
      <text xml:space="preserve">This proposal defines a &lt;code&gt;io/file/raw&lt;/code&gt; module which acts as a level 0
module for filesystem access. This module is not meant for use in normal programming
but instead acts as the lowest level layer between pure-JavaScript CommonJS code
and native filesystem code. It is intended only for the purpose of providing a
raw access layer that higher level modules may use to create file apis with.

Some comments about this proposal are on the [[Talk:IO/B/Filesystem/Level0]]

== Terminology ==
;Node
:A Node refers to an object which exists or does not exist on the filesystem, this is basically a path which irrelevant parts of (like the difference between / and \ on Windows) may be cleaned up but may not necessarily be a path string.
;''Opaque*''
:&quot;''Opaque*''&quot; is a piece of terminology (started in Filesystem/A) used to refer to a value of some sort which is implementation dependent. An Opaque value is one that only has a very small and specific set of defined behaviors, other than those there is no definition of how or what the implementation should use to create them. Something opaque can range in anything from an object literal, wrapped native data, a resource as a number, and so on... Inside a spec an Opaque value is NEVER introduced with something that requires dot notation (an Opaque is never expected to have the ability to look at a property on it), the only action used with an Opaque is to pass it as an argument to a function within the same implementation which will use it.

== The module ==
The &lt;code&gt;io/file/raw&lt;/code&gt; module accessed by &lt;code&gt;require('io/file/raw');&lt;/code&gt; exports these functions:

;.pathToNode(string path) -&gt; ''OpaqueNode''
:Returns an ''OpaqueNode'' that refers to a non-mutable path on the filesystem which may be used in methods within this module.
:{{hint|Even if your native layer accepts path strings, rather than just passing the path string through this is a good place to clean up that path string into a format that your implementation expects. Like how NSPR expects / even on Windows, while others expect \ on Windows. You can clean up both / and \ to the separator your underlying layer is expecting of you, then return the cleaned up string.}}

;.nodeToPath(''OpaqueNode'' node) -&gt; string
:Returns the string path for a ''OpaqueNode'' (this may have been cleaned up in terms of separator conversion).

;.nodeToName(''OpaqueNode'' node) -&gt; string
:Returns the file name for an ''OpaqueNode''.

;.stat(''OpaqueNode'' node) -&gt; ''OpaqueStat''
:Returns an ''OpaqueStat'' for the ''OpaqueNode'' specified by &lt;code&gt;node&lt;/code&gt;.
:Methods that use the ''OpaqueStat'' object are not guaranteed to not change between the time you call .stat and the time you call the method that uses the '''OpaqueStat'''.

;.canonical(''OpaqueNode'' node) -&gt; ''OpaqueNode''
:Returns a ''OpaqueNode'' refering to the canonical 

;.exists(''OpaqueStat'' stat) -&gt; boolean
:Tests for existence of the node on the filesystem.

;.size(''OpaqueStat'' stat) -&gt; uint|false
:Returns the size of the file specified by &lt;code&gt;stat&lt;/code&gt;, or returns false.

;.isFile(''OpaqueStat'' stat) -&gt; boolean|false
;.isDirectory(''OpaqueStat'' stat) -&gt; boolean|false
:Checks the &lt;code&gt;stat&lt;/code&gt; to see if the node it refers to is a file or is a directory.
:isFile and isDirectory may both return false if the node's path does not exist on the filesystem, or is a existing path on the filesystem that refers to something that is neither file nor directory.

;.lastModified(''OpaqueStat'' stat) -&gt; Date|false
:Returns the last modified time (mtime) of the file refered to by &lt;code&gt;stat&lt;/code&gt; as a date or returns false.

;.setLastModified(''OpaqueNode'' node, Date time) -&gt; boolean
:Sets the last modified time (mtime) of the file refered to by &lt;code&gt;node&lt;/code&gt;.

;.isReadable(''OpaqueStat'' stat) -&gt; boolean
;.isWriteable(''OpaqueStat'' stat) -&gt; boolean
:Returns booleans indicating if the &lt;code&gt;stat&lt;/code&gt; refers to a file that is readable or writable.

;.createDirectory(''OpaqueNode'' node, [boolean recursive=false]) -&gt; boolean
:Create a directory at the node specified by &lt;code&gt;node&lt;/code&gt;. If &lt;code&gt;resursive&lt;/code&gt; is specified this should attempt to create any parent directories instead of failing because they are missing.
:Returns a boolean to indicate if it created the directory or failed.

;.listPaths(''OpaqueNode'' node) -&gt; Array*string
;.listPathsByPath(''OpaqueNode'' node, Function pathCallback) -&gt; Array*string
;.listNodes(''OpaqueNode'' node) -&gt; Array*''OpaqueNode''
;.listNodesByPath(''OpaqueNode'' node, Function pathCallback) -&gt; Array*''OpaqueNode''
;.listNodesByNode(''OpaqueNode'' node, Function nodeCallback) -&gt; Array*''OpaqueNode''
;.listNodesByStat(''OpaqueNode'' node, Function statCallback) -&gt; Array*''OpaqueNode''
:List out the files within a directory.
:* These methods will throw if used on a file or nonexistent directory.
:* pathCallback(''OpaqueNode'' dir, string name);
:* nodeCallback(''OpaqueNode'' dir, ''OpaqueNode'' node);
:* statCallback(''OpaqueNode'' dir, ''OpaqueStat'' stat);

;.open(''OpaqueNode'' node, ''Object'' flags);
:Opens a file in a mode specified by &lt;code&gt;flags&lt;/code&gt; and returns a [[#Stream|stream]] in binary or text mode.
:* .open will throw if used on a directory.
:** &lt;code&gt;encoding&lt;/code&gt;: A character encoding to use when opening this in text mode. If this is falsey (undefined, false, or absent) the file shall be opened in binary mode instead of text mode
:** &lt;code&gt;read&lt;/code&gt;: True if opening for read
:** &lt;code&gt;write&lt;/code&gt;: True if opening for write
:** &lt;code&gt;append&lt;/code&gt;: True if all writes should be made to the end of the file
:** &lt;code&gt;truncate&lt;/code&gt;: True if the system should truncate the file after opening
:** &lt;code&gt;create&lt;/code&gt;: True if the system should create the file instead of failing if it doesn't exist (only applies when opening for writing)
:** &lt;code&gt;sync&lt;/code&gt;: True if writes should synchronously wait for the os to write the data to disk

;.remove(''OpaqueNode'' node) -&gt; boolean
:Deletes the file or empty directory specified by &lt;code&gt;node&lt;/code&gt;. Returns true or false to indicate if deletion worked or failed.

;.move(''OpaqueNode'' from, ''OpaqueNode'' to) -&gt; boolean
:Rename/moves the node specified by &lt;code&gt;from&lt;/code&gt; to the location specified by &lt;code&gt;to&lt;/code&gt;.

== Stream ==
Streams returned by .open are defined by [[IO/B/Stream/Level0]] with the following additional requirements:
* In binary mode .tell MUST return the location in bytes, not an OpaqueCookie.
* Programs using streams opened by .open in text mode MUST expect .tell to return an OpaqueCookie rather than a position in characters.
** Actual implementations may use whichever works best for their implementation

== Rationales ==
* Java and perhaps some other native abstractions use instances of a class or some other resource to non-mutably refer to a node on the filesystem, while others only use paths. For this reason we use an ''OpaqueNode'' which may take on an implementation dependent form. Java implementations could return a java.io.File object directly, implementations using a native layer that uses some sort of resource identifier could encapsulate that and return that as an ''OpaqueNode'', and implementations which use paths could simply return the path string.
* Similarly posix systems usually provide a stat object, while systems like Java have separate lastModified, and such calls. For that reason we use an ''OpaqueStat'' which could be some sort of stat object, or even just return the ''OpaqueNode'' that was passed to it.
* &lt;code&gt;ctime&lt;/code&gt; is inconsistent. Windows records creation time, but not change time of metadata. Unix records change time of metadata, but not creation time of the file. Then there are filesystems like ZFS which have separate fields that record both. Additionally Java does not provide a means to access ctime without significant work using JNI or something like JNA to access this data at C/C++ level. The majority of applications also have little need for ctime info and at most only need mtime (lastModified). For these reasons combined any sort of ctime (lastChanged/creationTime) is not specified by this platform independent filesystem access spec. That should be specified separately in something such as a posix module meant for posix specific filesystem access.
* While low level systems provide a directory open and read, Java only provides directory list* methods with Filename or File object filters. For this reason as a compromise we specify 4 separate directory listing methods, 3 of which can filter in different ways.
* All native level systems so far do not provide a copy mechanism. For this reason copy is omitted at this level and expected to be implemented at a higher level. (If there are any systems that provide a high performance copy this could be changed).
* .open at this level only specifies the raw things needed as a simple object. Any mode string parsing or more flexible object should be done in a higher level.
* Some implementations may optimize binary-&gt;text using native layering rather than js based layering so text/binary modes are included in .open at this level and a .raw binary layer is not exposed in a text layer.

== ToDo ==
* setCurrentWorkingDirectory. Should this use a path or a OpaqueNode?
* Permission modification
* Equivalence
* comparison?
* Hidden
* Roots and filesystem space
* isExecutable
* Temp files / delete on exit</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Buffer</title>
    <id>288</id>
    <revision>
      <id>1533</id>
      <timestamp>2009-09-30T09:04:14Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>/* Notes */</comment>
      <text xml:space="preserve">This proposal defines a &lt;code&gt;io/buffer&lt;/code&gt; module that defines 3 classes Buffer, StringBuffer, and BlobBuffer.

This proposal depends on [[Binary/C]] and uses a lot of terminology from there, please reference Binary/C for more information.

Binary/B originally defined a ByteArray, none of the prior art actually implemented a ByteArray as Binary/B proposes. Most implementations implemented a Blob type similar to Binary/B's ByteString, and any that implemented something called ByteArray actually implemented something more like a stream API based buffer rather than anything remotely resembling an Array.

This proposal and Binary/C is based off of API's drafted for MonkeyScript ([http://draft.monkeyscript.org/api/_std/Blob.html Blob] [http://draft.monkeyscript.org/api/_std/Buffer.html Buffer]).

== Prior art ==
Java's [http://java.sun.com/javase/6/docs/api/java/lang/StringBuffer.html java.lang.StringBuffer] is a very good reference for prior art. It is made for Strings rather than bytes, but nonetheless it's a api designed solely for the purpose of mutation of a string, not one designed for one purpose and hacked to suit another.

Java's StringBuffer works using by append[ing](), insert[ing](), strings to grow the buffer. .delete() removes portions of the buffer, .indexOf() and .lastIndexOf() can search, .replace() and .reverse() are available, .length() shows the length of the data itself, .capacity() shows the current amount of memory allocated, and .substring can grab a substring from the StringBuffer.

== The API ==
=== Buffer''s'' ===
Buffers are accompanied by three classes; Buffer, StringBuffer, and BlobBuffer. Buffer itself is the generic class, making calls to it will normally create either a StringBuffer or a BlobBuffer. Both StringBuffer and BlobBuffer should inherit from Buffer and return true in a &lt;code&gt;buf instanceof Buffer&lt;/code&gt;.

Buffers may implement smart resizing in the background (ie: padding arrays or whatnot to sizes to avoid reallocating on each insert) but information on this is not available to the JavaScript API.

Buffers will only take their own data type as arguments. If you try to insert a String into a BlobBuffer or a Blob into a StringBuffer a TypeError will be thrown.

;new Buffer();
:No-op... This simply creates an instance of Buffer. On it's own the Buffer class does nothing so this simply exists so that prototypes may be made that inherit from Buffer.
;new StringBuffer();
:Creates a new empty text buffer.
;new BlobBuffer();
:Creates a new empty binary buffer.
;new StringBuffer(len);
:Creates a new text buffer of &lt;code&gt;len&lt;/code&gt; size.
;new BlobBuffer(len);
:Creates a new binary buffer of &lt;code&gt;len&lt;/code&gt; size.
;new Buffer('''String''');
:Creates a new empty StringBuffer.
;new Buffer('''Blob''');
:Creates a new empty BlobBuffer.
;new Buffer('''String''', len);
:Creates a new StringBuffer of &lt;code&gt;len&lt;/code&gt; size.
;new Buffer('''Blob''', len);
:Creates a new BlobBuffer of &lt;code&gt;len&lt;/code&gt; size.
;new Buffer(string);
:Creates a new StringBuffer with the same size and contents as the string.
;new Buffer(blob);
:Creates a new BlobBuffer with the same size and contents as the blob.

;buf.length;
;buf.length = len;
:Get or set the length of the buffer (For binary buffers this is number of bytes, for text buffers this is number of characters).
:When length is set the buffer is dynamically resized. If shrunk it is truncated to size discarding items from the end. If grown the buffer is padded with 0 bytes for binary, and '\0' (null characters) for text.

;buf.contentConstructor;
:Returns Blob from a BlobBuffer to indicate it has binary content, and String from StringBuffer to indicate it has text content. Implementations should make an effort to make this readonly.

;blob.codeAt(index);
:Extracts a single byte from the blob and returns it as a unsigned integer (Number) such that the number will be in the range 0..255.

;buf.splice(offset, length, data, ...);
:Remove a section of the buffer and insert chunks of data starting from the place it was removed from. If data is another Buffer memcopy should be used.

;buf.slice();
;buf.slice(start);
;buf.slice(start, end);
:Extract a subsection of the buffer and return it as a new sequence. (Behaves the same as the string and blob counterparts)

;&lt;del&gt;buf.copy(data, offset, length, [dataOffset]);&lt;/del&gt;
:Uses memcopy to copy a section of data directly into buf. data may either be another buffer of the same type, or a sequence (String/Blob) of same type as indicated by contentConstructor.

;buf.indexOf(sequence, offset=0);
;buf.lastIndexOf(sequence, offset=0);
:Returns the index within the calling buffer object of the first or last (depending on which method is used) occurrence of the specified value, or -1 if not found.

;buf.valueOf();
:Return the non-mutable sequence for the buffer.
:* In a BlobBuffer this returns a Blob which matches the contents of the buffer.
:* In a StringBuffer this returns a String which matches the contents of the buffer.

;buf.valueAt(index);
:Returns a string or blob representing the unit at a specified index.

;buf.append(data);
:Append a chunk of data to the end of the buffer growing it by &lt;code&gt;data.length&lt;/code&gt;. If data is another Buffer memcopy should be used.

;buf.insert(data, index);
:Insert a chunk of data into a buffer growing it by &lt;code&gt;data.length&lt;/code&gt; and shifting the data to the right of the specified index towards the end of the buffer. If data is another Buffer memcopy should be used.

;buf.clear(start, length);
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with '\0' (null characters).

;buf.fill(start, length, seq);
:Zero out a section of the buffer. Binary buffers have bytes replaced with 0 bytes and text buffers have characters replaced with '\0' (null characters).

;buf.replace(data, index);
:Insert data into the buffer starting from an index overwriting any existing bytes after that index up to the end of the data. Expands the buffer if necessary (&lt;code&gt;index + data.length &gt; buf.length&lt;/code&gt;).

;buf.remove(offset, length);
:Remove a section of the buffer starting at &lt;code&gt;offset&lt;/code&gt; and continuing for &lt;code&gt;length&lt;/code&gt; units, shrinking it by &lt;code&gt;length&lt;/code&gt;.

;buf.split();
;buf.split(separator);
;buf.split(separator, limit);
:Splits the buffer based on a sequence and returns an array of strings or blobs. (When used on text buffers this may or may not chose to support regular expressions)

=== ''Ranges'' ===
IO/B/Buffer supports an additional pattern for memcopy of data from one mutable or non-mutable sequence to another mutable sequence.

This part of IO/B/Buffer extends Binary/B, native String, IO/B/Stream/Raw. Under this extension all Buffer and stream methods accepting a sequence type of data to be placed into the buffer/stream MUST accept an ''OpaqueRange'' and SHOULD memcopy that data. As well String, Blob, and Buffer MUST contain the additional method:

;.range(???, ???) -&gt; ''OpaqueRange'' 
:Returns an ''OpaqueRange'' which can be used to memcopy the specified range of data from the sequence.

==== ''OpaqueRange'' ====
An ''OpaqueRange'' MUST contain enough information to reconstruct a specific range of data from the sequence .range was called on. Normally this may consist of the original sequence, and two numbers that can be used to determine what portion of the sequence to memcopy. Or could perhaps consist of the chunk of data itself in memory.

An ''OpaqueRange'' is NOT required to remain safe after first use, and NOT required to provide valid data if not passed directly to a method for use. In short this means that the ONLY supported use of .range is a use such as &lt;code&gt;bufB.append(bufA.range(???, ???));&lt;/code&gt; where you pass the range directly to a method like .append that uses it. The result of attempting to reuse a pre-used range or storing an ''OpaqueRange'' for any period of time is not defined, not supported, and may typically result in anything from errors, corrupt or unexpected data, to a segfault of the application.

== Abstract API ==
Like [[Binary/C]], IO/B/Buffer is able to work abstractly on both strings and blobs. Every method on the Buffer classes is built abstractly. There are a number of useful code stubs:

Create a new buffer with the same type as another form of data (be it a string, blob, another buffer, stream, or anything following the same contentConstructor rule).
&lt;source&gt;var buf = new Buffer(data.contentConstructor);&lt;/source&gt;

Cast some data to the same type as the sequence type of a buffer (to string or to blob, or throw an error if bad data; good when writing Buffer prototypes):
&lt;source&gt;buf.contentConstructor(data);&lt;/source&gt;

Create a new empty sequence of the same type as the sequence type of a buffer (empty string or blob, like what you'd return to signal EOF).
&lt;source&gt;buf.contentConstructor();&lt;/source&gt;

Get a character or byte in sequence form of the same type as a buffer corresponding to a byte or character code. In this case, the most useful purpose is returning the 0 byte or null character for an operation like clearing data.
&lt;source&gt;buf.contentConstructor.fromCode(0);&lt;/source&gt;

These are key to string/blob abstract programming and must be supported by implementations.

== Notes ==
* Buffer was made independent of whether the data is binary or text. To avoid implicit string conversion TypeErrors are thrown when giving data of the incorrect type to a buffer. But you are still able to write code using buffer that works on either strings or blobs and doesn't care which mode it is in.
** Note how Buffer accepts &lt;code&gt;String&lt;/code&gt; or &lt;code&gt;Blob&lt;/code&gt; to determine it's data type. You could actually write code like &lt;code&gt;var buf = new Buffer(sequence.constructor);&lt;/code&gt; and create a buffer based on the type of a sequence without checking what it is.</text>
    </revision>
  </page>
  <page>
    <title>File:CommonJsModules.png</title>
    <id>289</id>
    <revision>
      <id>1285</id>
      <timestamp>2009-09-16T03:48:24Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>IO/B/Filesystem/Level1</title>
    <id>290</id>
    <revision>
      <id>1371</id>
      <timestamp>2009-09-20T02:12:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">== Stream ==
Streams returned by .open are defined by [[IO/B/Stream/Level1]] with the following additional requirements:
* In binary mode .tell MUST return the location in bytes, not an OpaqueCookie.
* Programs using streams opened by .open in text mode MUST expect .tell to return an OpaqueCookie rather than a position in characters.
** Actual implementations may use whichever works best for their implementation
** This requirement is made so that 

== Notes ==
* autoflush &quot;wf&quot; support for .open so that every .write will .flush right after</text>
    </revision>
  </page>
  <page>
    <title>I18n Proposal A</title>
    <id>291</id>
    <revision>
      <id>1342</id>
      <timestamp>2009-09-19T04:02:47Z</timestamp>
      <contributor>
        <username>Bryanwb</username>
        <id>12</id>
      </contributor>
      <comment>/* Test Cases */</comment>
      <text xml:space="preserve">This proposal focuses on i18n for strings javascript code and strings in HTML files. It may be better described as a module rather than a standard.

== Rationale ==

Basic internationalization is part of the standard library/platform. Good examples are [http://docs.python.org/3.1/library/gettext.html Python] and the [http://www.gnu.org/software/gettext/manual/gettext.html GNU platform]. Internationalization is frequently an afterthought for software developers so having a well-defined and simple API can ensure that applications can be internationalized without major refactoring.

== Philosophy ==

The i18n mechanism should work in a client/server application and completely offline without any server-side emulation. This is distinctly different than how i18n works in web frameworks such as [http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html ruby-on-rails] and django. Most web frameworks use server-side html templates that replace translatable strings before sending the page to the client. This scheme does not work for offline applications. It also relies on html markup that is either invalid or unrenderable prior to pre-processing. It also makes the application very dependent a on a specific server-side handler and particular web server configuration.

This document proposes an i18n mechanism without server-side dependencies and using valid html5 markup. It also proposes a mechanism that is as simple as possible and can be applied incrementally to an existing application.

== Applicability ==

This specification is applicable to:
* Marking strings in javascript code for translation
* Marking strings in html for translation

It is not applicable at this time to:
* Common Locale Data Repository (CLDR) as exemplified in [http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap07.html POSIX locale]
* internationalizing CSS attributes such as fonts and images

== Basic Mechanisms ==

=== Method for Marking Strings in javascript Code ===

1. The Standard GNU Gettext method _(&quot;A translatable string&quot;);

  Example:  document.write(_(&quot;Translate me!&quot;));

2. The same method within E4X

  Example: var navigationBar = &lt;nav&gt;&lt;button&gt;{_(&quot;Go Back&quot;)}&lt;/button&gt;&lt;button&gt;{_(&quot;Reset&quot;)}&lt;/button&gt;&lt;/nav&gt; ;  


=== Method for Marking strings for Translation in HTML ===

Use the [http://www.whatwg.org/specs/web-apps/current-work/#custom-data-attribute data-*] collection of author-defined attributes in html5

Example 1.

   &lt;nowiki&gt;&lt;p data-_=&quot;true&quot;&gt;To say hello in Spanish, say &lt;span data-_=&quot;false&quot;&gt;Hola&lt;/span&gt;&lt;/p&gt;&lt;/nowiki&gt;

Example 2.

   &lt;nowiki&gt;&lt;button data-_=&quot;true&quot; data-_context=&quot;research&quot;&gt;Compile Articles&lt;/button&gt;&lt;!-- Somewhere else in same application --&gt;&lt;button data-_=&quot;true&quot; data-_context=&quot;computers&quot;&gt;Compile Code&lt;/button&gt;&lt;/nowiki&gt;



'''Marking''' strings means that they will fetched from the translation .po files at run time and that collection script '''xgettext''' can be used to gather string for translation.

=== Storing and Retrieving Translations ===

The translations will be stored [http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files .po] files. PO (Portable Files) are well supported by online translation tools such as [http://translate.sourceforge.net/wiki/pootle/index Pootle].

xgettext is the standard tool for grabbing translatable strings from an application. CommonJS requires a js implementation of this tool.

== Implementation ==

Here are the methods, attributes, global variable, and helper scripts I would like to see. It is primarily using Gettext.js 

=== Methods ===

Pretty much entirely copied from [http://jsgettext.berlios.de/doc/html/Gettext.html#methods jsgettext]

* new Gettext (args)textdomain( domain )
* gettext( MSGID )
* dgettext( TEXTDOMAIN, MSGID )
* dcgettext( TEXTDOMAIN, MSGID, CATEGORY )
* ngettext( MSGID, MSGID_PLURAL, COUNT )
* dngettext( TEXTDOMAIN, MSGID, MSGID_PLURAL, COUNT )
* dcngettext( TEXTDOMAIN, MSGID, MSGID_PLURAL, COUNT, CATEGORY )
* pgettext( MSGCTXT, MSGID )
* dpgettext( TEXTDOMAIN, MSGCTXT, MSGID )
* dcpgettext( TEXTDOMAIN, MSGCTXT, MSGID, CATEGORY )
* npgettext( MSGCTXT, MSGID, MSGID_PLURAL, COUNT )
* dnpgettext( TEXTDOMAIN, MSGCTXT, MSGID, MSGID_PLURAL, COUNT )
* dcnpgettext( TEXTDOMAIN, MSGCTXT, MSGID, MSGID_PLURAL, COUNT, CATEGORY )
* strargs (string, argument_array)

strargs in particular will have to be modified to handle native numerals like १ २ ३ ४ ५ (1, 2, 3, 4, 5 in Nepali). Notably Arabic and Hindi use the standard numeric system (1-10) but different characters to represent the numbers

=== HTML5 Attributes ===
For specifying a String should be translated

* data-translate=&quot;true|false&quot;   text for element should be translated
* data-_=&quot;true|false&quot;    short form of the above
* data-_C=&quot;true|false&quot;   grab all text from this element and all its children
* data-_I=&quot;true|false&quot;   grab text AND all inline markup, then translators can decide whether &lt;nowiki&gt; &lt;i&gt; or &lt;strong&gt; &lt;/nowiki&gt; are semantically meaningful in their language. This grabs all innerHTML and leaves it to the translators to decide 
* data-_comments=&quot;help explain meaning of text to be translated&quot;   
   &lt;nowiki&gt;example:   &lt;button data-_=&quot;true&quot; data-_comments=&quot;File is used as verb&quot;&gt;File&lt;/button&gt;&lt;/nowiki&gt;
* data-_ctxt  -- Context -- to differentiate between different usage of the same word w/in the same document, particularly when those meanings do not have a synonym in a different language   
   &lt;nowiki&gt;example:  &lt;button data-_=&quot;true&quot; data-_context=&quot;research&quot;&gt;Compile&lt;/button&gt;   &lt;button data-_=&quot;true&quot; data-_context=&quot;computers&quot;&gt;Compile&lt;/button&gt;&lt;/nowiki&gt;

=== Helper Functions ===

  xgettext - w/ essentially the same options and function as [http://linux.die.net/man/1/xgettext gnu gettext], but w/ at least one new switch --report to   

  indicate what percent of the application has been translated into other locales

=== Environment Variables ===

ALL_LINGUAS = &quot;de en fr&quot;

this variable indicates what locales the application has translations for.

=== Relevant Files and directories ===

po/     for po files that contain translations
   POTFILES.in     files that xgettext should grab strings from
   POTFILES.ignore   files that xgettext should ignore
   application_name.pot
   locale_name.po     translation of the application for a given locale


== Test Cases ==

Sample text (Everything should be translated)

  Hello world 
        
Sample text with placeholder for dynamic data (The generated POT file should have the tags as well)

  Score : 0
        
Sample text with context (Everything should be translated, additionally the generated POT file should have two instances of &quot;Compile Articles&quot;, with different msgctxt)

  Compile Articles
        
  Compile Articles
        
Date and time (this should appear in local format, eg: শুক্র সেপ্টেম্বর 18 15:10:58 IST 2009)

Numbered list (The numerals should be in native digits)

# Hello world1
# Hello world2
# Hello world3
 
Right to left text - Direction and justification (left|right) should be preserved

        خطأ في مُغيّرات الألوان المحددة.

== Further Reading ==

* [http://cldr.unicode.org/ Common Locale Data Repository]
* [http://www.gnu.org/software/gettext/manual/gettext.html GNU Gettext Manual]
* [http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap07.html How POSIX handles locale]</text>
    </revision>
  </page>
  <page>
    <title>Talk:Modules/Meta</title>
    <id>292</id>
    <revision>
      <id>1334</id>
      <timestamp>2009-09-18T22:47:09Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">Dump of irc chat had about this subject.
&lt;poem&gt;
22:47 &lt;ashb&gt; http://wiki.commonjs.org/wiki/Modules/Meta
22:47 &lt;ashb&gt; a few discussion points added
22:48 &lt;kriskowal&gt; going on about isMain again, eh?
22:49 &lt;kriskowal&gt; it *is* more concise for the common use case
22:49 &lt;kriskowal&gt; but i believe i already mentioned that require(require.main) is handy too
22:49 &lt;ashb&gt; for?
22:49 &lt;kriskowal&gt; e.g., self executing jack config files.  i've done it.
22:49 &lt;ashb&gt; mmm lots of reasons i guess
22:49 &lt;ashb&gt; yeah
22:50 &lt;ashb&gt; exports.foo = ...; require('jackup'); and it just works
22:50 &lt;kriskowal&gt; actually, if (require.main == module.id) require(&quot;jackup&quot;).main([module.path])
22:51 &lt;kriskowal&gt; words to that effect anyway
22:51 &lt;ashb&gt; so i guess if module.id and require.id are both speced to be 'absolute/always load same module' thats okay
22:51 &lt;kriskowal&gt; is that not explicated in the spec?
22:51  * kriskowal checks
22:51 &lt;ashb&gt; implied, but not stated
22:51 &lt;kriskowal&gt; top-level
22:51 &lt;ashb&gt; 'The &quot;module&quot; object must have an &quot;id&quot; that is the top-level &quot;id&quot; of the module.'
22:52 &lt;ashb&gt; is all it says about module.id
22:53 &lt;ashb&gt; kriskowal: what does main() do with the path?
22:53 &lt;kriskowal&gt; top-level isn't the same thing as absolute, but has the effect you're talking about.  absolute id's are beyond spec, but it makes sense to make them absolute if they're outside the module id domain
22:53 &lt;kriskowal&gt; main takes system.args, or faux args
22:53 &lt;ashb&gt; kriskowal: yeah, i think the exact mechanism doesn't need to be specified, just hte intent that you get the right module
22:54 &lt;ashb&gt; k so for the jackup example isMain would work too
22:54 &lt;kriskowal&gt; right, so the question is whether you want two channels to the same data.
22:54 &lt;ashb&gt; yeah
22:54 &lt;kriskowal&gt; unless it's your expectation for isMain to be lazily evaluated on require.main == module.id
22:55 &lt;ashb&gt; but so far the only real example usage people have given me for require.main is what you've just shown
22:55 &lt;kriskowal&gt; or as a function call that closes on those values.
22:55 &lt;ashb&gt; if anyone can give me one real example i'll drop my quest for isMain :)
22:55 &lt;ashb&gt; kriskowal: i envisaged it as a ro prop rather than a fn
22:56 &lt;kriskowal&gt; suppose that you're in another module, and you want to see the main module's exports
22:56 &lt;ashb&gt; should probably make .main and .id perm, read-only properties
22:56 &lt;kriskowal&gt; in a system where the convention is for the main module to be a config file
22:56 &lt;ashb&gt; kriskowal: yeah that makes sense
22:57 &lt;kriskowal&gt; let's not take the &quot;if nobody's doing it for real yet no one will ever want to&quot; angle.  the purpose of a language or library is to permit programs to be written unforseen by the creators of the language or library.
22:57 &lt;ashb&gt; i do wonder slightly if |require.main| is the wrong name/place for it tho
22:57 &lt;ashb&gt; kriskowal: this is true. but we also don't want to go the other way of specing everything just because it might be useful to someone
22:57 &lt;kriskowal&gt; the reasoning is that it's a place that works with many variations on the loader.
22:58 &lt;ashb&gt; but consider isMain dropped
22:58 &lt;kriskowal&gt; the idea is that sometimes &quot;require&quot; is a global object, and &quot;module&quot; is always a per-module object.
22:58 &lt;kriskowal&gt; although, in some loaders &quot;require&quot; is per-module too
22:59 &lt;ashb&gt; yeah i've switched it to per module in flusspferd
22:59 &lt;ashb&gt; cos the way we had it before broke JITing
22:59 &lt;kriskowal&gt; ihab pointed out that we could have conflated require and module using the same mechanisms in gpsee and helma that were used to discover the calling module for these other properties, but i don't intend to rock the boat.  it's a little more readable anyway.
22:59 &lt;ashb&gt; kriskowal: so module.id should certainly be RO, and i guess require.main should be too?
23:00 &lt;kriskowal&gt; i certainly wouldn't expect things to work if it were assigned too
23:00 &lt;ashb&gt; what mechanism is that?
23:00 &lt;kriskowal&gt; i'm not intimate with the details, but i presume it was through dynamic scope traversal only possible from c
23:01 &lt;ashb&gt; okay. finaly comment on the proposal is i want to remove all mentions of 'sanbox'
23:01 &lt;ashb&gt; specifially i dont see why the spec mandates that those properties must not be present in a sandbox
23:02 &lt;kriskowal&gt; in a secure sandbox
23:02 &lt;kriskowal&gt; .paths discloses information about the structure of your file system and probably even your user name, increasing the attack surface of the system
23:03 &lt;ashb&gt; yes but there are many types of secure sandbox
23:03 &lt;kriskowal&gt; we should probably revisit the issue with security experts when we actually have a real sandbox to talk about.
23:03 &lt;kriskowal&gt; like, one :P
23:03 &lt;ashb&gt; thats kinda my thinking
23:04 &lt;ashb&gt; since 'a secure sandbox' might just mean loading no new code to one person
23:04 &lt;ashb&gt; where as it might mean 'no FS access at all and no info leak' to another
23:04 &lt;kriskowal&gt; that's where dependency injection comes in
23:05 &lt;kriskowal&gt; i haven't been able to do hermetic eval in narwhal yet, due to strangeness of rhino.  can't wait to have a real Object.freeze et al
23:05 &lt;ashb&gt; yeah, in the first module.path is allowed
23:05 &lt;ashb&gt; but: 'The &quot;path&quot; property must not exist in a sandbox.'
23:06 &lt;ashb&gt; tbh i basically see (ultra-)secure sandboxes as a documented subset of commonJS
23:06 &lt;kriskowal&gt; it's a little more strict than that
23:07 &lt;ashb&gt; oh?
23:07 &lt;kriskowal&gt; if we're talking about modules and standard libraries, in the interest of real interoperability, those modules must work in a secure sandbox
23:08 &lt;kriskowal&gt; so, while engine specific components can be written in the context of commonjs related stuff, those modules are not commonjs compliant, and really can't be shared in the absolute sense
23:08 &lt;kriskowal&gt; i think the general idea is that application developers can do whatever they need, but we're promising that the standard library will work in a wide variety of contexts.
23:09 &lt;ashb&gt; yeah. i just dont like the fact we are mandating that something must not be possible in X, when we haven't really defined X
23:09 &lt;kriskowal&gt; it's better to be safe than future incompatible
23:10 &lt;Wes_&gt; Mmmm much better
23:10  * Wes_ was seeing stars
23:10 &lt;kriskowal&gt; that happens a lot in LA
23:10 &lt;ashb&gt; kriskowal: hmmm i guess you're right
23:11 &lt;kriskowal&gt; so, i think that Modules/Meta is ratified.  i guess the status line never got updated.
23:11 &lt;kriskowal&gt; would you say that's okay?
23:11 &lt;ashb&gt; tho in this specific example (module.path) i can't see how forbidding an optional property could be incompatible
23:12 &lt;ashb&gt; kriskowal: whith one slight amendment as to the intent/behaviour of module.id/require.main
23:12 &lt;kriskowal&gt; perhaps explication of intent would be the right word.  i think the normative text is as strict as we can make it without defining &quot;absolute&quot;
23:12 &lt;ashb&gt; just some verbage such as 'require.main can be passed to require() and loading the main program module'
23:12 &lt;kriskowal&gt; perhaps you can add something to the introduction or add a footnote
23:13 &lt;kriskowal&gt; ah, that would work
23:13 &lt;ashb&gt; and similar for module.id
23:13 &lt;ashb&gt; and i guess that the forms must be normalize so that .main == .id is true for the main script
23:13 &lt;kriskowal&gt; require(require.main) must return the exports of the main module
23:13 &lt;kriskowal&gt; require(module.id) must be equivalent to exports
23:14 &lt;ashb&gt; even when called from outside the current module
23:14 &lt;kriskowal&gt; even when passed through another module
23:14 &lt;kriskowal&gt; aye
23:14 &lt;ashb&gt; with those changes, yes i'm happy with it
23:14  * Wes_ is caught up
23:14 &lt;kriskowal&gt; i'd say go for it.
23:14 &lt;Wes_&gt; Not super happy with require.main -- but there isn't a better solution that doesn't involve polluting namespace: lesser of two evils wins
23:15 &lt;kriszyp&gt; so kriskowal, I sent you my work that I did on adding async/comet support to jack/narwhal. Is there anyone else I should send it to for review?
23:15 &lt;Wes_&gt; I'm also not happy with sandboxy &quot;must not&quot; -- but agree with KK pragmatism on subject
23:15 &lt;ashb&gt; Wes_: the other thing i thought was something on system module
23:15 &lt;kriskowal&gt; kriszyp: got email
23:15 &lt;Wes_&gt; ashb: possibly, but it doesn't seem like loading a module to get that seems reasomable either
23:15 &lt;kriskowal&gt; as far as i know tlrobinson isn't ready to evaluate promises.
23:15 &lt;kriskowal&gt; of course, neither am i :P
23:16 &lt;ashb&gt; Wes_: yeah it doesn't
22:47 &lt;ashb&gt; http://wiki.commonjs.org/wiki/Modules/Meta
22:47 &lt;ashb&gt; a few discussion points added
22:48 &lt;kriskowal&gt; going on about isMain again, eh?
22:49 &lt;kriskowal&gt; it *is* more concise for the common use case
22:49 &lt;kriskowal&gt; but i believe i already mentioned that require(require.main) is handy too
22:49 &lt;ashb&gt; for?
22:49 &lt;kriskowal&gt; e.g., self executing jack config files.  i've done it.
22:49 &lt;ashb&gt; mmm lots of reasons i guess
22:49 &lt;ashb&gt; yeah
22:50 &lt;ashb&gt; exports.foo = ...; require('jackup'); and it just works
22:50 &lt;kriskowal&gt; actually, if (require.main == module.id) require(&quot;jackup&quot;).main([module.path])
22:51 &lt;kriskowal&gt; words to that effect anyway
22:51 &lt;ashb&gt; so i guess if module.id and require.id are both speced to be 'absolute/always load same module' thats okay
22:51 &lt;kriskowal&gt; is that not explicated in the spec?
22:51  * kriskowal checks
22:51 &lt;ashb&gt; implied, but not stated
22:51 &lt;kriskowal&gt; top-level
22:51 &lt;ashb&gt; 'The &quot;module&quot; object must have an &quot;id&quot; that is the top-level &quot;id&quot; of the module.'
22:52 &lt;ashb&gt; is all it says about module.id
22:53 &lt;ashb&gt; kriskowal: what does main() do with the path?
22:53 &lt;kriskowal&gt; top-level isn't the same thing as absolute, but has the effect you're talking about.  absolute id's are beyond spec, but it makes sense to make them absolute if they're outside the module id domain
22:53 &lt;kriskowal&gt; main takes system.args, or faux args
22:53 &lt;ashb&gt; kriskowal: yeah, i think the exact mechanism doesn't need to be specified, just hte intent that you get the right module
22:54 &lt;ashb&gt; k so for the jackup example isMain would work too
22:54 &lt;kriskowal&gt; right, so the question is whether you want two channels to the same data.
22:54 &lt;ashb&gt; yeah
22:54 &lt;kriskowal&gt; unless it's your expectation for isMain to be lazily evaluated on require.main == module.id
22:55 &lt;ashb&gt; but so far the only real example usage people have given me for require.main is what you've just shown
22:55 &lt;kriskowal&gt; or as a function call that closes on those values.
22:55 &lt;ashb&gt; if anyone can give me one real example i'll drop my quest for isMain :)
22:55 &lt;ashb&gt; kriskowal: i envisaged it as a ro prop rather than a fn
22:56 &lt;kriskowal&gt; suppose that you're in another module, and you want to see the main module's exports
22:56 &lt;ashb&gt; should probably make .main and .id perm, read-only properties
22:56 &lt;kriskowal&gt; in a system where the convention is for the main module to be a config file
22:56 &lt;ashb&gt; kriskowal: yeah that makes sense
22:57 &lt;kriskowal&gt; let's not take the &quot;if nobody's doing it for real yet no one will ever want to&quot; angle.  the purpose of a language or library is to permit programs to be written unforseen by the creators of the language or library.
22:57 &lt;ashb&gt; i do wonder slightly if |require.main| is the wrong name/place for it tho
22:57 &lt;ashb&gt; kriskowal: this is true. but we also don't want to go the other way of specing everything just because it might be useful to someone
22:57 &lt;kriskowal&gt; the reasoning is that it's a place that works with many variations on the loader.
22:58 &lt;ashb&gt; but consider isMain dropped
22:58 &lt;kriskowal&gt; the idea is that sometimes &quot;require&quot; is a global object, and &quot;module&quot; is always a per-module object.
22:58 &lt;kriskowal&gt; although, in some loaders &quot;require&quot; is per-module too
22:59 &lt;ashb&gt; yeah i've switched it to per module in flusspferd
22:59 &lt;ashb&gt; cos the way we had it before broke JITing
22:59 &lt;kriskowal&gt; ihab pointed out that we could have conflated require and module using the same mechanisms in gpsee and helma that were used to discover the calling module for these other properties, but i don't intend to rock the boat.  it's a little more readable anyway.
22:59 &lt;ashb&gt; kriskowal: so module.id should certainly be RO, and i guess require.main should be too?
23:00 &lt;kriskowal&gt; i certainly wouldn't expect things to work if it were assigned too
23:00 &lt;ashb&gt; what mechanism is that?
23:00 &lt;kriskowal&gt; i'm not intimate with the details, but i presume it was through dynamic scope traversal only possible from c
23:01 &lt;ashb&gt; okay. finaly comment on the proposal is i want to remove all mentions of 'sanbox'
23:01 &lt;ashb&gt; specifially i dont see why the spec mandates that those properties must not be present in a sandbox
23:02 &lt;kriskowal&gt; in a secure sandbox
23:02 &lt;kriskowal&gt; .paths discloses information about the structure of your file system and probably even your user name, increasing the attack surface of the system
23:03 &lt;ashb&gt; yes but there are many types of secure sandbox
23:03 &lt;kriskowal&gt; we should probably revisit the issue with security experts when we actually have a real sandbox to talk about.
23:03 &lt;kriskowal&gt; like, one :P
23:03 &lt;ashb&gt; thats kinda my thinking
23:04 &lt;ashb&gt; since 'a secure sandbox' might just mean loading no new code to one person
23:04 &lt;ashb&gt; where as it might mean 'no FS access at all and no info leak' to another
23:04 &lt;kriskowal&gt; that's where dependency injection comes in
23:05 &lt;kriskowal&gt; i haven't been able to do hermetic eval in narwhal yet, due to strangeness of rhino.  can't wait to have a real Object.freeze et al
23:05 &lt;ashb&gt; yeah, in the first module.path is allowed
23:05 &lt;ashb&gt; but: 'The &quot;path&quot; property must not exist in a sandbox.'
23:06 &lt;ashb&gt; tbh i basically see (ultra-)secure sandboxes as a documented subset of commonJS
23:06 &lt;kriskowal&gt; it's a little more strict than that
23:07 &lt;ashb&gt; oh?
23:07 &lt;kriskowal&gt; if we're talking about modules and standard libraries, in the interest of real interoperability, those modules must work in a secure sandbox
23:08 &lt;kriskowal&gt; so, while engine specific components can be written in the context of commonjs related stuff, those modules are not commonjs compliant, and really can't be shared in the absolute sense
23:08 &lt;kriskowal&gt; i think the general idea is that application developers can do whatever they need, but we're promising that the standard library will work in a wide variety of contexts.
23:09 &lt;ashb&gt; yeah. i just dont like the fact we are mandating that something must not be possible in X, when we haven't really defined X
23:09 &lt;kriskowal&gt; it's better to be safe than future incompatible
23:10 &lt;Wes_&gt; Mmmm much better
23:10  * Wes_ was seeing stars
23:10 &lt;kriskowal&gt; that happens a lot in LA
23:10 &lt;ashb&gt; kriskowal: hmmm i guess you're right
23:11 &lt;kriskowal&gt; so, i think that Modules/Meta is ratified.  i guess the status line never got updated.
23:11 &lt;kriskowal&gt; would you say that's okay?
23:11 &lt;ashb&gt; tho in this specific example (module.path) i can't see how forbidding an optional property could be incompatible
23:12 &lt;ashb&gt; kriskowal: whith one slight amendment as to the intent/behaviour of module.id/require.main
23:12 &lt;kriskowal&gt; perhaps explication of intent would be the right word.  i think the normative text is as strict as we can make it without defining &quot;absolute&quot;
23:12 &lt;ashb&gt; just some verbage such as 'require.main can be passed to require() and loading the main program module'
23:12 &lt;kriskowal&gt; perhaps you can add something to the introduction or add a footnote
23:13 &lt;kriskowal&gt; ah, that would work
23:13 &lt;ashb&gt; and similar for module.id
23:13 &lt;ashb&gt; and i guess that the forms must be normalize so that .main == .id is true for the main script
23:13 &lt;kriskowal&gt; require(require.main) must return the exports of the main module
23:13 &lt;kriskowal&gt; require(module.id) must be equivalent to exports
23:14 &lt;ashb&gt; even when called from outside the current module
23:14 &lt;kriskowal&gt; even when passed through another module
23:14 &lt;kriskowal&gt; aye
23:14 &lt;ashb&gt; with those changes, yes i'm happy with it
23:14  * Wes_ is caught up
23:14 &lt;kriskowal&gt; i'd say go for it.
23:14 &lt;Wes_&gt; Not super happy with require.main -- but there isn't a better solution that doesn't involve polluting namespace: lesser of two evils wins
23:15 &lt;kriszyp&gt; so kriskowal, I sent you my work that I did on adding async/comet support to jack/narwhal. Is there anyone else I should send it to for review?
23:15 &lt;Wes_&gt; I'm also not happy with sandboxy &quot;must not&quot; -- but agree with KK pragmatism on subject
23:15 &lt;ashb&gt; Wes_: the other thing i thought was something on system module
23:15 &lt;kriskowal&gt; kriszyp: got email
23:15 &lt;Wes_&gt; ashb: possibly, but it doesn't seem like loading a module to get that seems reasomable either
23:15 &lt;kriskowal&gt; as far as i know tlrobinson isn't ready to evaluate promises.
23:15 &lt;kriskowal&gt; of course, neither am i :P
23:16 &lt;ashb&gt; Wes_: yeah it doesn't
&lt;/poem&gt;</text>
    </revision>
  </page>
  <page>
    <title>User:Mvalente</title>
    <id>293</id>
    <revision>
      <id>1353</id>
      <timestamp>2009-09-19T23:59:53Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <text xml:space="preserve">Headline

Work
[[User:Mvalente/SocketsA|SocketsA]]</text>
    </revision>
  </page>
  <page>
    <title>Sockets/A</title>
    <id>294</id>
    <revision>
      <id>1647</id>
      <timestamp>2009-10-06T23:13:35Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <comment>/* Sockets */</comment>
      <text xml:space="preserve">'''Proposal A, Draft 1 (in development)'''

The &quot;socket&quot; module supports the Socket API, providing an interface for socket manipulation.

For the purpose of this documentation, &quot;soc&quot; is a variable name for any object that implements the Socket API, including the exports of the &quot;socket&quot; module



=== Interface ===

;var s = new Socket(family, type)
:The Socket class is used to create a non-blocking TCP socket. 
*family = AF_INET (default), AF_INET6 or AF_UNIX.
*type = SOCK_STREAM for TCP (default) or SOCK_DGRAM for UDP). Others (RAW, RDM, SEQPACKET)?



==== Sockets ====

The &quot;socket&quot; module must export the following:


;connect( host, port [, timeout] ) 
:Initiate a connection on a socket. Connect to a remote port  on the specified host with a connection timeout. Throws an exception in case of failure.
* host: IP address or hostname
* port: port number or service name
* timeout: timeout value (default X microseconds)


;accept()
:Accept a connection on a socket. Returns a new (connected) Socket.


;bind( [host] [,port]) 
:When a new socket is created, it has no address bound to it. Bind assigns the specified address (also known as name) to the socket. Throws an exception in case of failure.
* host: address (interface) to which the socket will be bound. If address is ommited, any address is will match. 
* port: port number or service name to which socket is to be bound. If port is undefined, the socket wont bind to any port. 


;listen()
: Listen for incoming connections on a socket (use before an accept). Throws an exception in case of failure.


;shutdown([what])
:Shut down part of a full-duplex connection on a socket. If [what] is SHUT_RD, further receives will be disallowed. If [what] is SHUT_WR further sends will be disallowed. If what is SHUT_RDWR, further sends and receives will be disallowed.
* what: SHUT_RD, SHUT_WR or SHUT_RDWR


;close()
: Close the socket immediately 


;receive/read( [maxlen]) 
:Receive a block of bytes from the socket. Returns block of bytes read
* maxlen: number of bytes to read. Default: X bytes


;send/write(data) 
: Send a block of bytes to the socket
* data: block of bytes to send


;receiveFrom( [maxlen])
: Receive all data from socket. Returns object with ip_address and port of sender along with data properties
* maxlen: number of bytes to read. Default: X bytes


;sendTo( host, port, data) 
: Send a block of data to a specific host and port
* host: IP address or hostname
* port: port number or service name
* data: block of bytes to send


;sendFile(file)
: Sends a complete File object across a socket.
* file: a File object


;setOption( option, value)
: Set socket option value to socket option name


;getOption()
: Get socket option value, option should be socket option name

==== Tests ====

;isConnected
: Returns TRUE if the socket is in a connected state - READ ONLY

;isWritable
: Returns TRUE if socket can accept written data - READ ONLY

;isReadable
: Returns TRUE if data is waiting to be read from socket - READ ONLY




==== Metadata ====

;localAddress
: Get local socket IP address. Returns the IP address for this socket.

;localPort
: Get local socket port number. Returns the port number for this socket.

;remoteAddress
: Get remote socket IP address. Returns the IP address for this socket.

;remotePort
: Get remote socket port number. Returns the port number for this socket.


;type
: Socket type, SOCK_STREAM (TCP) or SOCK_DGRAM (UDP)</text>
    </revision>
  </page>
  <page>
    <title>SocketsA</title>
    <id>296</id>
    <revision>
      <id>1415</id>
      <timestamp>2009-09-21T16:33:30Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[Sockets/A]]</comment>
      <text xml:space="preserve">#REDIRECT [[Sockets/A]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Stream</title>
    <id>297</id>
    <revision>
      <id>1363</id>
      <timestamp>2009-09-20T02:09:10Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[IO/B/Stream]] to [[IO/B/Stream/Level1]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Stream/Level1]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Filesystem/Raw</title>
    <id>298</id>
    <revision>
      <id>1365</id>
      <timestamp>2009-09-20T02:10:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[IO/B/Filesystem/Raw]] to [[IO/B/Filesystem/Level0]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Filesystem/Level0]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Filesystem</title>
    <id>299</id>
    <revision>
      <id>1367</id>
      <timestamp>2009-09-20T02:10:48Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[IO/B/Filesystem]] to [[IO/B/Filesystem/Level1]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Filesystem/Level1]]</text>
    </revision>
  </page>
  <page>
    <title>IO/B/Stream/Raw</title>
    <id>300</id>
    <revision>
      <id>1369</id>
      <timestamp>2009-09-20T02:10:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[IO/B/Stream/Raw]] to [[IO/B/Stream/Level0]]</comment>
      <text xml:space="preserve">#REDIRECT [[IO/B/Stream/Level0]]</text>
    </revision>
  </page>
  <page>
    <title>User:Mvalente/SocketsA</title>
    <id>302</id>
    <revision>
      <id>1413</id>
      <timestamp>2009-09-21T16:31:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[User:Mvalente/SocketsA]] to [[Sockets/A]]:&amp;#32;History merge</comment>
      <text xml:space="preserve">#REDIRECT [[Sockets/A]]</text>
    </revision>
  </page>
  <page>
    <title>JSGI/Level0/A</title>
    <id>303</id>
    <revision>
      <id>2551</id>
      <timestamp>2010-04-02T16:30:54Z</timestamp>
      <contributor>
        <username>Deanlandolt</username>
        <id>15</id>
      </contributor>
      <comment>needs a note to point people to recent version</comment>
      <text xml:space="preserve">NOTE: the more recent version of this specification is [http://wiki.commonjs.org/wiki/JSGI/Level0/A/Draft2 Draft 2]


JSGI Level 0 Proposal A, Draft 1 (in development)

== Philosophy ==

* A straightforward but more user friendly mapping to existing gateway interface conventions
* Suitable for extension via some forthcoming &quot;Level 1&quot; JSGI
* Addressing all known shortcomings that would be difficult to correct with a &quot;Level 1&quot; layer (header name mangling, header case consistency, raw/decoded values)
* Tweak to be JSGI more inline with javascript idioms (proper environment variable namespacing and dot access, mixedCase keys)

== Principles ==

* Do not duplicate data in the request or response
* Optimize for the application developer, not the server or middleware developer

== Specification ==

=== Applications ===

A JSGI application is a javascript function. It takes exactly one argument, the '''environment''', and returns a JavaScript Object containing three attributes: the '''status''', the '''headers''', and the '''body'''.

=== Request ===

The request environment must be a JavaScript Object instance that includes CGI-like headers. The application is free to modify the environment. The environment is required to include these variables (adopted from PEP333 and Rack), except when they would be empty (exceptions noted below):
* '''.requestMethod''': The HTTP request method, such as &quot;GET&quot; or &quot;POST&quot;. This MUST NOT be an empty string, and so is always required.
* '''.scriptName''': The initial portion of the request URL's &quot;path&quot; that corresponds to the application object, so that the application knows its virtual &quot;location&quot;. This MAY be an empty string, if the application corresponds to the &quot;root&quot; of the server. ''Restriction: if non-empty, MUST start with &quot;/&quot; and MUST be decoded.''
* '''.pathInfo''': The remainder of the request URL's &quot;path&quot;, designating the virtual &quot;location&quot; of the request's target within the application. This may be an empty string, if the request URL targets the application root and does not have a trailing slash. ''Restriction: if non-empty, MUST start with &quot;/&quot; and MUST be decoded.''
* '''.queryString''': The portion of the request URL that follows the &quot;?&quot;, if any. ''Restriction: MAY be empty but key MUST exist.''
* '''.serverName''', '''serverPort''': When combined with scriptName and pathInfo, these variables can be used to complete the URL. Note, however, that '''.headers.host''', if present, should be used in preference to serverName for reconstructing the request URL. ''Restriction: serverName and serverPort can never be empty strings, and so MUST be present.''
* '''.scheme''': URL scheme (per [http://www.ietf.org/rfc/rfc1738.txt RFC 1738]). &quot;http&quot;, &quot;https&quot;, etc.
* '''.body''': The request body, which MAY be empty. ''Requirement: MUST be an input stream.''

Variables corresponding to the client-supplied HTTP request headers are stored in the '''.headers''' object. The presence or absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request. All keys in the '''.headers''' object MUST be the lower-case equivalent of the request's HTTP header keys.

In addition to this, the request environment MUST include these JSGI-specific variables:
* '''.jsgi''':
** '''.jsgi.version''': The Array [0,3], representing this version of JSGI.
** '''.jsgi.errors''': See below, the error stream.
** '''.jsgi.multithread''': true if the application object may be simultaneously invoked by another thread in the same process, false otherwise.
** '''.jsgi.multiprocess''': true if an equivalent application object may be simultaneously invoked by another process, false otherwise.
** '''.jsgi.runonce''': true if the server expects (but does not guarantee!) that the application will only be invoked this one time during the life of its containing process. Normally, this will only be true for a sever based on CGI (or something similar).

JSGI server implementations are encouraged to include as much information in the request environment as possible. CGI-like keys ('''TODO''': define?) should be all lower case, except letters following the underscores, which should be upper case, with the underscore removed, and stored at the top level of the environment ('''TODO''': this wording sucks, somebody FIXME). These keys MUST have string values.

&lt;strike&gt;Servers or applications can also store their own data in the request environment. In order to prevent collisions with unspecified CGI keys, custom keys MUST be stored in the '''.env''' top level object.&lt;/strike&gt;

=== Input Stream ===

Must be an input stream. ('''TODO''' can we reference something in particular?)

=== Output Stream ===

Must be an output stream.

=== Response ===

;.status
:The status MUST be an integer greater than or equal to 100. ('''TODO''' changed from &quot;if parsed as an integer&quot; -- was this right?)
;.headers
:The header MUST be a JavaScript object containing key/value pairs of Strings. All keys SHOULD be lower-case to prevent confusion. The header must not contain a Status key, contain keys with : or newlines in their name, contain keys names that end in - or _, but only contain keys that consist of letters, digits, _ or - and start with a letter. The values of the header must be Strings, consisting of lines (for multiple header values) separated by “\n”. The lines must not contain characters below 037.
:* '''content-type''': There must be a Content-Type, except when the Status is 1xx, 204 or 304, in which case there must be none given.
:* '''content-length''': There must not be a Content-Length header when the Status is 1xx, 204 or 304.
Compliant Level 0 servers MUST accept header keys that are lower-case over keys that contain capital letters but are otherwise identical. Servers SHOULD ignore keys that contain capital letters. Servers MAY case-correct keys when serving the response in any manner. ('''TODO''': DL assumed this was decided but it's still up in the air -- if you have an opinion one way or another please show your hand here or on the mailing list)
;.body
:The Body must respond to forEach and must only yield objects which have a toByteString method (including Strings and Binary objects) ('''TODO''': is this a dependency on the binary spec?). If the Body responds to close, it will be called after iteration. The Body commonly is an array of Strings or ByteStrings.

== Summary of changes from [http://jackjs.org/jsgi-spec.html JSGI 0.2] ==

''NOTE: this area is not aligned with proposals in the Open Issues section and is most certainly out of date.''

=== Environment ===

==== Top level keys ====

* UPPER_SNAKE_CASE to mixedCase
* No alterations to key names themselves (env.REQUEST_METHOD to env.requestMethod, not env.method)
* Server or application-specific environment keys no longer required to contain a &quot;.&quot; to differentiate from CGI keys. Since CGI keys MUST be strings; added top-level keys in the environment MUST be objects.
* CONTENT_LENGTH and CONTENT_TYPE moved into headers object and case-normalized (TODO: should content-length still be parsed down to an int?)

=== JSGI variables ===

* moved env[&quot;jsgi.URL_SCHEME&quot;] to env[&quot;scheme&quot;] (rationale: it's not a CGI key so no need to maintain consistency in naming)
* moved env[&quot;jsgi.input&quot;] to env[&quot;body&quot;] (rationale: consistent with response object)
* env[&quot;jsgi.*&quot;] to env[&quot;jsgi&quot;][&quot;*&quot;]; changed snake_case to mixedCase (technically, all lowercase)
* lower_snake_case to mixedCase

=== Headers variables ===

* env[&quot;HTTP_*&quot;] to env[&quot;headers&quot;][&quot;*&quot;]
* Header keys MUST NOT be mangled in any way, and must be set in lower-case form

=== Server or application variables: ===

* Instead of differentiating these by requiring a &quot;.&quot;, we require added top-level keys to contain an object

== Notes ==

The &quot;jsgi&quot; property only contains metadata related to JSGI itself, not HTTP, top level contains HTTP info. &quot;input&quot; is moved top level &quot;body&quot;, and &quot;url_scheme&quot; is &quot;scheme&quot;, like servlet's request.

== Open questions ==

;The &quot;CGI&quot; problem
:JSGI server implementations built atop CGI SHOULD provide a truthy &lt;code&gt;.jsgi.cgi&lt;/code&gt; parameter (in case we discover multiple levels of cgi FAIL)

*DL: What should our NOTE FOR CGI IMPLEMENTERS say? They have to s/_/-/g header keys, for one.

;Response key casing
:(a) lower-case
:(b) UPPER-CASE
:(c) Mixed-case
:(d) specify a case-insensitive object
:(e) unspecified
*DL: (a) +1; (c), (d), (e) -1

;Content-Length -- where should it appear?
:(a) &lt;code&gt;.headers[&quot;content-length&quot;]&lt;/code&gt; as String
:(b) &lt;code&gt;.contentLength&lt;/code&gt; as integer, added by server if response is buffered
:(c) Both
*DL: (a) +1; (c) -1: including both would violate our principle of non-duplication

;Header modification
:Should it be noted whether servers or applications are encouraged, discouraged or prevented from adding or modifying headers (e.g. .headers[&quot;content-length&quot;])? Is there any rationale for preventing this (e.g. the headers SHOULD reflect the initial state of the request)?
*DL: -1, I think it should stay unspecified

;More spec-like
:Should we call out normative references where they have been codified for required environment variable? This would allow us to ''explicitly'' override them in specific cases (PATH_INFO, SCRIPT_NAME).
*DL: +1: I'll add them -- they'll be easy to remove if this is a bad idea

;Response Reason
:Specifying a ''.reason'' or ''.statusText'' on the response object would duplicate information. If this is necessary servers could provide a mechanism to make this happen -- does this merit a note?
*DL: probably not: &quot;The client is not required to examine or display the Reason-Phrase.&quot; -- [http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 RFC 2616]

;Replacing the &quot;request&quot; object
:Overwriting the &quot;request&quot; object with a new environment -- should this be explicitly disallowed? If L0 middleware does this it could break L1 middleware. But in order for L1 to exist on an L0 server it would need to wrap the request. The function of L1 doesn't belong in this discussion, but we should probably at least discuss the implications here.
*DL: +1 on explicitly disallowing this

;Response object defaults
:Should applications and middleware be REQUIRED to return a full response object -- status, headers and body? If not, middleware developers will always have to feature-test the response -- is this a problem?
*DL: a related question is async testing promises

;Async
:How much should we say about async usage patterns? Kris Zyp has gone into great detail on the list, discussions we could link to -- but what kind of normative language should the spec contain about async?

;Top-level env conflicts
:When additional CGI keys are added to the environment, they should exist at the top level and be camelCased -- this opens the door to conflicts with user-added keys. How do we fix this?
*DL: I've got a suggestion on the ML

== Acknowledgements ==

This specification is adapted from the [http://rack.rubyforge.org/doc/files/SPEC.html Rack specification] written by Christian Neukirchen.

Some parts of this specification are adopted from [http://www.python.org/dev/peps/pep-0333/ PEP333: Python Web Server Gateway Interface v1.0].</text>
    </revision>
  </page>
  <page>
    <title>File:Packages-0.png</title>
    <id>304</id>
    <revision>
      <id>1437</id>
      <timestamp>2009-09-23T21:32:54Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <comment>uploaded a new version of &quot;[[File:Packages-0.png]]&quot;</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-1.png</title>
    <id>305</id>
    <revision>
      <id>1443</id>
      <timestamp>2009-09-23T21:54:33Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-2.png</title>
    <id>306</id>
    <revision>
      <id>1451</id>
      <timestamp>2009-09-23T23:03:06Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-file.png</title>
    <id>307</id>
    <revision>
      <id>1453</id>
      <timestamp>2009-09-23T23:10:17Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-3.png</title>
    <id>308</id>
    <revision>
      <id>1460</id>
      <timestamp>2009-09-23T23:27:01Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-3.5.png</title>
    <id>309</id>
    <revision>
      <id>1462</id>
      <timestamp>2009-09-23T23:30:26Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-5.png</title>
    <id>310</id>
    <revision>
      <id>1466</id>
      <timestamp>2009-09-23T23:49:59Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <comment>uploaded a new version of &quot;[[File:Packages-5.png]]&quot;</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Packages-misc.png</title>
    <id>311</id>
    <revision>
      <id>1504</id>
      <timestamp>2009-09-28T04:12:58Z</timestamp>
      <contributor>
        <username>Ihab</username>
        <id>11</id>
      </contributor>
      <comment>uploaded a new version of &quot;[[File:Packages-misc.png]]&quot;</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>JSGI/B/Voting</title>
    <id>313</id>
    <revision>
      <id>1502</id>
      <timestamp>2009-09-27T09:18:34Z</timestamp>
      <contributor>
        <username>Mikewse</username>
        <id>9</id>
      </contributor>
      <comment>removing</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>JSGI/Level1/A</title>
    <id>314</id>
    <revision>
      <id>1530</id>
      <timestamp>2009-09-28T23:32:45Z</timestamp>
      <contributor>
        <username>Deanlandolt</username>
        <id>15</id>
      </contributor>
      <minor/>
      <comment>/* Response */</comment>
      <text xml:space="preserve">Just reserving this page for some notes on L1 nice to haves:

== Request ==

An object that can accommodate:
* Header case-insensitive hash implementation
* Cosmetic cleanups

== Response ==

An object that can accommodate:
* Automagical promise fulfillment
* Header case-preservation hints
* Reason message hints</text>
    </revision>
  </page>
  <page>
    <title>Talk:IO/B/Filesystem/Level0</title>
    <id>315</id>
    <revision>
      <id>1555</id>
      <timestamp>2009-10-04T05:25:18Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve"># you still use OpaqueLeaf. as i mentioned before, Leaf bad term
# all the listXXX functions are odd. 
#* a) can't list on a file either
# open doesn't make sense on a dir
# 2+3 imply to me that its worht separating into Dir only, File only, and common (Path or Entity)
# isFile isn't always !isDir (fifo,socket, etc)
# should probably have an lstat to go with your stat
# createDir should die if it fails, not return false.
# ditto for anything else that returns false on failure. (setLastModified)
# lastModified returning a date or false is odd od odd. Date or undefined/null, or perhaps even die
[[User:Ashb|Ashb]] 20:14, 3 October 2009 (UTC)

:# couldn't come up with a new name yet
:# listXXX are due to open/read/close dir not being portable (Java replaces them with a variety of list functions which can be filtered in different ways).
:#* a) Course, it errors
:# Course, it errors
:# The other apis didn't exactly do it... and it's not really a common thing to do. I don't see a reason. Especially since this is level0.
:# I know, I debated an isOther, thought !isFile !isDirectory would do, Java doesn't provide this either. I could make a note though.
:# stat is lstat; stat and lstat work on file descriptors and paths, an Opaque in that api would be a path, file descriptors don't exist on opaques, file descriptors are used by streams, another stat would require a stat in the stream api.
:# Java doesn't throw errors, what about other engines? Throwing an error when a directory you want to exist already exists sounds strange.
:# I was avoiding custom errors at this level, this is a low level interface, IMHO not the place for custom errors that are hard to implement in JS engines.
:# To match up with other methods
:[[User:Dantman|Daniel Friesen]]05:25, 4 October 2009 (UTC)</text>
    </revision>
  </page>
  <page>
    <title>Filesystem/A/0</title>
    <id>316</id>
    <revision>
      <id>2787</id>
      <timestamp>2010-05-23T23:58:21Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>corrected narwhal rhino version</comment>
      <text xml:space="preserve">{{Spec
|status=implementations, unresolved issues with permissions
|implementations=Flusspferd, GPSEE, NarwhalNode=0.5, NarwhalRhino=8a45686, RingoJS
}}

The &quot;fs-base&quot; module exports a minimal, engine-specific interface for manipulating a file system and constructing raw byte streams.  The [[IO|IO stream API]] is beyond the scope of this specification.  It is the intent of this specification to provide exactly and only the components of a file system API that cannot be implemented in pure JavaScript.  

''Pending the ratification of [[Filesystem/A]]: Implementations may opt to provide more methods, matching the interfaces specified in [[Filesystem/A]], if they can be implemented with better performance natively than in pure JavaScript based on the methods specified here.''

= Specification =

== Types ==

Arguments used throughout this document will have the following types, unless explicitly specified otherwise:

* '''path''' is either a String, an Object with a toString() method, or an Object with a valueOf() method that returns an Object with a toString() method. In the case where path is an Object, the object must return the same string for the same path on the same system, provided the path in canonicalizable.

* '''mode''' is an Object describing the open mode for a file. Each property is subject to a true or falsey test. Meaningful properties include read, write, append, truncate, create, and exclusive.  ''Note: any value is equivalent to false if the property is omitted.''

* '''permissions''' is an instance of Permissions, or a duck-type thereof.

The &quot;fs-base&quot; module exports the following constructors:

* '''Permissions''', a class that describes file system permissions. Instances of Permissions are initially deep copies of all transitively owned properties of Permissions.default and have a eponymous property for the optional &quot;constructor&quot; argument of the constructor.
** Mandatory properties on all platforms are Boolean values owner.read and owner.write. 
** Mandatory properties on UNIX platforms platforms are Boolean values owner.{read, write, execute}, group.{read, write, execute} and other.{read, write, execute}. 
** Permissions.default must initially reflect the current default file creation permissions in the host environment; i.e. in a UNIX environment, Permissions.default would reflect the inverse of umask. Where this is not possible, compliant implementations must initialize Permissions.default to {{owner: {read: true, write: true}}

== Files ==

; openRaw(path, mode, permissions)
: returns a raw byte stream object with the given mode and permissions from the [[IO]] system. The details of this object are unspecified, except 
* it has a &quot;close&quot; method that closes any operating-system level resources allocated by &quot;openRaw&quot;, and 
* the garbage collector must finalize the stream by performing an equivalent operation to the &quot;close&quot; method to prevent resource leaks.

&quot;openRaw&quot; throws an exception when &quot;path&quot; cannot be opened, or &quot;path&quot; refers to a directory.
* &quot;openRaw&quot; interprets the '''mode''' object's properties as follows
** '''read''': open for reading
** '''write''': open for writing
** '''append''': open for writing: the file position is set to the end of the file before every write. An exception is thrown when append is not used in conjunction with write.
** '''create''': create the file if it does not exist
** '''exclusive''': used only in conjunction with create, specifies that the if the file already exists that the open should fail. &quot;openRaw&quot; must implement &quot;exclusive&quot; with atomic file system primitives. &quot;openRaw&quot; must throw an exception when &quot;path&quot; is a symbolic link, and when &quot;exclusive&quot; is used without &quot;create&quot;.
** '''truncate''': used only in conjunction with &quot;write&quot; or &quot;append&quot;, specifies that if the path exists, it must be truncated (not replaced) by &quot;openRaw&quot;. &quot;openRaw&quot; must throw an exception when &quot;truncate&quot; is used without &quot;write&quot;.
* When creating a file, the '''permissions''' object passed to &quot;openRaw&quot; is used as the argument to the Permissions constructor. The resultant Permissions instance is used to open this file.

; move(source, target)
: Moves a file at one path to another. Failure to move the file, or specifying a directory for target when source is a file must throw an exception. 

* When the files are in the same file system, a compliant implementation must use the operating system's underlying atomic move or rename function to perform this operation.
* When the files are not in the same file system, a compliant implementation may choose to copy-then-remove the original file. This behaviour is encouraged when there is technical means to accomplish this by system-wide atomic means. In the case where target is copied, a conforming implementation must
** Overwrite the target file if it exists
** Not create or alter an existing target file unless the entire operation succeeds
** Transfer permissions from source to target (failure to do so must throw)
** Make an effort to transfer ownership from source to target
** Preserve modification time from source to target (failure to do so must throw)
** Not remove the source file unless the entire operation succeeds (move does not throw)

; remove(path String)
: Removes the file at the given path.  Throws an exception if the path corresponds to anything that is not a file or a symbolic link.  If &quot;path&quot; refers to a symbolic link, removes the symbolic link.

; touch(path, mtime_opt Date)
: Sets the modification time of a file or directory at a given path to a specified time, or the current time.  Creates an empty file at the given path if no file (special or otherwise) or directory exists, using the default permissions (as though openRaw were called with no permissions argument).  If the underlying file system does not support milliseconds, the time is truncated (not rounded) to the nearest supported unit.   On file systems that support last-accessed time, this must be set to match the modification time.  Where possible, the underlying implementation should insure that file creation and time stamp modification are transactionally related to the same file, rather than the same directory entry.

== Directories ==

; makeDirectory(path, permissions_opt)
: Create a single directory specified by ''path''. If the directory cannot be created for any reason an exception must be thrown. This includes if the parent directories of &quot;path&quot; are not present. The '''permissions''' object passed to this method is used as the argument to the Permissions constructor. The resultant Permissions instance is applied to the given path during directory creation. 

* Conforming implementations must create the directory with the exact permissions given, rather than applying the permissions after directory creation. In cases where this is not possible, the directory must be created with more restrictive permissions than specified, and a subsequent system call will be used to relax them.

; removeDirectory(path) 
: Removes a directory if it is empty. If path is not empty, not a directory, or cannot be removed for another reason an exception must be thrown. If path is a link and refers canonically to a directory, the link must be removed.

; move(source, target)
: Moves a directory from one path to another on the same file system. Does not copy the directory under any circumstances. A conforming implementation must move the directory using the operating system's file-system-atomic move or rename call. If it cannot be moved for any reason an exception must be thrown. An exception must be thrown if &quot;target&quot; specifies an existing directory.
: *Note*: this is the same method used to move files. The behaviour differs depending on whether source is a file or directory.

== Paths ==

; canonical(path) String
: returns the canonical path to a given abstract path.  Canonical paths are both absolute and intrinsic, such that all paths that refer to a given file (whether it exists or not) have the same corresponding canonical path.  This function is equivalent to joining the given path to the current working directory (if the path is relative), joining all symbolic links along the path, and normalizing the result to remove relative path (. or ..) references.

* When the underlying implementation is built on a Unicode-aware file system, Unicode normalization must also be performed on the path using the same normal form as the underlying file system.

* It is not required that paths whose directories do not exist have a canonical representation. Such paths will be canonicalized as &quot;undefined&quot;. ''Note: this point has caused some argument, and the exact behaviour in this case needs to be determined.''

; workingDirectory() String
: returns the current working directory as an absolute String (not as an object with a toString method)

; changeWorkingDirectory(path)
: changes the current working directory to the given path, resolved on the current working directory. Throws an exception if the operation failed. 

* ''Note: It is not required that this method call the operating system's underlying change-directory system call; virtualizing the appearance of a working directory at the level of this API to the JavaScript environment is sufficient for a compliant implementation. Module writers implementing modules in a language other than JavaScript (i.e. Java or C++) should take care when interoperating with this module.''

== Security ==

; owner(path) String
; owner(path) Number ''optional''
: returns the name of the owner of a file with typeof string. Where the owner name is not defined, a numeric userId with typeof number may be returned instead. 

; group(path) String 
; group(path) Number ''optional''
: returns the name of the group owner of a file with typeof string. Where the group name is not defined, a numeric groupId with typeof number may be returned instead.  This interface is optional but recommended when Permissions support a group member; the numeric interface shall not be implemented unless the String interface is implemented.

; changeOwner(path, name String)
; changeOwner(path, userId Number) ''optional''
: sets the owner of a given file or directory. If path is a symbolic link, the target file or directory is affected instead. Throws an exception if the operation fails for any reason (including that current user does not have permission to change the owner). This method must accept any return values from the &quot;owner&quot; method.

; changeGroup(path, name String)
; changeGroup(path, userId Number) ''optional''
: sets the group ownership of a given file or directory. If path is a symbolic link, the target file or directory is affected instead. Throws an exception if the operation fails for any reason (including that current user does not have permission to change the group). This method must accept any return values from the &quot;group&quot; method.  This interface is optional but recommended when Permissions support a group member; the numeric interface shall not be implemented unless the String interface is implemented.

; permissions(path) Permissions
: returns a Permissions object describing the current permissions for a given path. If path is a symbolic link, the returned permissions describe the target file or directory and not the link file itself.

; changePermissions(path, permissions Permissions)
: sets the permissions for a given path.  The '''permissions''' object passed to this method is used as the argument to the Permissions constructor. The resultant Permissions instance is applied to the given path if it is a file or directory; if path is a symbolic link it will be applied to the link target instead.

== Links ==

Symbolic and hard links must not be emulated with Windows Shortcuts. On systems where symbolic links are not supported, symbolicLink and readLink must be undefined. On systems where hard links are not supported, hardLink must be undefined.

; symbolicLink(source, target)
: creates a symbolic link at the target path that refers to the source path.  Must throw an exception if the target already exists. Conforming implementations must not rewrite or canonicalize either the source or target arguments, nor validate that the link target exists, before passing to the underlying filesystem layer. ''Note: The intent is to allow users to create directory hierarchies with symbolic links that can be freely moved around a filesystem and maintain internal referential integrity.''

; hardLink(source, target)
: creates a hard link at the target path that shares storage with the source path.  Throws an exception if this is not possible, such as when the source and target are on separate logical volumes or hard links are not supported by the volume.

; readLink(path) String
: returns the immediate target of a symbolic link at a given path.  Throws an exception if there is no symbolic link at the given path or the link cannot be read. This function differs from canonical in that it may return a path that itself is a symbolic link.

== Tests ==

; exists(path)
: returns true if a file (of any type) or a directory exists at a given path. If the file is a broken symbolic link, returns false. 

; isFile(path)
: returns true if a path exists and that it, after resolution of symbolic links, corresponds to a regular file.

; isDirectory(path)
: returns whether a path exists and that it, after resolution of symbolic links, corresponds to a directory.

; isLink(target)
: returns whether a symbolic link exists at &quot;target&quot;.  Windows Shortcuts must not be equated with symbolic links. This function must not follow/resolve symbolic links.

; isReadable(path)
: returns whether a path exists and that it could be opened for reading at the time of the call using &quot;openRaw&quot; for files or &quot;list&quot; for directories.

; isWriteable(path)
: If a path exists, returns whether a file may be opened for writing, or entries added or removed from an existing directory.  If the path does not exist, returns whether entries for files, directories, or links can be created at its location.

; same(pathA, pathB) Boolean
: returns whether two paths refer to the same storage (file or directory), either by virtue of symbolic or hard links, such that modifying one would modify the other. In the case where either some or all paths do not exist, we return false. If we are unable to verify if the storage is the same (such as by having insufficient permissions), an exception is thrown.

; sameFilesystem(pathA, pathB) Boolean
: returns whether two paths refer to an entity on the same filesystem. An exception will be thrown if it is not possible to determine this.
* In the case where any path does not exist, we yield the same result as though it did exist, and that any necessary intermediate directories also exist as real directories and not symbolic links.

== Attributes ==

; size(path) Number
: returns the size of a file in bytes, or throws an exception if the path does not correspond to an accessible path, or is not a regular file or a link. If path is a link, returns the size of the final link target, rather than the link itself. 
: Care should be taken that this number returned is suitably large (i.e. that we can get useful figures for files over 1GB (30bits+sign bit). If the size of a file cannot be represented by a JavaScript number, &quot;size&quot; must throw a RangeError.

; lastModified(path) Date
: returns the time that a file was last modified as a Date object.

== Listing ==

; list(path) Array * String
: returns the names of all the files in a directory, in lexically sorted order.  Throws an exception if the directory cannot be traversed (or path is not a directory).
: ''Note: this means that &lt;code&gt;list(&quot;x&quot;)&lt;/code&gt; of a directory containing &lt;code&gt;&quot;a&quot;&lt;/code&gt; and &lt;code&gt;&quot;b&quot;&lt;/code&gt; would return &lt;code&gt;[&quot;a&quot;, &quot;b&quot;]&lt;/code&gt;, not &lt;code&gt;[&quot;x/a&quot;, &quot;x/b&quot;]&lt;/code&gt;.''

; iterate(path) Iterator * String
: returns an iterator that lazily browses a directory, backward and forward, for the base names of entries in that directory.

=== Iterator Objects ===

Iterator objects have the following members:

; next() String or Path
: returns the next path in the iteration or throws &quot;StopIteration&quot; if there is none.

; iterator()
: returns itself

; close()
: closes the iteration.  After calling close, all calls to next and prev must throw StopIteration.

== Extended Attributes (optional) ==

Extended attribute methods may be defined on systems that may support the feature on some volumes.  See [http://en.wikipedia.org/wiki/Extended_file_attributes].

; getAttribute(path, key String, default ByteString) ByteString
: Gets the value of an extended attribute.  If a third argument is provided, including undefined, and there is no corresponding extended attribute for the requested key, the default is returned.  Otherwise, if there is no extended attribute for the requested key, getAttribute must throw an exception. Throws a ValueError if the volume does not support extended attributes.

; setAttribute(path, key String, value ByteString)
: Sets an extended attribute.  Throws a ValueError if the volume does not support extended attributes.

; removeAttribute(path, key String)
: Removes the extended attribute for a given key.  If there is no corresponding key, throws an exception. Throws a ValueError if the volume does not support extended attributes.

; listAttributeNames(path) Array * String
: returns an Array of Strings of the keys of all extended attributes on a given path. Throws a ValueError if the volume does not support extended attributes.

== Unicode ==

* Filesystems which are Unicode-compatible shall have their file names seamlessly translated to and from Strings containing UTF-16BE or UTF-16LE, depending on the native architecture.

* Filesystems which are not Unicode-compatible shall have file names represented in JavaScript strings such that all unique filenames generate unique Strings, and all values returned by the index() method are suitable for use as a path.

= Notes =

* Conformant implementations working on ''path'' must not alter the permissions of ''path'''s parent directory to complete an operation, even if altering the permissions of the parent directory would be necessary for the operation to succeed.

The following topics have been deferred for a future specification:

* locking
* access control lists (ACL's)
* temporary files and directories

= Implementations =

* Trial implementation in Flusspferd (no permissions support yet)
* Trial implementation in GPSEE

= Related Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/150ff8f33d4810ea Minimal Filesystem API]</text>
    </revision>
  </page>
  <page>
    <title>Template:Hint</title>
    <id>317</id>
    <revision>
      <id>1664</id>
      <timestamp>2009-10-08T11:11:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;div class=hint&gt;'''Hint:''' {{{1|{{{ }}}}}}&lt;/div&gt;</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing/1.0/Voting</title>
    <id>318</id>
    <revision>
      <id>2115</id>
      <timestamp>2010-02-19T01:28:09Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Must throw error */</comment>
      <text xml:space="preserve">== Show of Hands ==

=== Assertion ===
* assert.assert(actual, message_opt)
** Tom Robinson
** Ash Berlin
** Kris Kowal
* assert.is(true, actual, message_optl)
** George Moschovitis
** Raphael Speyer
* assert.isTrue(actual, message_opt)
** Neville Burnell
** Chris Zumbrunn
** Nathan Stott
* assert.ok(action, message_opt)
** Dean Landolt

=== Deep equivalence assertion ===
* none
* assert.eq(expected, actual, message_opt)
** Kris Kowal
** Ash Berlin
** Ates Goral
* assert.equal(expected, actual, message_opt)
** Hannes Wallnöfer
** George Moschovitis
** Dean Landolt
** Raphael Speyer
* assert.isEqual(expected, actual, message_opt)
** Chris Zumbrunn
** Nathan Stott
* assert.equals(expected, actual, message_opt)
* assert.equiv(expected, actual, message_opt)
* assert.equivalent(expected, actual, message_opt)

=== Deep non-equivalence assertion ===
* none
* assert.notEqual(expected, actual, message_opt)
** Hannes Wallnöfer
** George Moschovitis
** Chris Zumbrunn
** Dean Landolt
* assert.ne(expected, actual, message_opt)
** Kris Kowal
** Ates Goral
** Ash Berlin
* assert.neq(expected, actual, message_opt)
** Ates Goral
* assert.notEqual(expected, actual, message_opt)
* assert.notEquals(expected, actual, message_opt)
* assert.notEquiv(expected, actual, message_opt)
* assert.notEquivalent(expected, actual, message_opt)
* assert.not.eq(expected, actual, message_opt)
* assert.not.equal(expected, actual, message_opt)
** Dean Landolt
** Nathan Stott
** Raphael Speyer

=== Object identity assertion ===
* assert.same(expected, actual, message_opt)
** Hannes Wallnöfer
** Dean Landolt
** Nathan Stott
** Raphael Speyer
* assert.is(expected, actual, message_opt)
** Kris Kowal
** Ash Berlin
* assert.isIdentical(expected, actual, message_opt)
** Chris Zumbrunn
* assert.identical(expected, actual, message_opt)

=== Object non-identity ===
* none
* assert.notSame(expected, actual, message_opt)
** Hannes Wallnöfer
** Dean Landolt
* assert.isnt(expected, actual, message_opt)
** Ash Berlin
** Ates Goral
* assert.ni(expected, actual, message_opt)
* assert.notIdentical(expected, actual, message_opt)
** Chris Zumbrunn
* assert.not.same
** Dean Landolt
** Nathan Stott
** Raphael Speyer

=== Must throw error ===
* none
* assert.throws
** Hannes Wallnöfer
** Ash Berlin
** George Moschovitis
** Chris Zumbrunn
** Dean Landolt
* assert.error
** Kris Kowal

=== Arguments ===

# (A) making (message, guard) and (guard) the accepted argument forms.
#* Daniel Friesen
# (B) making (guard, message) and (guard) the accepted argument forms.
#* Ash Berlin
#* Mark Porter
#* Kris Kowal
#* George Moschovitis
#* Hannes Wallnöfer

# (X) make the assertion message mandatory.
#* 
# (Y) make the assertion message optional.
#* Ash Berlin
#* Kris Kowal
#* Mark Porter
#* George Moschovitis
#* Hannes Wallnöfer</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing/A</title>
    <id>319</id>
    <revision>
      <id>1690</id>
      <timestamp>2009-10-16T04:42:39Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Unit Testing/A]] to [[Unit Testing/1.0]]:&amp;#32;ratification</comment>
      <text xml:space="preserve">#REDIRECT [[Unit Testing/1.0]]</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing/A/Voting</title>
    <id>320</id>
    <revision>
      <id>1692</id>
      <timestamp>2009-10-16T04:42:39Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Unit Testing/A/Voting]] to [[Unit Testing/1.0/Voting]]:&amp;#32;ratification</comment>
      <text xml:space="preserve">#REDIRECT [[Unit Testing/1.0/Voting]]</text>
    </revision>
  </page>
  <page>
    <title>Modules/SecurableModules</title>
    <id>321</id>
    <revision>
      <id>1695</id>
      <timestamp>2009-10-16T04:56:09Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Modules/SecurableModules]] to [[Modules/1.0]]:&amp;#32;ratification</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/1.0]]</text>
    </revision>
  </page>
  <page>
    <title>System</title>
    <id>322</id>
    <revision>
      <id>1697</id>
      <timestamp>2009-10-16T04:56:52Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[System]] to [[System/1.0]]</comment>
      <text xml:space="preserve">#REDIRECT [[System/1.0]]</text>
    </revision>
  </page>
  <page>
    <title>System/ArchivedShowOfHands</title>
    <id>324</id>
    <revision>
      <id>1701</id>
      <timestamp>2009-10-16T04:56:52Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[System/ArchivedShowOfHands]] to [[System/1.0/ArchivedShowOfHands]]</comment>
      <text xml:space="preserve">#REDIRECT [[System/1.0/ArchivedShowOfHands]]</text>
    </revision>
  </page>
  <page>
    <title>System/1.0/1.0</title>
    <id>325</id>
    <revision>
      <id>1703</id>
      <timestamp>2009-10-16T04:58:28Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[System/1.0/1.0]] to [[System/1.0]] over redirect</comment>
      <text xml:space="preserve">#REDIRECT [[System/1.0]]</text>
    </revision>
  </page>
  <page>
    <title>Modules/1.1</title>
    <id>326</id>
    <revision>
      <id>2800</id>
      <timestamp>2010-05-27T09:10:24Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=multiple implementations
|standard=yes
|implementations=Ejscript=2.x, Flusspferd=0.9, GPSEE, Narwhal=0.2, Persevere=?, RingoJS, SproutCore=?, v8cgi, Wakanda
}}

This specification addresses how modules should be written in order to be interoperable among a class of module systems that can be both client and server side, secure or insecure, implemented today or supported by future systems with syntax extensions.  These modules are offered privacy of their top scope, facility for importing singleton objects from other modules, and exporting their own API.  By implication, this specification defines the minimum features that a module system must provide in order to support interoperable modules.

== Contract ==

=== Module Context ===

# In a module, there is a free variable &quot;require&quot;, that is a Function.
## The &quot;require&quot; function accepts a module identifier.
## &quot;require&quot; returns the exported API of the foreign module.
## If there is a dependency cycle, the foreign module may not have finished executing at the time it is required by one of its transitive dependencies; in this case, the object returned by &quot;require&quot; must contain at least the exports that the foreign module has prepared before the call to require that led to the current module's execution.
## If the requested module cannot be returned, &quot;require&quot; must throw an error.
## The &quot;require&quot; function may have a &quot;main&quot; property that is read-only, don't delete and represents the top-level &quot;module&quot; object of the program. If this property is provided, it must be referentially identical to the &quot;module&quot; object of the main program.
## The &quot;require&quot; function may have a &quot;paths&quot; attribute, that is a prioritized Array of path Strings, from high to low, of paths to top-level module directories.
### The &quot;paths&quot; property must not exist in &quot;sandbox&quot; (a secured module system).
### The &quot;paths&quot; attribute must be referentially identical in all modules.
### Replacing the &quot;paths&quot; object with an alternate object may have no effect.
### If the &quot;paths&quot; attribute exists, in-place modification of the contents of &quot;paths&quot; must be reflected by corresponding module search behavior.
### If the &quot;paths&quot; attribute exists, it may not be an exhaustive list of search paths, as the loader may internally look in other locations before or after the mentioned paths.
### If the &quot;paths&quot; attribute exists, it is the loader's prorogative to resolve, normalize, or canonicalize the paths provided.
# In a module, there is a free variable called &quot;exports&quot;, that is an object that the module may add its API to as it executes.
## modules must use the &quot;exports&quot; object as the only means of exporting.
# In a module, there must be a free variable &quot;module&quot;, that is an Object.
## The &quot;module&quot; object must have a read-only, don't delete &quot;id&quot; property that is the top-level &quot;id&quot; of the module. The &quot;id&quot; property must be such that &lt;tt&gt;require(module.id)&lt;/tt&gt; will return the exports object from which the &lt;tt&gt;module.id&lt;/tt&gt; originated. (That is to say module.id can be passed to another module, and requiring that must return the original module).
## The &quot;module&quot; object may have a &quot;uri&quot; String that is the fully-qualified URI to the resource from which the module was created.  The &quot;uri&quot; property must not exist in a sandbox.

=== Module Identifiers ===

# A module identifier is a String of &quot;terms&quot; delimited by forward slashes.
# A term must be a camelCase identifier, &quot;.&quot;, or &quot;..&quot;.
# Module identifiers may not have file-name extensions like &quot;.js&quot;.
# Module identifiers may be &quot;relative&quot; or &quot;top-level&quot;.  A module identifier is &quot;relative&quot; if the first term is &quot;.&quot; or &quot;..&quot;.
# Top-level identifiers are resolved off the conceptual module name space root.
# Relative identifiers are resolved relative to the identifier of the module in which &quot;require&quot; is written and called.

=== Unspecified ===

This specification leaves the following important points of interoperability unspecified:

# Whether modules are stored with a database, file system, or factory functions, or are interchangeable with link libraries.
# Whether a PATH is supported by the module loader for resolving module identifiers.

== Unit Tests ==

* [http://github.com/commonjs/commonjs/tree/master/tests/modules Unit tests on CommonJS Github Repository]

== Sample Code ==

;math.js:
&lt;source&gt;
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i &lt; l) {
        sum += args[i++];
    }
    return sum;
};
&lt;/source&gt;

;increment.js:
&lt;source&gt;
var add = require('math').add;
exports.increment = function(val) {
    return add(val, 1);
};
&lt;/source&gt;

;program.js:
&lt;source&gt;
var inc = require('increment').increment;
var a = 1;
inc(a); // 2

module.id == &quot;program&quot;;
&lt;/source&gt;

== Notes ==

* [[Modules/Secure|Secure Modules]]
* [[Modules/Natives|How Modules relate to global natives like String]]
* [[Modules/Natives|How do you extend native prototypes from a Module?]]
* [[Modules/CompiledModules|Notes on compiling modules for browsers]]
* [[Modules/ScriptModules|On writing modules that also work as &lt;script&gt;s]]

== Related Documents ==

* Proposal to ECMA TC39: [http://docs.google.com/Doc?id=dfgxb7gk_34gpk37z9v&amp;hl=en Module System for ES-Harmony]
* Presentation to ECMA TC39: [http://docs.google.com/Presentation?docid=dcd8d5dk_0cs639jg8&amp;hl=en Modules]

== Related Discussion ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/6ad5c2c3b005cb3b/5a0f17e43d347673 RFC require.paths behaviour]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c3682135d72b1f8 Module meta data Proposal.] (resurrection of this discussion)</text>
    </revision>
  </page>
  <page>
    <title>Talk:RDBMS</title>
    <id>327</id>
    <revision>
      <id>1732</id>
      <timestamp>2009-10-28T13:40:09Z</timestamp>
      <contributor>
        <username>Optimus</username>
        <id>29</id>
      </contributor>
      <text xml:space="preserve">About placeholders: we could use a second parameter in the query method to send values for sanitizing, like: db.query(sql,values) so we could have two constructors, one for plain sql with embedded values, the other with parametrized and sanitizable values.

db.query(&quot;select * from customers where id=123&quot;)

or

db.query(&quot;select * from customers where id=?id&quot;,{id:123})


----

About resultsets: I believe sending column names in every row is a waste of bytes, we are already defining them in the meta section of the set, so no need to repeat them. Unless you want named objects in the result set for better manipulation like customer.name instead of customer[1] but we should give the coder the option to save bytes, specially for large resultsets over the wire.

Proposal: a setting to indicate if the resultset will be an object of objects (with meta) or a 2d array, like db.resultType=db.typeObject or db.typeArray</text>
    </revision>
  </page>
  <page>
    <title>Modules/Transport/A</title>
    <id>328</id>
    <revision>
      <id>1757</id>
      <timestamp>2009-11-23T18:06:51Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>moved [[AlternateModuleFormatRun]] to [[Modules/Transport/A]]:&amp;#32;organizing</comment>
      <text xml:space="preserve">'''STATUS: PROPOSED'''

== Alternate Module Format: run()==

This is a proposal for an alternate module format that is optimized for browser loading. The current difficulties with [Modules/1.1] as it relates to loading code in a browser:

In order to work in the browser, CommonJS 1.1 modules normally need to take one of two paths:

# Requires a synchronous XHR request to load the module and eval it, so that modules are loaded in the right order.
# Requires an intermediate process (like a server process or build step) to wrap the module in a function wrapper so the modules are not executed out of order.

Path #1 is a slower loading process that blocks the browser. Using eval() on the modules makes it hard to debug them in all browsers, and eval() is generally discouraged as a coding practice.

Path #2 requires an intermediary, extra machinery to develop modules. Depending on your environment choice, it means slower development. It also means a developer cannot just write some static files in an IDE and click refresh to load static files.

== Proposed Format ==

To fix these problems, an alternate format is suggested. This format is implemented by [http://code.google.com/p/runjs/wiki/RunJs RunJS], but it is open for discussion on the particulars. RunJS in some form is a likely candidate for a Dojo 2.0 code loader.

Choices made in the module format are optimized for/restricted by the browser environment, but they will work on in a server environment.

All modules are registered by calling a run() function. The name of the function is not set in stone, but a function entry point is needed. 

run() takes a variable amount of arguments, based on the scenario:

=== Running code that does not define a module ===
&lt;source&gt;
run(
    [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;], //the module names
    function(a, b, c) { //modules are passed in as arguments matching the array of module names.
        //do things with the a, b and c modules.
    }
);
&lt;/source&gt;

=== Defining a module ===

Defining a module is the same as running code that depends on a module, but the first argument is the module name, and the function should return an object that defines the module:

&lt;source&gt;
run(
    &quot;a&quot;,
    [&quot;b&quot;, &quot;c&quot;],
    function(b, c) {
        //Return an object or function to define the &quot;a&quot; module.
        return {
            color: &quot;blue&quot;
        };
    }
);
&lt;/source&gt;

An explicit module name is needed in order to properly identify the run call in the browser. Mike Wilson on the dojo-contributors list suggested that maybe the script tag's onload handler would be fired right after loading of a script, which would make it possible to not specify the module name. Unfortunately, Internet Explorer does not always fire onload events that match up to the script onload events. [http://www.tagneto.org/runjs/0.0.3/tests/scriptload/ See this test page].

So an explicit module name is needed. This is also beneficial when combining a few modules together into one file, for the purposes of optimized file loading.

If a module does not have any dependencies, and it is just a set of properties, then the run() call can be simplified:

&lt;source&gt;
run(
    &quot;a&quot;,
    {
        color: &quot;blue&quot;
    }
);
&lt;/source&gt;

A module can also define a function as its definition, but run() needs to know that it will return a Function, so Function is passed after the module name.

&lt;source&gt;
run(
    &quot;node&quot;,
    Function,
    [&quot;b&quot;, &quot;c&quot;],
    function(b, c) {
        return function(id) {
           if (typeof id == &quot;string&quot;) {
               return document.getElementById(id);
            } else {
               //already a DOM node, return it.
               return id;
            }
        }
    }
);
&lt;/source&gt;

Currently runjs also supports a format for loading i18n bundles. I will not document it here, since it is not strictly necessary for basic module syntax, but you can [http://code.google.com/p/runjs/wiki/RunJs read more about it here], in the &quot;Define an I18N Bundle&quot; section.

== Configuration Options ==

At the top level of code execution, a configuration object can be passed as the first option. This example shows it running in a browser:

&lt;source&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;scripts/run.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  run({
          baseUrl: &quot;/another/path/&quot;,
          paths: {
              &quot;some&quot;: &quot;some/v1.0&quot;
          },
          waitSeconds: 15,
          context: &quot;foo&quot;
      },
      [&quot;a.js&quot;, &quot;b.js&quot;, &quot;some.module&quot;, &quot;my.module&quot;],
      function() {
          //This function will be called when all the dependencies
          //listed above are loaded. Note that this function could
          //be called before the page is loaded. This callback is optional.
      }
  );
&lt;/script&gt;
&lt;/source&gt;

That example shows all the supported configuration options:

'''baseUrl''': the root path to use for all module lookups. So in the above example, &quot;my.module&quot;'s script tag will have a src=&quot;/another/path/my/module.js&quot;. If no baseUrl is passed in, the path to run.js is used as the baseUrl path.

'''paths''': allows configuration of some modules paths. Assumed to be relative to baseUrl. So for &quot;some.module&quot;'s script tag will have a src=&quot;/another/path/some/v1.0/module.js&quot;

'''waitSeconds''': The number of seconds to wait before giving up on loading a script. The default is 7 seconds. This is needed for the browser context, where loading of individual modules is done through async script tags.

'''context''': A name to give to a loading context. This allows run.js to load multiple versions of modules in a page, as long as each top-level run call specifies a unique context string. See Advanced Features below.

== Advanced Features ==

=== Multiversion support ===

As mentioned in Configuration Options, multiple versions of a module can be loaded in a page by using different &quot;context&quot; configuration options. Here is an example that loads two different versions of the alpha and beta modules (this example is taken from one of the test files):

&lt;source&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../run.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
run({
          context: &quot;version1&quot;,
          baseUrl: &quot;version1/&quot;
    },
    [&quot;run&quot;, &quot;alpha&quot;, &quot;beta&quot;,],
        function(run, alpha, beta) {
          log(&quot;alpha version is: &quot; + alpha.version); //prints 1
          log(&quot;beta version is: &quot; + beta.version); //prints 1

          setTimeout(function() {
                run([&quot;omega&quot;],
                  function(omega) {
                        log(&quot;version1 omega loaded with version: &quot; + omega.version); //prints 1
                  }
                );
          }, 100);
        }
);

run({
          context: &quot;version2&quot;,
          baseUrl: &quot;version2/&quot;
    },
    [&quot;run&quot;, &quot;alpha&quot;, &quot;beta&quot;],
    function(run, alpha, beta) {
      log(&quot;alpha version is: &quot; + alpha.version); //prints 2
      log(&quot;beta version is: &quot; + beta.version); //prints 2

      setTimeout(function() {
        run([&quot;omega&quot;],
          function(omega) {
            log(&quot;version2 omega loaded with version: &quot; + omega.version); //prints 2
          }
        );
      }, 100);
      }
);
&lt;/script&gt;
&lt;/source&gt;

=== Module Modifiers ===
The [http://code.google.com/p/runjs/wiki/RunJs RunJS documentation] describes a module modifier capability, that works by lazy loading modules that modify other modules. However, that feature is not required for this proposal.

== Tests ==

There are some tests that show a simple use case, a circular reference and multiversion support:

[http://www.tagneto.org/runjs/0.0.3/tests/ RunJS 0.0.3 tests]

== Contrasts with CommonJS modules ==

This format differs from current CommonJS files in the following ways:

# Requires modules to specify their name, because of browser constraints. It also makes bundling multiple modules in one file easier.
# Relative module names that start with &quot;.&quot; and &quot;..&quot; are not supported in the module names, given the first point.
# All dependencies are declared up top, and passed as arguments to a function that define the module.
# &quot;.&quot; is used in module names, however, it could be changed to &quot;/&quot; if that worked better for the community.</text>
    </revision>
  </page>
  <page>
    <title>TimsModuleThoughts</title>
    <id>329</id>
    <revision>
      <id>1748</id>
      <timestamp>2009-11-17T17:42:42Z</timestamp>
      <contributor>
        <username>Timjs</username>
        <id>28</id>
      </contributor>
      <text xml:space="preserve">Here are some snippets from my own notes on these subjects, having
experimented with current platforms looking for feasible common
ground.  These are of course my opinions, but because of limited time,
I’ve expressed them as matters-of-fact and probably out of order.
Thanks for bearing with me if you do.

Synchronicity
-----------------
async-to-sync is apples-to-oranges.  This might one day be expressed
and well-maintained as two separate copies of similar functionalities
(at twice the cost).  Not today, not in retrospect, and not by
accident.

Security
----------
Minimally-Practical vs. Secure is also apples-to-oranges.  Python’s
“restricted mode” abandoned its noble efforts likely because of too
many loopholes hidden by applying security in retrospect.  In all
practical ways, CommonJS  is in retrospect here.  (FWIW, I had a need
to explore sharing global state between modules/contexts, and am
currently using an inconspicuous security loophole across several
recent proto-platforms to accomplish this).

Thought Vehicles
---------------------
I see lots of bike-shaped stenciling on minivans, monster trucks, and
unicycles.
‘JavaScript’ is 40% ‘Java’ in terms of surface stenciling, but…

Separation of Concerns
----------------------------
Very little overlap happens by random chance.  How are these
different needs to be managed now and in the future, both in
discussion and in code?  Are current specifications catering to just
one or two of these?

* The CommonJS-as-a-language
* The Module Librarians
* The End-User Developers
* The Platform Builders
* The Module Authors

Going with the Flow
-------------------------
Current proposals, when viewed across the above concerns and across
existing codebases, remain suspicious and burdensome.  What other
approaches might better serve to maintain inter-project rapport while
revealing palatable solutions?  How about an incremental approach?

(1) vanilla ES3 module concept
No prescribed module identifiers or resolution mandates or paths, just
an embryonic, abstract mechanism for an End-User Developer to express
a need, and for a Module Author to similarly identify dependencies.
This is doable in useful ways through code comments.

(2) vanilla ES3+Core concept
With the addition of bare-minimum, majority concurred CommonJS APIs.
Both Synchronous and Asynchronous interfaces provided (fine if
emulated). Nothing dependent on any module or packaging system.  The
APIs expressed as superglobals, not module imports, with no choices
whatsoever for the End-User Developer to make here (beyond all or
nothing ES3+Core).

(3) An ES3+Core+Stdlib reference implementation
Basically ES3+Core+MoreES3s, with any MoreES3s’ synchronicity support
TBD.  Again superglobals used to reference the larger API, and just
one decision for a user to make.

(4) ??

Tangential Needs
---------------------
* DISCUSSION FORUM: ES3+xAPI *
To vet some good interfaces to already-common libraries like mysql/
memcache/etc.  This seems completely overlooked by CommonJS movement.
It needs to be addressed quickly to re-unify current divides and to
avoid new exponential divides across platforms.

* DISCUSSION FORUM: ES3+Synchronicity *
To coordinate async vs. sync standards any possible interop; to track
relatable efforts w/o confusing them with module or security
discussions.
------------------------

Again, just some thoughts from my notes offered with a grain of salt.

Best, -Tim 


Here is my wish list for a specification-backed module environment, somewhat organized by stakeholders.   It contemplates several atomic needs that have been obscured by recent pushes towards a one-size-fits-most &quot;require&quot; construct.

--------------------------------

1) Standard Library/Modules (ala Python) [@ CommonJS core ]
  a) The CommonJS-as-a-language standard libs and APIs
  b) The CommonJS-candidates &quot;de facto standard&quot; libs and APIs
  c) Pseudo-standard libs (ie: verticals)
  d) ...generalized module reuse, packaging, repositories

2) Local Module Management [@ Sysop / Code Librarian]
  a) Intrinsic modules (knowledge of globals, superglobals, &quot;require&quot;)
  b) Filesystem (organized by paths)
  c) COM registration (ie: Components.classes[&quot;@mozilla.org/preferences-service;1&quot;])
  d) URI mappings / registrations

3) Module Binding [@ End-user developer]
  a) _global_ (affects VM state)
  b) _static_ (deterministic / easy to lint / perhaps sync)
  c) _dynamic_ (non-deterministic / difficult to lint / perhaps async)
  d) _untrusted_ (sandboxed / preprocessed)

4) Module Loaders / Resolvers [@ VM / Platform developers]
  a) Versioning (dependency tracking, sniffing)
  b) De-duping (ie: load into VM/context just once)
  c) Unloading / Reloading modules
  d) Synthetic modules (adapters, submodules, autoloaders, etc.)
  e) Serialization (ie: VM-hibernate)

5) Module XYZ [ @ Module developers ]
  a) (expression of) dynamic dependencies (container agnostic)
  b) Static linking (for autonomy)
  c) Submodules (internal reuse, public/private conventions)
  d) etc.

-------------</text>
    </revision>
  </page>
  <page>
    <title>Talk:TimsModuleThoughts</title>
    <id>330</id>
    <revision>
      <id>1743</id>
      <timestamp>2009-11-11T03:20:19Z</timestamp>
      <contributor>
        <username>Timjs</username>
        <id>28</id>
      </contributor>
      <comment>Created page with 'What wonderfully-different JavaScript module systems to consider now, both in use and those presented in theory.  They represent such a large and diverse set of developer require…'</comment>
      <text xml:space="preserve">What wonderfully-different JavaScript module systems to consider now, both in use and those presented in theory.  They represent such a large and diverse set of developer requirements.  

The more I dive into the existing documentation and code of our predecessors (alongside current efforts), the more I see what at first blush appeared as avoidable fragmentation may be entirely to the contrary.

Beyond mere fragmentation, we seem headed towards outright exclusion!  “One of five” is not quite as common as I was thinking we’d be shooting for.

So, by what measurement are varying developer needs being ranked?  Voting with only a handful of constituents present seems difficult to validate.  Who are our constituents?
 
People (developers) don’t seem to commonly know about CommonJS yet, but have started arriving more regularly (if the mailing list is any indication).  They are often all too happy to share their wealth of knowledge and experience with us.  Many of these “late arrivals” are not late in any other sense -- having had their own module implementations in place for some time.

As I ponder these differences, I look for ways to distinguish between various approaches and for classification (ie: as potential candidates for bike-shedding, as legitimate apples-to-oranges, etc.).

Consider the following separation of concerns:

* The CommonJS-as-a-language
* The Module Librarians
* The End-User Developers
* The Platform Builders
* The Module Authors

The distances between these areas continue to grow.  I’m not sure why.

I do think that we need more representative abstractions to inform any reasonable set of specifications moving forward.</text>
    </revision>
  </page>
  <page>
    <title>Modules/Loaders</title>
    <id>331</id>
    <revision>
      <id>2767</id>
      <timestamp>2010-05-10T01:11:52Z</timestamp>
      <contributor>
        <username>Markm</username>
        <id>54</id>
      </contributor>
      <minor/>
      <comment>fixed link</comment>
      <text xml:space="preserve">'''STATUS: PROPOSALS'''

There are a variety of reasons why it should be possible to create new module systems from within a module system.  For one, such a system would make it possible to write test scaffolds for a module, where modules are injected around a module to simulate its interface with the rest of the world.   Also, the ability to load a module is a capability (in the [http://en.wikipedia.org/wiki/Object-capability_model object-capability programming sense]), but can be made a very safe capability by restricting the loadable modules to a carefully managed branch of a file system, by statically verifying that the content of the module is compliant with the CommonJS module specification, and by otherwise freezing and attenuating all other security hazards.  Doing all of these things guarantees that, if you instantiate a module system, the modules therein would only have the ability to perform computation, and manipulate the capabilities you deliberately inject into that system.  Another facet of exposing some of the internal mechanisms for finding, evaluating, and loading modules is that these facilities can be used to create more advanced module systems for domain specific languages.

== Proposals ==

* The [http://docs.google.com/Doc?docid=0AVWyIFBvIVXGZGZneGI3Z2tfMzRncGszN3o5dg&amp;hl=en|original proposal] for modules to ECMA TC39 in January 2009 included a module loader design.  The design in practical implementations has drifted and improved since.
* [[Modules/Loaders/A]] accompanied the original [[Modules/SecurableModules]] proposal, was ignored, and now has become obsolete.
* [[Modules/Loaders/B]]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Loaders/B</title>
    <id>332</id>
    <revision>
      <id>1755</id>
      <timestamp>2009-11-22T04:32:38Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

This is a proposal that specifies the interface of a Module Loader.  Implementations of the Module Loader interface can be made secure and provided to suspicious sandboxes: sandboxes with reduced capabilities (privileges that are exercisable only by containing a reference to a gate keeper).  The module loader interface is intended to be extensible in privileged sandboxes to:

# load shared objects and dynamic libraries
# load modules from formats other that CommonJS, like ObjectiveJ, or a hand-written module factory format, like a module transport format suitable also for script injection in browsers
# load modules that have different values in scope, dependency injection, like Jakefiles and QUnit tests, or a simulated browser scope

== Specification ==

=== 1. Modules ===

# The &quot;require&quot; function provided to modules may have a &quot;loader&quot; property that must be a module loader object.

=== 2. Module Loaders ===

# A module loader must have the &quot;resolve(id, baseId)&quot; function.  This function must return a top-level module identifier given any other valid CommonJS module identifier.  The given identifier may be relative to the base identifer or a top-level identifier itself, in which case the base identifier is ignored.  If the module loader supports module identifiers outside the CommonJS module identifier domain, resolve must return some form of canonical module identifier acceptable by require(canonicalId).
# A module loader must have a &quot;reload(topId)&quot; property function.  This function may force a module factory function to be created from the original medium.  The given identifier must be a value returned by &quot;resolve&quot;.
# A module loader must have a &quot;load(topId)&quot;.  The given identifier must be a value returned by &quot;resolve&quot;.  &quot;load&quot; returns a module factory function.

==== 2.1. Module File Loaders ====

# A module loader may have a &quot;find(topId)&quot; function that must return the canonical path of the file that can be loaded.
# A module loader may have an &quot;evaluate(text, fileName_opt, lineNo_opt)&quot; function that accepts the text of a JavaScript program and returns a module factory function.  The resultant factory function, when called may execute the program in a different, or deeply frozen JavaScript context.
# A module loader may implement the augmented reload interface, &quot;reload(topId, path_opt)&quot;, that accepts a hint of where to find the path to the file corresponding to the identifier.
# A module loader may implement the augmented load interface, &quot;load(topId, path_opt)&quot;, that accepts a hint of where to find the path to the file corresponding to the identifier.

==== 2.2. Module Multiplexer Loaders ====

# A module may implement &quot;canLoad(path)&quot; that accepts a path and returns whether the loader can load a module at that path with &quot;reload(id, path)&quot; and &quot;load(id, path)&quot;.  Acceptable grounds for determining whether the module can load the module include the extension or the content of the file.
# A module may have a &quot;loaders&quot; property that must be an Array of module loader objects, [canLoad(path), loader] pairs, [extension, loader] pairs, or any combination thereof.
## Any module loader providing a &quot;loaders&quot; property must respect in-place changes to the loaders property.
## The loaders property may not be writable.
## The loaders property may not be configurable.

=== 3. Module Factory Functions ===

# A module factory function accepts an object and returns nothing.
# The keys of the object accepted by a module factory function must be valid JavaScript identifiers.
# The object accepted by a module factory function may include a &quot;require&quot;, &quot;exports&quot;, and &quot;module&quot;, the values of which correspond to the free variables defined in a CommonJS module.

=== 4. Packaged Module Loaders ===

# A package may provide a module loader.
# package.json may have a &quot;loader&quot; property that may either be a loader identifier or a prioritized order of loader identifiers from high to low priority.
# A package system may construct and provide as &quot;require.loader&quot; a multiplexing loader from the collected loader identifiers in all installed packages, in which case it must construct the multiplexing loader's &quot;loader&quot; property with loader instances corresponding to each loader identifier in each &lt;tt&gt;package.json&lt;/tt&gt; in each package in package dependency order as established by a topological sort of all packages ordered from most dependent to least dependent.
# A loader instance corresponding to a module loader identifier must be constructed, without use of the &quot;new&quot; keyword, from the &quot;Loader&quot; function of the module file found by resolving resolving the module loader identifier as the path relative to the containing &lt;tt&gt;package.json&lt;/tt&gt;.</text>
    </revision>
  </page>
  <page>
    <title>AlternateModuleFormatRun</title>
    <id>333</id>
    <revision>
      <id>1758</id>
      <timestamp>2009-11-23T18:06:51Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[AlternateModuleFormatRun]] to [[Modules/Transport/A]]:&amp;#32;organizing</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Transport/A]]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Transport</title>
    <id>334</id>
    <revision>
      <id>2521</id>
      <timestamp>2010-03-25T04:23:20Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>/* Related Discussions */</comment>
      <text xml:space="preserve">There are a variety of ways to transport a module from a server to a browser.  However, the highest performance solutions available today involve script injection, which necessitates that the script arrange with the loader to call a particular function when it executes.

== Proposals ==

* [[Modules/Transport/A]] &quot;run&quot; system.
* [[Modules/Transport/B]] &quot;register&quot; system.
* [[Modules/Transport/C]] &quot;register&quot; system that uses positional args, explicit free variables.
* [[Modules/Transport/D]] &quot;register&quot; system that supports dependency injection and module sets.

== Prior Art ==

== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/129c8d4ec3244ec7 Module spec questions]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a1e8c041c40751ab/b0f7e0a647382d27?#b0f7e0a647382d27 Module Loaders]
* [http://groups.google.com/group/google-caja-discuss/browse_thread/thread/b060927ff5b47ffa/cd55027d5100588d Module loading discussion]
* [http://groups.google.com/group/commonjs/browse_thread/thread/3cab4886bb39c28e Updated Transport proposals]</text>
    </revision>
  </page>
  <page>
    <title>Binary/D</title>
    <id>335</id>
    <revision>
      <id>1809</id>
      <timestamp>2009-12-01T09:37:25Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>/* Relevant Discussions */ additional dicussions</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

This proposal, based on [[Binary/B]], defines types and methods for constructing, manipulating, and transcoding binary data in both mutable and immutable forms.  ByteString resembles its immutable text analog, String, and ByteArray resembles its mutable analog, Array.  Both types constrain their data to the byte domain and provide a memory-safe interface to underlying continguous, random-access byte collections.

An [http://spreadsheets.google.com/ccc?key=0An5phhxDkYDPdEFoTnlsRWgyc0x0WkpidURWT3pSYnc&amp;hl=en overview] of the supported types, methods, signatures, and corresponding return types is on Google Docs.

= Specification =

The &quot;binary&quot; top-level module must export ByteArray, ByteString, BitArray, BitString, Range, a charset support checking function, and the following alphabets for radix encodings.

; ByteString
: immutable, byte quantized
; ByteArray
: mutable, explicitly resizable, byte quantized
; BitString
: immutable, bit quantized
; BitArray
: mutable, explicitly resizable, bit quantized

; supports(charset String) Boolean
: returns whether the given charset is supported for all encoding, decoding, or transcoding operations.

; base8 String
: The base 8 alphabet, including padding, &quot;&lt;tt&gt;01234567=&lt;/tt&gt;&quot;.
; base16 String
: The base 16 alphabet, &quot;&lt;tt&gt;0123456789abcdef&lt;/tt&gt;&quot;.
; base32 String
: The default alphabet for base 32 encoding as specified by [http://www.crockford.com/wrmg/base32.html Doug Crockford]. See the toString(radix, alphabet) methods of ByteString and ByteArray.
; rfc4648 String
: An alternate alphabet for base 32 encoding as specified by [http://tools.ietf.org/html/rfc4648 RFC 4648]. See the toString(radix, alphabet)
; base64 String
: The base 64 alphabet, &quot;&lt;tt&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&lt;/tt&gt;&quot;.

== ByteString ==

A ByteString is an immutable, fixed-width representation of a C unsigned char (byte) array that does not implicitly terminate at the first 0-valued byte.

ByteString instances are comparable with the &lt;tt&gt;==&lt;/tt&gt; and &lt;tt&gt;===&lt;/tt&gt; operators based on equal order and respective values of their content.

=== Constructor ===

A ByteString function must exist.  When called as a function, it must return a byte string.  When constructed with &quot;&lt;tt&gt;new&lt;/tt&gt;&quot;, it must throw a TypeError.

&lt;source&gt;
ByteString();
assert.throws(function () {
    new ByteString();
}, TypeError);
&lt;/source&gt;

; ByteString()
: Construct an empty byte string.
; ByteString(byteString)
: Copies byteString.
; ByteString(byteArray)
: Use the contents of byteArray.  For performance, transparently to the layer specified here, the &quot;ByteArray&quot; may relinquish ownership of its underlying byte buffer and switch to a copy-on-write mode.
; ByteString(arrayOfNumbers)
: Use the numbers in arrayOfNumbers as the bytes.  Coerces Numbers to bytes by selecting their least significant eight bits.
; ByteString(string, charset)
: Convert a string. The ByteString will contain string encoded with charset.

=== Prototype Properties ===

; toByteArray() ByteArray
: Returns a byte for byte copy in a ByteArray.
: ''Note: for best performance, implementations should transfer ownership of the underlying buffer and flag the original owner to copy-on-write.''
; toByteArray(sourceCharset, targetCharset) ByteArray
: Returns this transcoded from the source charset to the target charset as a ByteArray.  The source and target charset are internally cast to String with the String constructor.
; toByteString() ByteString
: Returns this ByteString.
; toByteString(sourceCharset, targetCharset) ByteString
: Returns this transcoded from the source charset to the target charset as a ByteString.  The source and target charset are internally cast to String with the String constructor.
; toBitArray() BitArray
: Returns this as a BitArray by composing each byte, in consistent order, into groups of eight bits from most significant to least significant. &lt;code&gt;ByteArray([3]).toBitArray()&lt;/code&gt; and &lt;code&gt;BitArray([0, 0, 0, 0, 0, 0, 1, 1])&lt;/code&gt; are equivalent.
; toBitString() BitString
: Returns this as a BitString by composing each byte, in consistent order, into groups of eight bits from most significant to least significant. &lt;code&gt;ByteString([3]).toBitString() == BitString([0, 0, 0, 0, 0, 0, 1, 1])&lt;/code&gt;.
; toString() String
: Returns a debug representation like &quot;&lt;tt&gt;[ByteString 10]&lt;/tt&gt;&quot;, where 10 is the length this ByteString.
; toString(charset) String
: Decodes this ByteString according to the given character set and returns the String from the corresponding unicode points.  May throw a ValueError if the byte string is malformed or if any of the code points are out of the implementation's supported range.
; toString(radix, alphabet_opt) String
: encodes this as base 2, 8, 16, 32, or 64 with the given alphabet.  The default padding character is &quot;=&quot;, but can be overridden with an alternate padding character at the index of the radix in the alphabet.  Throws a &quot;ValueError&quot; if the alphabet is not the length of the radix or one larger than the radix.  The default alphabet corresponds to [http://www.crockford.com/wrmg/base32.html Doug Crockford's] base32 alphabet for human-error resistant binary communication.  &quot;rfc4648&quot; is an alternate alphabet.  These alphabets are exported by the &quot;binary&quot; module as &quot;base32&quot; and &quot;rfc4648&quot; respectively.
; toArray() Array
: Returns an Array containing the bytes as Numbers.
; valueOf(endian_opt) Number
: Returns this as a Number of the highest precision storable, treating these bytes as ordered in the given endianness.  endian may be omitted, undefined, &quot;LE&quot; or &quot;BE&quot;.  If omitted or undefined, defaults to &quot;BE&quot;.  If &quot;LE&quot;, these bytes are treated as little-endian, or least to most significant.  If &quot;BE&quot;, these bytes are treated as big-endian, albeit network-byte-order, most to least significant.
; toSource() String
: returns &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteString([])&lt;/tt&gt;&quot; for a null byte string or &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteString([0, 1, 2])&lt;/tt&gt;&quot; for a byte string of length 3 with bytes 0, 1, and 2.
; valueAt(offset_opt) Number
: Returns the byte at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; byteStringAt(offset_opt) ByteString
: Returns a unary (length 1) ByteString of the byte at the given offset. The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; indexOf(values, start_opt, stop_opt) Number
: Returns the index of the first occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; lastIndexOf(values, start_opt, stop_opt) Number
: Returns the index of the last occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; range(start_opt, stop_opt) Range
: Returns a Range object.  The value of stop defaults to the length of this.  The value of start defaults to 0.  Uses this for the Range's ref property.
; copy(target, targetStart, start, stop) ByteString
: Copies the Number values of each byte from this between start and stop to a target ByteArray or Array at the targetStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; slice(start_opt, stop_opt) ByteString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; substr(start_opt, length_opt) ByteString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substr String.prototype.substr]
; substring(start_opt, last_opt) ByteString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substring String.prototype.substring]
; concat(...) ByteString
: Returns a ByteString composed of itself concatenated with the given ByteString, ByteArray, and Array values.  Throws a TypeError if any of the arguments are not a ByteString, ByteArray, or Array of Numbers.  Coerces Numbers to bytes by selecting their least significant eight bits.
; join(array) ByteString
: Returns a ByteString of the ByteStrings, ByteArrays, Arrays of Numbers, or a combination thereof, delimited by this.  Arrays of Numbers are converted to ByteArrays.  Coerces Numbers to bytes by selecting their least significant eight bits.
; split(delimiter_opt, max_opt) Array
: Returns an Array of ByteStrings pared from the ByteString between strings of ByteStrings that match the given delimiter for up to the maximum number of delimiters, starting from the left.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.
; splitRight(delimiter_opt, max_opt) Array
: Returns an Array of ByteStrings pared from the ByteString between strings of ByteStrings that match the given delimiter for up to the maximum number of delimiters, starting from the right.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.
; Content
: an alias of ByteString, indicating that ByteString is the type of what &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; returns.

=== Internal Properties ===

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; ByteString
: Returns a unary (length 1) ByteString of the byte at the given offset.
; &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt;
: throws a TypeError.

=== Instance Properties ===

; length
: The length in bytes. Not &lt;nowiki&gt;[[Writable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.

== ByteArray ==

A ByteArray is a mutable, flexible (explicitly growable and shrinkable) representation of a C unsigned char (byte) array.

=== Constructor ===

A ByteArray function must exist.  Calling and constructing a ByteArray both return a new ByteArray instance.

&lt;source&gt;
ByteArray() instanceof ByteArray;
new ByteArray() instanceof ByteArray;
typeof ByteArray() === &quot;object&quot;;
typeof new ByteArray() === &quot;object&quot;;
&lt;/source&gt;

; ByteArray()
: New, empty ByteArray.
; ByteArray(length Number, fill_opt Number)
: New ByteArray of the given length, with the given fill number at all offsets.  The default filler is 0.
; ByteArray(byteArray)
: Copy byteArray.
; ByteArray(byteString)
: Copy contents of byteString.
; ByteArray(arrayOfBytes)
: Use numbers in arrayOfBytes as contents.  Coerces Numbers to bytes by selecting their least significant eight bits.
; ByteArray(string, charset)
: Create a &quot;ByteArray&quot; from a &quot;String&quot;, the result being encoded with charset.

=== Prototype Properties ===

; toByteArray() ByteArray
: Returns a byte for byte copy in a ByteArray.
: ''Note: for best performance, implementations should transfer ownership of the underlying buffer and flag the original owner to copy-on-write.''
; toByteArray(sourceCharset, targetCharset) ByteArray
: Returns this transcoded from the source charset to the target charset as a ByteArray.  The source and target charset are internally cast to String with the String constructor.
; toByteString() ByteString
: Returns a byte for byte copy in a ByteString.
: ''Note: for best performance, implementations should transfer ownership of the underlying buffer and flag the original owner to copy-on-write.''
; toByteString(sourceCharset, targetCharset) ByteString
: Returns this transcoded from the source charset to the target charset as a ByteString.  The source and target charset are internally cast to String with the String constructor.
; toBitArray() BitArray
: Returns this as a BitArray by composing each byte, in consistent order, into groups of eight bits from most significant to least significant. &lt;code&gt;ByteArray([3]).toBitArray()&lt;/code&gt; and &lt;code&gt;BitArray([0, 0, 0, 0, 0, 0, 1, 1])&lt;/code&gt; are equivalent.
; toBitString() BitString
: Returns this as a BitString by composing each byte, in consistent order, into groups of eight bits from most significant to least significant. &lt;code&gt;ByteString([3]).toBitString() == BitString([0, 0, 0, 0, 0, 0, 1, 1])&lt;/code&gt;.
; toString() String
: Returns a debug representation like &quot;&lt;tt&gt;[ByteArray 10]&lt;/tt&gt;&quot;, where 10 is the length this ByteArray.
; toString(charset) String
: Decodes this according to the given character set and returns the String from the corresponding unicode points.  May throw a ValueError if the byte string is malformed or if any of the code points are out of the implementation's supported range.
; toString(radix, alphabet_opt) String
: encodes this as base 2, 8, 16, 32, or 64 with the given alphabet.  The default padding character is &quot;=&quot;, but can be overridden with an alternate padding character at the index of the radix in the alphabet.  Throws a &quot;ValueError&quot; if the alphabet is not the length of the radix or one larger than the radix.  The default alphabet corresponds to [http://www.crockford.com/wrmg/base32.html Doug Crockford's] base32 alphabet for human-error resistant binary communication.  &quot;rfc4648&quot; is an alternate alphabet.  These alphabets are exported by the &quot;binary&quot; module as &quot;base32&quot; and &quot;rfc4648&quot; respectively.
; toArray() Array
: Returns an Array containing the bytes as Numbers.
; valueOf(endian_opt) Number
: Returns this as a Number of the highest precision storable, treating these bytes as ordered in the given endianness.  endian may be omitted, undefined, &quot;LE&quot; or &quot;BE&quot;.  If omitted or undefined, defaults to &quot;BE&quot;.  If &quot;LE&quot;, these bytes are treated as little-endian, or least to most significant.  If &quot;BE&quot;, these bytes are treated as big-endian, albeit network-byte-order, most to least significant.
; toSource() String
: returns &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteArray([])&lt;/tt&gt;&quot; for a null byte string or &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteArray([0, 1, 2])&lt;/tt&gt;&quot; for a byte string of length 3 with bytes 0, 1, and 2.
; valueAt(offset_opt) Number
: Returns the byte at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; byteStringAt(offset_opt) ByteString
: Returns a unary (length 1) ByteString of the byte at the given offset. The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; indexOf(values, start_opt, stop_opt) Number
: Returns the index of the first occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; lastIndexOf(values, start_opt, stop_opt) Number
: Returns the index of the last occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; range(start_opt, stop_opt) Range
: Returns a Range object.  The value of stop defaults to the length of this.  The value of start defaults to 0.  Uses this for the Range's ref property.
; copy(target, targetStart, start, stop) ByteArray
: Copies the Number values of each byte from this between start and stop to a target ByteArray or Array at the targetStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; copyFrom(source, sourceStart, start, stop) ByteArray
: Copies the Number values of each byte from a given ByteArray or ByteString into this from start to stop at the given sourceStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; fill(value, start_opt, stop_opt) ByteArray
: Fills each of the contained bytes with the given value (either a unary ByteString, ByteArray, or a Number) from the start offset to the stop offset.  start and stop must be numbers, undefined, or omitted.  If omitted, start is presumed to be 0.  If omitted, stop is presumed to beh the length of this ByteArray.  If omitted, &quot;value&quot; is presumed to be 0.  Returns this.
; splice(start_opt, stop_opt, ...values) ByteArray
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/splice Array.prototype.splice]
; slice(start_opt, stop_opt) ByteArray
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; split(delimiter_opt, max_opt) Array
: Returns an Array of ByteArrays pared from the ByteArrays between strings of ByteArrays that match the given delimiter for up to the maximum number of delimiters, starting from the left.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteArray.  The dlimiter is internally coerced to a ByteArray with the ByteArray constructor.
; splitRight(delimiter_opt, max_opt) Array
: Returns an Array of ByteArrays pared from the ByteArray between strings of ByteArrays that match the given delimiter for up to the maximum number of delimiters, starting from the right.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteArray.  The delimiter is internally coerced to a ByteArray with the ByteArray constructor.
; forEach(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach Array.prototype.forEach]
; every(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/every Array.prototype.every]
; some(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/some Array.prototype.some]
; map(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/map Array.prototype.map]
; Content
: an alias of Number, indicating that Number is the type of what &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; returns.

=== Internal Properties ===

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; Number
: Returns the Number value of a the byte at the given offset.
; &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt; Number
: Sets the byte value at the given offset.  Throws a ValueError if the index is beyond the current bounds of the byte array (byte arrays can be grown or shrunk by explicitly assigning a new length).

=== Instance Properties ===

; length
: The length in bytes. Not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.  Assigning to the length of a ByteArray causes the array to reallocate its underlying buffer to the given size, copying the original buffer up to the length of the new buffer if it is less, and filling all bytes beyond the length of the original buffer with the value 0.

== BitString ==

A &quot;BitString&quot; is an immutable, fixed-width representation of any number of bits (not necessarily a multiple of 8).

BitString instances are comparable with the &lt;tt&gt;==&lt;/tt&gt; and &lt;tt&gt;===&lt;/tt&gt; operators based on equal order and respective values of their content.

=== Constructor ===

A &quot;BitString&quot; function must exist.  When called as a function, it must return a bit string.  When constructed with &quot;new&quot;, it must throw a &quot;TypeError&quot;.

&lt;source&gt;
BitString();
assert.throws(function () {
    new BitString();
}, TypeError);
&lt;/source&gt;

; BitString()
: Construct an empty bit string.
; BitString(bitString)
: Copies bitString.
; BitString(bitArray)
: Use the contents of bitArray.
; BitString(array)
: construct a bit string where a bit is on if Boolean(value) for each value of the given value is true.
; BitString(bytes)
: Returns the given ByteString or ByteArray as a BitString by composing each byte, in consistent order, into groups of eight bits from most significant to least significant.

=== Prototype Properties ===

; toByteArray() ByteArray
: Returns a ByteArray composed of these bits in groups of eight from most to least significant.  Throws a ValueError if the length of this is not a multiple of 8.
; toByteString() ByteString
: Returns a ByteString composed of these bits in groups of eight from most to least significant.  Throws a ValueError if the length of this is not a multiple of 8.
; toBitArray() BitArray
: Returns this as a BitArray with equivalent respective bit values.
; toBitString() BitString
: Returns this BitString.
; toString() String
: Returns this represented as a String of 0s and 1s.
; toArray() Array
: Returns an Array containing the bits as the Numbers 0 and 1.
; valueOf() Number
: Returns this as a Number of the highest precision storable, treating these bits as ordered from most to least significant.  The result of valueOf must be equivalent to the Number arrived at by initializing an accumulator with 0 and iteratively multiplying the accumulator by 2 and adding the 0 or 1 Number value of each bit.
; toSource() String
: returns &quot;&lt;tt&gt;require(&quot;binary&quot;).BitString([])&lt;/tt&gt;&quot; for a null bit string or &quot;&lt;tt&gt;require(&quot;binary&quot;).BitString([0, 1, 0])&lt;/tt&gt;&quot; for a bit string of length 3 with bits 0, 1, and 0.
; valueAt(offset_opt) Number
: Returns the bit at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; indexOf(values, start_opt, stop_opt) Number
: Returns the index of the first occurence of of a bit or consecutive bits as represented by a Number, BitString, or BitArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; lastIndexOf(values, start_opt, stop_opt) Number
: Returns the index of the last occurence of of a bit or consecutive bits as represented by a Number, BitString, or BitArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; range(start_opt, stop_opt) Range
: Returns a Range object.  The value of stop defaults to the length of this.  The value of start defaults to 0.  Uses this for the Range's ref property.
; copy(target, targetStart, start, stop) BitString
: Copies the Number values of each bit from this between start and stop to a target BitArray or Array at the targetStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a BitArray or Array.  Returns this.
; slice(start_opt, stop_opt) BitString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; substr(start_opt, length_opt) BitString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substr String.prototype.substr]
; substring(start_opt, last_opt) BitString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substring String.prototype.substring]
; concat(...) BitString
: Returns a BitString composed of itself concatenated with the given BitString, BitArray, and Array values.  Throws a TypeError if any of the arguments are not a ByteString, ByteArray, or Array of Numbers.  Coerces nonzero Numbers to 1.
; join(array) BitString
: Returns a BitString of the BitStrings, BitArrays, Arrays of Numbers, or a combination thereof, delimited by this.  Arrays of Numbers are converted to BitArrays, so this function may throw a RangeError.
; split(delimiter_opt, max_opt) Array
: Returns an Array of BitStrings pared from the BitStrings between strings of BitStrings that match the given delimiter for up to the maximum number of delimiters, starting from the left.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty BitString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.
; splitRight(delimiter_opt, max_opt) Array
: Returns an Array of BitStrings pared from the BitStrings between strings of BitStrings that match the given delimiter for up to the maximum number of delimiters, starting from the right.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty BitString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.

=== Internal Properties ===

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; BitString
: Returns a unary (length 1) BitString of the byte at the given offset.

=== Instance Properties ===

; length
: The length in bits. Not &lt;nowiki&gt;[[Writable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.

== BitArray ==

A BitArray is a mutable, flexible (explicitly growable and shrinkable) representation of an ordered collection of bits, not necessarily with a length that is a multiple of 8.

=== Constructor ===

A BitArray function must exist.  Calling and constructing a BitArray both return a new BitArray instance.

&lt;source&gt;
BitArray() instanceof BitArray;
new BitArray() instanceof BitArray;
typeof BitArray() === &quot;object&quot;;
typeof new BitArray() === &quot;object&quot;;
&lt;/source&gt;

; BitArray()
: New, empty BitArray.
; BitArray(length Number, fill_opt Number)
: New BitArray of the given length, with the given fill number at all offsets.  The default filler is 0.
; BitArray(bitArray)
: Copy bitArray.
; BitArray(array)
: construct a bit string where a bit is on if Boolean(value) for each value of the given value is true.
; BitArray(bytes, endian)
: Returns the given ByteString or ByteArray as a BitArray by composing each byte, in consistent order, into groups of eight bits from most significant to least significant.

=== Instance Methods ===

; toByteArray() ByteArray
: Returns a ByteArray composed of these bits in groups of eight from most to least significant.  Throws a ValueError if the length of this is not a multiple of 8.
; toByteString() ByteString
: Returns a ByteString composed of these bits in groups of eight from most to least significant.  Throws a ValueError if the length of this is not a multiple of 8.
; toBitArray() BitArray
: Returns a copy of this.
; toBitString() BitString
: Returns this as a BitString with equivalent respective bit values.
; toString() String
: Returns this represented as a String of 0s and 1s.
; toArray() Array
: Returns an Array containing the bits as the Numbers 0 and 1.
; valueOf() Number
: Returns this as a Number of the highest precision storable, treating these bits as ordered from most to least significant.  The result of valueOf must be equivalent to the Number arrived at by initializing an accumulator with 0 and iteratively multiplying the accumulator by 2 and adding the 0 or 1 Number value of each bit.
; toSource() String
: returns &quot;&lt;tt&gt;require(&quot;binary&quot;).BitArray([])&lt;/tt&gt;&quot; for a null bit array or &quot;&lt;tt&gt;require(&quot;binary&quot;).BitArray([0, 1, 0])&lt;/tt&gt;&quot; for a bit array of length 3 with bits 0, 1, and 0.
; valueAt(offset_opt) Number
: Returns the bit at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; indexOf(values, start_opt, stop_opt) Number
: Returns the index of the first occurence of of a bit or consecutive bits as represented by a Number, BitString, or BitArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; lastIndexOf(values, start_opt, stop_opt) Number
: Returns the index of the last occurence of of a bit or consecutive bits as represented by a Number, BitString, or BitArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; range(start_opt, stop_opt) Range
: Returns a Range object.  The value of stop defaults to the length of this.  The value of start defaults to 0.  Uses this for the Range's ref property.
; copy(target, targetStart, start, stop) BitArray
: Copies the Number values of each bit from this between start and stop to a target BitArray or Array at the targetStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a BitArray or Array.  Returns this.
; copyFrom(source, sourceStart, start, stop) BitArray
: Copies the Number values of each bit from a given BitArray or BitString into this from start to stop at the given sourceStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; fill(value, start_opt, stop_opt) BitArray
: Fills each of the contained bits with the given value (either a unary BitString, BitArray, or a Number) from the start offset to the stop offset.  start and stop must be numbers, undefined, or omitted.  If omitted, start is presumed to be 0.  If omitted, stop is presumed to beh the length of this ByteArray.  If omitted, &quot;value&quot; is presumed to be 0.  Returns this.
; splice(start_opt, stop_opt, ...values) BitArray
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/splice Array.prototype.splice]
; slice(start_opt, stop_opt) BitArray
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; split(delimiter_opt, max_opt) Array
: Returns an Array of BitStrings pared from the BitStrings between strings of BitStrings that match the given delimiter for up to the maximum number of delimiters, starting from the left.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty BitString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.
; splitRight(delimiter_opt, max_opt) Array
: Returns an Array of BitArrays pared from the BitArray between strings of BitArrays that match the given delimiter for up to the maximum number of delimiters, starting from the right.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty BitArray.  The delimiter is internally coerced to a BitArray with the BitArray constructor.

=== Internal Properties ===

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; Number
: returns the Number value of a the bit at the given offset.
; &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt; Number
: Sets the bit value at the given offset.  Throws a ValueError if the index is beyond the current bounds of the bit array (bit arrays can be grown or shrunk by explicitly assigning a new length).

=== Instance Properties ===

; length
: The length in bits. Not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.  Assigning to the length of a bit array causes the array to reallocate its underlying buffer to the given size, copying the original buffer up to the length of the new buffer if it is less, and filling all bits beyond the length of the original buffer with the value 0.

== Range ==

A range object is a convenience for copying ranges from one ByteArray or ByteString to another ByteArray.

=== Constructor ===

; new Range({ref, start, stop})
: returns a Range object with the respective properties.

=== Prototype Properties ===

; copy(target, start_opt, stop_opt)
: generically calls &lt;codee&gt;this.ref.copy(target, this.start, Math.min(this.stop, this.start + target.length - start), start)&lt;/code&gt;.  The default value of stop is the target length.
; copyFrom(source, start_opt, stop_opt)
: generically calls &lt;code&gt;this.ref.copyFrom(source, this.start, Math.min(this.stop, this.start + source.length - start), start)&lt;/code&gt;.  The default value of stop is the source length.
; fill(value)
: generically calls &lt;code&gt;this.ref.fill(value, this.start, this.stop)&lt;/code&gt;
; splice(start_opt, stop_opt, ...values)
: generically calls &lt;code&gt;this.ref.splice.apply(this.ref, arguments)&lt;/code&gt;

== String ==

=== Prototype Properties ===

; toByteArray(charset) ByteArray
: Returns a ByteArray of these unicode code points as the corresponding bytes in the given character set.  Must throw an error if the given character set is not supported.
; toByteArray(radix, alphabet_opt, lookup_opt) ByteArray
: Returns a ByteArray of these characters encoded in base 2, 8, 16, 32, or 64.  If omitted or undefined, the alphabet defaults to the standard alphabet, or the Doug Crockford base 32 alphabet.  Optionally accepts a lookup object or function that normalizes ambiguous characters, as in the default behavior of Doug Crockford's base 32 encoding for the characters &quot;o&quot; to 0, and &quot;l&quot; to 1, and all lower-case letters to their upper-case analogs.  Must throw a ValueError if any contained character cannot be expressed in the requested radix's alphabet.
; toByteString(charset) ByteString
: Returns a ByteString of these unicode code points as the corresponding bytes in the given character set.  Must throw an error if the given character set is not supported.
; toByteString(radix, lookup_opt) ByteString
: Returns a ByteString of these characters encoded in base 2, 8, 16, 32, or 64.  If omitted or undefined, the alphabet defaults to the standard alphabet, or the Doug Crockford base 32 alphabet.  Optionally accepts a lookup object or function that normalizes ambiguous characters, as in the default behavior of Doug Crockford's base 32 encoding for the characters &quot;o&quot; to 0, and &quot;l&quot; to 1, and all lower-case letters to their upper-case analogs.  Must throw a ValueError if any contained character cannot be expressed in the requested radix's alphabet.
; valueAt(offset_opt) Number
: Returns the Unicode code point Number at the given offset.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; charCodes() Array
: Returns an array of Unicode code points for each respective contained character.

== Array ==

=== Prototype Properties ===

; toByteArray(charset)
: Returns a ByteArray of these unicode code points as the corresponding bytes in the given character set.  Must throw an error if the given character set is not supported.
; toByteString(charset)
: Returns a ByteString of these unicode code points as the corresponding bytes in the given character set.  Must throw an error if the given character set is not supported.

== Number ==

=== Prototype Properties ===

; toByteArray(width, endian_opt) ByteArray
: Returns this as a ByteArray of the given width, extending the most significant bits of a negative Number arithmetically.  The endian parameter may be omitted, undefined, &quot;LE&quot; or &quot;BE&quot;.  If omitted or undefined, the endian parameter defaults to &quot;BE&quot;.  If the endianness is &quot;BE&quot;, the bytes are ordered from most to least significant, and if the endianness is &quot;LE&quot;, they are ordered from least to most significant.  If this Number translates to bits that cannot be represented
; toByteString(width, endian_opt) ByteString
: Returns this as a ByteString of the given width, extending the most significant bits of a negative Number arithmetically.  The endian parameter may be omitted, undefined, &quot;LE&quot; or &quot;BE&quot;.  If omitted or undefined, the endian parameter defaults to &quot;BE&quot;.  If the endianness is &quot;BE&quot;, the bytes are ordered from most to least significant, and if the endianness is &quot;LE&quot;, they are ordered from least to most significant.  If this Number translates to bits that cannot be represented
; toBitArray(length) BitArray
: Returns this as a BitArray of the given length, extending the most significant bits of a negative Number arithmetically.  The bits are ordered from most to least significant.
; toBitString(length) BitString
: Returns this as a BitString of the given length, extending the most significant bits of a negative Number arithmetically.  The bits are ordered from most to least significant.

== General Requirements ==

All of the properties specified on prototypes are not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt; on instances.

Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &quot;us-ascii&quot;, &quot;utf-8&quot;, and &quot;utf-16&quot;.

Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.

Charsets are case insensitive.

Endianness arguments are case insensitive.

= Rationale =

The idea of using the particular ByteString and ByteArray types and their respective names originated with Jason Orendorff in the [http://groups.google.com/group/commonjs/msg/89808c05d46b92d0 Binary API Brouhaha] discussion.

== Structures ==

This proposal is not an object oriented variation on Perl, PHP, Python, or Ruby's pack, unpack, and calcsize with notions of inherent endianness, read/write head position, or intrinsic codec or charset information.  The objects described in this proposal are merely for the storage and direct manipulation of strings and arrays of byte data.  Some object oriented conveniences are made, but the exercise of implementing pack, unpack, or an object-oriented analog thereof are left as an exercise for a future proposal of a more abstract type or a 'struct' module (as mentioned by Ionut Gabriel Stan on [http://groups.google.com/group/commonjs/msg/592442ba98c6c70e the list]).  This goes against most mentioned [[../|prior art]].

== Encoding Methods ==

This proposal also does not provide separate member functions for any particular subset of the possible charsets, encodings, compression algorithms, or consistent hash digests that might operate on a byte string or array, for example &quot;toBase64&quot;, &quot;toMd5&quot;, or &quot;toUtf8&quot; are not specified.  Instead, &quot;toString&quot; accepts IANA charset names and radix numbers for charsets and encodings.  The intent is that implementations will opt to make this extensible by falling back to an &quot;encodings&quot; module and searching for modules by the same name and calling &quot;encode&quot; or &quot;decode&quot; exports on those modules if they exist.  (As supported originally by Robert Schultz, Davey Waterson, Ross Boucher, and tacitly myself, Kris Kowal, on the [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst First proposition] thread on the mailing list).  This proposal does not address the need for stream objects to support pipelined codecs and hash digests (mentioned by Tom Robinson and Robert Schultz in the same conversation).

== &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; and &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt; ==

This proposal also reflects both group sentiment and a pragmatic point about properties.  This isn't a decree that properties like &quot;length&quot; should be consistently used throughout the CommonJS APIs.  However, given that all platforms support properties at the native level (to host String and Array objects) and that byte strings and arrays will require support at the native level, pursuing client-side interoperability is beyond the scope of this proposal and therefore properties have been specified.  (See comments by Kris Zyp about the implementability of properties in all platforms, comments by Davey Waterson from Aptana about the counter-productivity of attempting to support this API in browsers, and support properties over accessor and mutator functions by Ionut Gabriel Stand and Cameron McCormack on the [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst mailing list]).

== Future Proofing ==

This proposal suggests that the specified data types should be exported by a &quot;binary&quot; module.  The intent is that eventually ECMAScript will specify native types to replace these, and these new types would be hosted as &quot;primordials&quot;, free variables available in all top-level scopes.  Because these types are specified to be exported by the &quot;binary&quot; module, there is some ambiguity of whether &quot;instanceof&quot; relationships would be maintained when references are passed among global contexts.  It would be valuable for these identities to be preserved.  For module systems that share a common global scope, this would suggest that the binary types should be patched into some commonly shared object, like the global scope, only if they do not yet exist.  That would permit the first, permissive context to construct the types, and all subsequent sandboxes to share them.  Secure sandboxes would have to make other accomodations.

== Memory Optimization ==

In contrast to Maciej Stachowiak's [https://mail.mozilla.org/pipermail/es-discuss/2009-November/010132.html proposal], there are no methods for explicitly managing the mutability of the underlying buffer.  Since it is possible for implementations to explicitly use ownership and copy-on-write flags, it is desirable to keep the memory management beneath the surface of JavaScript.  For example, with freezing semantics as proposed by Maciej, freezing a mutable byte array could produce an immutable byte string that usurps ownership of the original byte array's buffer, so there would be no need for allocation.  However, this would render the original byte array unusable, and all persisting references to that array would be broken and we would have to define failure modes for that object.  Alternately, the byte array and byte string could share the buffer.  The byte string would be guaranteed to not modify the content of the buffer, and if the owner of the original byte array were to perform a modifying operation on the byte array, the implementation could at that time incur the cost of copying the buffer.  Similar optimizations could be applied by all ByteString and ByteArray constructors and conversion functions.

== Genericity ==

In accordance with Daniel Friesen's [[Binary/C]], a high priority in this proposal was duck typing.

; a generic way to get a value in the Content type of a ByteArray, ByteString, or String
: &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
; a generic way to get the type of what is returned by &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; for ByteArray, ByteString, and String (Number, ByteString, and String respectively):
: Content
; a generic way to get a ByteString for the value at an offset for either ByteArray or ByteString
: byteStringAt(offset) ByteString
; a generic way to get a ByteArray for the value at an offset for either ByteArray or ByteString
: would have been wasteful to include since byte arrays are meant for assembling large byte buffers through copying data from other binary collections, not for allocation churn.
; a generic way to get a Number for the value at an offset for any ByteArray, ByteString, Array, or String
: valueAt(offset) Number
; a generic way to get an object of length one in the same type that contains just the value at a given offset for any ByteArray, ByteString, Array, or String
: slice(offset, offset + 1)

The following methods and properties are interoperable among ByteArray, ByteString, Array, and String:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* indexOf
* lastIndexOf
* slice

The following methods and properties are interoperable among ByteArray, ByteString, and String:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* Content
* valueAt
* join
* split
* splitRight
* indexOf
* lastIndexOf
* slice

The following methods and properties are interoperable between ByteArray and ByteString:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* Content
* valueAt
* byteStringAt
* indexOf
* lastIndexOf
* slice
* copy
* range

The following methods and properties are interoperable between ByteString and String:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* Content
* valueAt
* indexOf
* lastIndexOf
* slice
* substr
* substring

The following methods are interoperable between ByteArray and Array:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* indexOf
* lastIndexOf
* slice
* forEach
* every
* some
* map

== Idempotence ==

[[Binary/B]] had a &quot;decodeToString&quot; method and &quot;toString&quot; was required to be distinct, to avoid decoding and encoding hazards.  However, in keeping with the existing Number.prototype.toString(radix), for subjective aesthetic reasons having worked with prototypes of both, and because it easier to remember which way encoding and decoding go with &quot;toString&quot;, &quot;toByteString&quot;, and &quot;toByteArray&quot; than with &quot;encode&quot; and &quot;decode&quot;, this proposal eschews &quot;decodeToString&quot;.  This has the side effect of making the generic &quot;toByteString&quot; and &quot;toString&quot; methods idempotent for converting to and from a charset.  For example, if you receive an object that may be a ByteString or a String, but if it is a String it will need to be converted to a ByteString with a given charset, you can simply call &quot;toByteString&quot; with that charset, even repeatedly.  Likewise, if you receive a ByteString or a String and you need it to be a String, you can simply call &quot;toString&quot; with the desired charset, allowing a succession of adapters or decorators to make the conversion at any point along the way.

== Binary Object ==

This proposal omits the &quot;Binary&quot; type from [Binary/B] in anticipation that &quot;ByteArray&quot; and &quot;ByteString&quot; may become native types, in which case they would not be objects.  Presently, any &quot;String&quot; constructed with the &quot;new&quot; keyword is not a native string, but a &quot;boxed&quot; wrapper object for a String.

&lt;source&gt;
assert.equals(typeof &quot;&quot;, &quot;string&quot;);
assert.equals(&quot;&quot; instanceof String, false);
assert.equals(new String() instanceof String, true);
assert.equals(typeof new String(), &quot;object&quot;);
assert.equals(new String().slice() instanceof String, false);
assert.equals(Object.prototype.toString.call(&quot;&quot;), &quot;[object String]&quot;);
&lt;/source&gt;

This anticipates that the following would be true in an ECMA specification:

&lt;source&gt;
assert.equals(typeof &quot;&quot;, &quot;byteString&quot;);
assert.equals(&quot;&quot; instanceof ByteString, false);
assert.equals(new ByteString() instanceof ByteString, true);
assert.equals(typeof new ByteString(), &quot;object&quot;);
assert.equals(new ByteString().slice() instanceof ByteString, false);
assert.equals(Object.prototype.toString.call(&quot;&quot;), &quot;[object ByteString]&quot;);
&lt;/source&gt;

This means that this specification does not provide a facility for checking whether a reference is either of the binary types: byte string or byte array, any more than it provides a direct facility for checking whether an object is either a String or a ByteString.  However, it should serve in practice to call &quot;toByteString(charset)&quot; or &quot;toString(charset)&quot; to coerce either type to &quot;ByteString&quot; or &quot;String&quot;.  If the &quot;charset&quot; is not a useful argument, as it would be to convert a byte string to a byte string, this specification mandates that it be ignored.

This specification also deliberately avoids specifying whether the &quot;typeof&quot; operator on binary types should return &quot;object&quot; or some other value, and whether &quot;instanceof&quot; between a binary instance and its factory function returns true, as it is anticipated that this will be false in the future, but may be onerous to prevent from being true in the short term.  This is to permit CommonJS implementations to take a breadth of approaches to providing the type today.  This specification, however, does require constructing binary types with &quot;new&quot; to throw an error, in anticipation that that code pattern will eventually return a boxed type.

== Miscelaneous ==

&quot;ByteString&quot; does not implement &quot;toUpperCase&quot; or &quot;toLowerCase&quot; since they are not meaningful without the context of a charset.

Unlike the &quot;Array&quot;, the &quot;ByteArray&quot; is not variadic so that its initial length constructor is not ambiguous with its copy constructor.

The [[Binary/B]] proposal, at Ash Berlin's recommendation, had split methods on both ByteStrings and ByteArrays that accepted as their optional second argument, an object of options for both the number of delimiters to match, but whether to include the delimiter on the right side of each term, presumably including a terminal delimiter that would obviate an empty collection from being returned as the last value.  This has been left as an exercise for a byte reader stream's &quot;readLine(delimiter)&quot; method, so that this proposal's split and splitRight methods may more closely resemble their cousins on existing Strings in JavaScript and other languages.

The &quot;join&quot; methods on &quot;ByteArray&quot; and &quot;ByteString&quot; differ from what you would expect in JavaScript based on Array joins, in a way that will be familiar and probably upsetting coming from Python.  The delimiter is the left side of the expression.  This is because the Array joining method can not be practically extended to determine whether to return a String, ByteString, or ByteArray based on the types of all of the values it contains.  It is far more practical to multi-plex the return type based on the type of the left hand side of the expression.

This proposal calls for extensions to existing types. This does not mean that this specification encourages the practice of monkey-patching. Ideally, this proposal would be implemented at the very lowest levels of each engine, augmenting the existing primordial types before a line of JavaScript is evaluated. However, this specification does not prevent implementations from performing these augmentations either as a stop-gap or as standard practice (as in V8) in JavaScript as part of the engine's bootstrapping process.  This suggests that it is not the responsibility of the &quot;&lt;tt&gt;binary&lt;/tt&gt;&quot; module to construct these types, but merely to host them.  If multiple modules systems share the same primordial objects, the instantiation of the binary module should not cause these types to be recreated or to not be referentially identical.

The &quot;Content&quot; property begins with a capital letter to distinguish it as a factory method like the constructor function to which it always refers, albeit ByteString, ByteArray, or Number.  To date, this remains a point of discussion.  Daniel Friesen's proposal [[Binary/C]] uses the name &quot;contentConstructor&quot;.

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a8d3a91af37fd355 ByteArray: byteAt method]
* [http://groups.google.com/group/commonjs/browse_thread/thread/45190ac89d7b422a Binary/B Extension Proposals and Implementation Notes]
* [http://groups.google.com/group/commonjs/browse_thread/thread/98c51580a47e855e Binary D ready for review]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f609c72c9749e2c3 Binary/D Draft 2]

= Todo =

# chronicle the rationale for bit and byte types supported at this architecture layer
# write a section on what kinds of additional requirements could be expected in a future revision of the specification</text>
    </revision>
  </page>
  <page>
    <title>JSGI/Level0/A/Draft2</title>
    <id>336</id>
    <revision>
      <id>2762</id>
      <timestamp>2010-05-05T21:41:45Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>/* body */ Maybe I'll install Cite later...</comment>
      <text xml:space="preserve">JSGI Level 0/A Draft 2 Proposal (AKA JSGI 0.3)

== Philosophy ==

* Straightforward but convenient mapping to HTTP and existing gateway interface conventions
* Suitable for extension with a defined mechanism for Extension Proposals
* Cosmetic modifications more inline with JavaScript conventions and idioms

=== Principles ===

* Discourage duplicate data in request and response objects
* Optimize for the Application developer, not the Server or Middleware developer
* Adhere to HTTP semantics wherever possible

== Specification ==

=== Application ===

A JSGI Application is a JavaScript Function which takes exactly one argument, the [[#Request|Request]] as a JavaScript Object, and returns its [[#Response|Response]] as a JavaScript Object containing three required attributes: '''status''', '''headers''' and '''body''' ('''DL: should we mention `then` here?''').

=== Middleware ===

JSGI Middleware are JSGI Applications that can call other JSGI Applications. Middleware can be stacked up into a call chain to provide useful services to Requests and Responses.

=== Server ===

A JSGI Server is the glue that connects JSGI Applications to HTTP request and response messages. ('''DL: this definition sucks, but Server should be defined...ideas?''')

=== Request ===

The request environment MUST be a JavaScript Object representative of an HTTP request. Applications are free to modify the Request.

==== Required Keys ====

The Request is required to include these keys:

* '''.method''': The HTTP request method, such as &quot;GET&quot; or &quot;POST&quot;. Request's method cannot be undefined and so MUST be present with a value of an UPPERCASE string.
* '''.scriptName''': The initial portion of the request URL's &quot;path&quot; that corresponds to the Application object, so that the Application knows its virtual &quot;location&quot;. This MAY be an empty string, if the Application corresponds to the &quot;root&quot; of the Server. ''Restriction: if non-empty `scriptName` MUST start with &quot;/&quot;, MUST NOT end with &quot;/&quot; and MUST NOT be decoded.''
* '''.pathInfo''': The remainder of the request URL's &quot;path&quot;, designating the virtual &quot;location&quot; of the Request's target within the Application. This may be an empty string, if the request URL targets the Application root and does not have a trailing slash. ''Restriction: if non-empty `pathInfo` MUST start with &quot;/&quot; and MUST NOT be decoded.''
* '''.queryString''': The portion of the request URL that follows the first &quot;?&quot;, if any. ''Restriction: MAY be an empty string but `queryString` key MUST NOT be undefined.''
* '''.host''': The portion of the request URL that follows the `scheme`. ''Restriction: MUST be non-empty String, MUST NOT contain a colon or slash.'' ''Note: when combined with `scheme`, `port`, `scriptName`, `pathInfo`,  and `queryString` this variable can be used to complete the URL. However Request's `headers.host`, if present, should be used in preference to `host` for reconstructing the request URL.'' '''DL: not according to RFC 2616: If Request-URI is an absoluteURI, the host is part of the Request-URI. Any Host header field value in the request MUST be ignored.'''
* '''.port''': Representative of the Request port. If `host` is followed by a colon this is all digits following this colon. If not present in the request URL `port` can be derived from the `scheme`. ''Restriction: MUST NOT be undefined and MUST be an integer.
* '''.scheme''': URL scheme (per [http://www.ietf.org/rfc/rfc1738.txt RFC 1738]). &quot;http&quot;, &quot;https&quot;, etc.
* '''.input''': The request body. ''Requirement: MUST be an input stream.''

* '''.headers''': Variables corresponding to the client-supplied HTTP request headers are stored in the `headers` object. The presence or absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request. All keys in the `headers` object MUST be the lower-case equivalent of the request's HTTP header keys. ''See: [[#Examples|example requests]] for more details.''

* '''.jsgi''': The Request MUST include these JSGI-specific variables in a `jsgi` key:
** '''.jsgi.version''': The Array [0,3], representing this version of JSGI.
** '''.jsgi.errors''': Stream for Application errors ('''anyone have better wording?'''). ''Requirement: MUST be an output stream.'' ('''MOB: shouldn't this also be moved to the top level?''')
** '''.jsgi.multithread''': truthy if the Application object may be simultaneously invoked by another thread in the same process, otherwise falsey.
** '''.jsgi.multiprocess''': truthy if an equivalent Application object may be simultaneously invoked by another process, otherwise falsey.
** '''.jsgi.runOnce''': truthy if Server expects (but does not guarantee) that the Application will only be invoked this one time during the life of its containing process, otherwise falsey. ''Note: normally, this will only be true for a server based on CGI (or something similar).''
** '''.jsgi.cgi''': CGI version Array in [major, minor] form if Server is implemented atop CGI, otherwise falsey.
** '''.jsgi.ext''': Defined in the [[#Extensions|Extensions]] section.

* '''.env''': The top level of the Request object SHOULD only consist of the keys specified above. Servers and Middleware MAY add additional information the `env` key. Servers are encouraged to add any additional relevant data relating to the Request in a key in the `env` object. ''Requirements: MUST be an object.''

==== Optional Keys ====

The Request MAY contain contain these keys:
* '''.authType''': Corresponds to the CGI key AUTH_TYPE
* '''.pathTranslated''': Corresponds to the CGI key PATH_TRANSLATED
* '''.remoteAddr''': Corresponds to the CGI key REMOTE_ADDR
* '''.remoteHost''': Corresponds to the CGI key REMOTE_HOST
* '''.remoteIdent''': Corresponds to the CGI key REMOTE_IDENT
* '''.remoteUser''': Corresponds to the CGI key REMOTE_USER
* '''.serverSoftware''': Corresponds to the CGI key SERVER_SOFTWARE

('''DL: added the above keys (everything spec'd by CGI) to effectively ''reserve'' them in the top level request so that we can safely extend the JSGI spec without worrying about conflicts -- is this alright?''')

=== Response ===

Applications MUST return a JavaScript Object representative of an HTTP response:

==== status ====

The status MUST be a three-digit integer ([http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 RFC 2616 Section 6.1.1])

==== headers ====

MUST be a JavaScript object containing key/value pairs of Strings or Arrays. Servers SHOULD output multiple headers for `header` values supplied as Arrays. All keys MUST be lower-case. The `headers` object MUST NOT contain a `status` key and MUST NOT contain key names that end in `-` or `_`. It MUST contain keys that consist of letters, digits, `_` or `-` and start with a letter. Header values MUST NOT contain characters below 037.
* '''content-type''': There MUST be a `content-type` header key, except when the [#status Status]  is 1xx, 204 or 304, in which case `content-type MUST NOT be present.
* '''content-length''': There MUST NOT be `content-length` header key when the Status is 1xx, 204 or 304.

==== body ====

MUST be an object which responds to `forEach` and MUST only yield objects which have a toByteString method (including Strings and Binary&lt;ref&gt;Binary, as defined in [[Binary/D]] ('''DL: or whatever binary module is ratified''') objects&lt;/ref&gt;).

If `body` responds to close, it SHOULD be called after iteration.

== Conventions ==

To facilitate interoperability among JSGI Applications and Servers, Applications SHOULD be added as the `app` key on their module's `exports` object.

Upon initialization Servers MUST provide an object representative of every Request's `jsgi` object as a second argument to the `app` function. ('''AB: this needs more detail''')

=== Extensions ===

This specification can be extended by JSGI Extension Proposals. Ratification of extensions occurs by the standard [[Process|CommonJS process]]. An Extension Proposal MUST specify a key String and version Array to be placed in `request.jsgi.ext` to be ratified.



----

'''The following sections of this specification are non-normative.'''

----



== Rationale ==

Multiple header values with the same key should now be provided as an Array value. JSGI 0.2 specified this as a string containing `\n` but working with them as arrays is easier and should a middleware mistakenly concatenate to the header value Array's toString will do the right thing [http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 according to RFC 2616] and coerce header value into a comma-joined string.

Header casing is specified as lower-case to aid interoperability amongst middleware. While case is irrelevant according to RFC 2616 Servers MAY correct the case of Response header keys or expose this functionality to Applications.

('''DL: notes about potential CGI information loss, particularly with regard to decoded paths, headers actually containing an _ and multiple headers, as well as the security implications (X_FORWARDED_FOR/x-forwarded-for''')

(AB: If server on top of CGI and undecoded PATH_INFO available, we should note that servers should use it)

('''DL: there should be a note about forEach for sync streaming and a promise's progressCallback for async streaming, which has been the subject of confusion. Any other areas that deserve special explanation?''')

== Changes from [http://jackjs.org/jsgi-spec.html JSGI 0.2] ==

== Specification changes ==

* Added definitions for Middleware and Server
* Added specification for Extensions

=== Request changes ===

* Explicitly override CGI-like variables:

; Required
: env.REQUEST_METHOD =&gt; request.method
: env.SERVER_PROTOCOL =&gt; request.version, parsed &quot;HTTP/1.1&quot; =&gt; [1, 1]
: env.SERVER_NAME =&gt; request.host
: env.SERVER_PORT =&gt; request.port, parsed
: env.SCRIPT_NAME =&gt; request.scriptName, MUST NOT be decoded, MUST NOT end in slash
: env.PATH_INFO =&gt; request.pathInfo, MUST NOT be decoded
: env.QUERY_STRING =&gt; request.queryString

; Optional
: env.AUTH_TYPE =&gt; request.authType
: env.PATH_TRANSLATED =&gt; request.pathTranslated ''DL: this is duplicate data, should we forbid?''
: env.REMOTE_ADDR =&gt; request.remoteAddr ''DL: remoteAddress?''
: env.REMOTE_HOST =&gt; request.remoteHost
: env.REMOTE_IDENT =&gt; request.remoteIdent ''DL: remoteIdentity?''
: env.REMOTE_USER =&gt; request.remoteUser
: env.SERVER_SOFTWARE =&gt; request.serverSoftware

; Forbidden
: env.CONTENT_TYPE: exists in request.jsgi.headers[&quot;content-type&quot;] if applicable
: env.CONTENT_LENGTH: exists in request.jsgi.headers[&quot;content-length&quot;] if applicable
: env.GATEWAY_INTERFACE: exists in request.jsgi.cgi if applicable

* Allow request.headers[&quot;content-length&quot;] and request.headers[&quot;content-type&quot;] and disallow env.CONTENT_LENGTH and env.CONTENT_TYPE
* Add request.env object for all non-specified keys
* Move env[&quot;jsgi.url_scheme&quot;] to request.scheme
* Move env[&quot;jsgi.input&quot;] to request.input

==== request.jsgi ====

* Move env[&quot;jsgi.*&quot;] to request.jsgi.*
* Added request.jsgi.ext required object
* Move request.jsgi.run_once to request.jsgi.runOnce ('''DL: Mike Wilson suggested this be camelCase like everything else and noone objected -- speak up if you don't like''')
* Server SHOULD add request.jsgi.async key if Server supports returning response as promise
* Add request.jsgi.cgi key if Server sits atop CGI
** Note CGI security deficiencies, e.g. X_FORWARDED_FOR/x-forwarded-for
* Bump request.jsgi.version to [0,3]

==== request.headers ====

* Move env[&quot;HTTP_*&quot;] to request.headers.* (eliminating the &quot;HTTP_&quot; prefix)
* Header keys MUST be lowercase but otherwise SHOULD be equivelent to the HTTP request headers
** Compliant Servers MUST ''unmangled'' header keys if CGI (replace(/_/g, &quot;-&quot;))
* Servers MAY provide request header values as Array of Strings if HTTP request contains multiple headers with the same key '''(DL: should this be SHOULD? It's impossible with CGI -- any ideas?)'''

==== request.env ====

* All custom keys added to the request by Servers or Middleware MUST be placed in request.env

=== response ===

* Specify status, headers and body keys MUST be present in Response OR Response must contain a '''then''' function that, when resolved, returns an object with all three keys
* Middleware SHOULD preserve additional keys supplied in response object if not intending to supersede it

==== response.status ====

* No changes

==== response.headers ====

* The header MUST be a JavaScript Object containing values which are Objects that respond to toString
* Keys MUST be in lower-case form
* If a header value responds to a forEach method Server SHOULD provide multiple HTTP headers with values corresponding to toString

==== response.body ====

* If the Body responds to '''close''' it MUST be called after iteration with the same arguments passed to forEach

=== Conventions ===

* Applications: SHOULD be added as the `app` key on their module's `exports` object for interoperability.
* Servers: To allow Applications on Servers with unsupported features to fail fast servers must now supply the contents of the `jsgi` key as a second argument to the Application.

== Examples ==

=== Request ===

&lt;pre&gt;
{
    version: [1, 1], // parsed HTTP version ~ &quot;HTTP/1.1&quot;
    method: &quot;GET&quot;,
    headers: { // HTTP headers, lowercased but otherwise unmangled
        host: &quot;jackjs.org&quot;,
        &quot;user-agent&quot;: &quot;Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3&quot;,
        accept: &quot;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&quot;,
        &quot;accept-language&quot;: &quot;en-us,en;q=0.5&quot;,
        &quot;accept-encoding&quot;: &quot;gzip,deflate&quot;,
        &quot;accept-charset&quot;: &quot;ISO-8859-1,utf-8;q=0.7,*;q=0.7&quot;,
        &quot;keep-alive&quot;: &quot;300&quot;,
        connection: &quot;keep-alive&quot;,
        &quot;if-modified-since&quot;: &quot;Fri, 04 Sep 2009 07:47:22 GMT&quot;,
        &quot;cache-control&quot;: &quot;max-age=0&quot;
    },
    input: (new InputStream), // request body stream
    scheme: &quot;http&quot;,
    host: &quot;jackjs.org&quot;,
    port: 80,
    env: { // this is the place where Server and Middleware put keys
        juice: {
            version: [0, 1]
        },
        jack: {
            request: null
        }
    },
    jsgi: {
        version: [0, 3],
        errors: (new OutputStream),
        multithread: false,
        multiprocess: true,
        runOnce: false,
        async: true,
        cgi: false // [1, 1] if CGI/1.1
    }
}
&lt;/pre&gt;

('''DL: I'd like to have at least a simple response and Async Extension promise response example''')

== Acknowledgements ==

This specification is adapted from the [http://rack.rubyforge.org/doc/files/SPEC.html Rack specification] written by Christian Neukirchen.
Some parts of this specification are adopted from [http://www.python.org/dev/peps/pep-0333/ PEP333: Python Web Server Gateway Interface v1.0].
Special thanks to the many contributors of the CommonJS group.</text>
    </revision>
  </page>
  <page>
    <title>User:Mdaniel</title>
    <id>337</id>
    <revision>
      <id>1812</id>
      <timestamp>2009-12-01T20:39:02Z</timestamp>
      <contributor>
        <username>Mdaniel</username>
        <id>45</id>
      </contributor>
      <comment>initial revision</comment>
      <text xml:space="preserve">== Matthew L Daniel ==
http://MatthewDaniel.com/</text>
    </revision>
  </page>
  <page>
    <title>JSGI/Extension/Request</title>
    <id>338</id>
    <revision>
      <id>1824</id>
      <timestamp>2009-12-04T23:41:30Z</timestamp>
      <contributor>
        <username>Deanlandolt</username>
        <id>15</id>
      </contributor>
      <comment>added placeholder</comment>
      <text xml:space="preserve">This is a placeholder for a strawman for a JSGI Request object wrapper (formerly referred to as JSGI Level 1).

.jsgi.ext.request = [0,1]</text>
    </revision>
  </page>
  <page>
    <title>Reactor</title>
    <id>339</id>
    <revision>
      <id>1842</id>
      <timestamp>2009-12-11T01:53:00Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <comment>Replaced content with 'Event Queue Module specification for the Reactor pattern

'''STATUS: PROPOSAL'''

The event queue module exists for the purpose of maintaining an event queue and running an e…'</comment>
      <text xml:space="preserve">Event Queue Module specification for the Reactor pattern

'''STATUS: PROPOSAL'''

The event queue module exists for the purpose of maintaining an event queue and running an event loop based on that queue.

== Proposals ==

# [[Reactor/A]] Proposal A</text>
    </revision>
  </page>
  <page>
    <title>Reactor/A</title>
    <id>340</id>
    <revision>
      <id>1855</id>
      <timestamp>2009-12-11T16:55:39Z</timestamp>
      <contributor>
        <username>Okito</username>
        <id>50</id>
      </contributor>
      <minor/>
      <comment>/* Functions */</comment>
      <text xml:space="preserve">Event Queue Module specification for the Reactor pattern

'''STATUS: PROPOSAL'''

== Specification ==
The event queue module exists for the purpose of maintaining an event queue and running an event loop based on that queue.

The &quot;reactor&quot; top-level module must export enterEventLoop, enqueue, shutdown, hasPendingEvents, processNextEvent, and optionally getNextEvent.

=== Functions ===

; enterEventLoop(onIdle) 
: Enters the event loop, sequentially processing each event in the queue and blocking (waiting) for events when the queue is empty. This should continue to loop until shutdown is called and all the events are processed. If a function is provided as the first parameter, it should be called after any event finishes processing and the queue is empty.

; enqueue(task, priority) boolean
: Adds a new event to the event-queue. The first parameter, task, should be a function that will be added to the queue and then executed when its is removed from the queue. The second parameter is a number that indicates the requested priority of the task. The handling of the priority parameter is implementation specific and it may be ignored. This returns true if the task was successfully added the queue, otherwise it should return false (generally only the case if the event loop is shutting down).

; shutdown()
: This makes a request to exit the event loop. The event loop will continue processing all the events in the queue, but the enqueue operation should not allow any events to be added. One the event loop has processed all the events in the event queue, enterEventLoop should return.

; hasPendingEvents()
: Determines whether or not the event-queue has events that are ready to be processed. Returns true if there are pending events at the time the function was called.

; processNextEvent(mayWait)
: Processes the next pending event. If there aren't any pending events, this method may wait -- depending on the value of the mayWait parameter -- until an event is enqueued in this queue. This method is re-entrant. If the mayWait parameter is true, this method blocks until an event is available to process if the event queue is empty. If false, this method returns immediately if the queue is empty. This returns true if an event was processed, or false if there were no pending events.

; getNextEvent()
: If implemented, this returns the next event function to be processed, removing it from the queue. this method blocks until an event is available if the event queue is empty.

; timer setTimeout(func, delay, context, ...param)
: Schedules a one shot timer to execute the passed function after &quot;delay&quot; milliseconds.  If &quot;context&quot; is passed, the function will be bound to it when invoked.  Any additional parameters should be curried and passed as params to the function as well.  This method does not offer a real-time guarantee.  The passed function will execute eventually but it may be delayed if the process is busy executing other code in the mean time.  Returns an opaque object referencing the scheduled timer.

; void clearTimeout(timer)
: Removes a previously scheduled one-shot timer from the event loop.  If the passed timer object is not valid or if it has already fired, this function has no effect.

; timer setInterval(func, delay, context, ...param)
: Works just like setTimeout() with the same params except the function will execute periodically every &quot;delay&quot; milliseconds until the timer is explicitly cancelled. 

; void clearInterval(timer)
: Removes a previously scheduled interval timer from the event loop.  If the passed timer is not a valid interval timer or if it has already been cancelled, this function has no effect.

== Open Issues ==

* If a timeout timer or an interval timer is scheduled, should the process exit when the main code finishes executing?  If so, how do we blend that with the event-drive API of the browser or node.js where you run an implicit event loop?  A generic wait() function won't work because you can't actually block in the browser. [Charles Jolley]

* The browser does not support explicit control over it's event loop.  This means you pretty much cannot implement any of the above methods except for enqueue(), setTimeout(), clearTimeout(), setInterval(), and clearInterval().  Perhaps the loop control methods should be made optional? [Charles Jolley]</text>
    </revision>
  </page>
  <page>
    <title>Worker</title>
    <id>341</id>
    <revision>
      <id>1848</id>
      <timestamp>2009-12-11T02:12:37Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <comment>Created page with 'Worker Module Specification  '''STATUS: PROPOSAL'''  The worker module exists for the purpose of creating workers, concurrent shared nothing processes/threads, that can communica…'</comment>
      <text xml:space="preserve">Worker Module Specification

'''STATUS: PROPOSAL'''

The worker module exists for the purpose of creating workers, concurrent shared nothing processes/threads, that can communicate with other workers with message passing.

== Proposals ==

The 'worker' module must export Worker, SharedWorker, and optionally name. Worker and SharedWorker are constructors that follow the W3C/HTML5 WebWorkers specification:
http://dev.w3.org/html5/workers/
The primary difference is that script names should follow CommonJS module naming mechanism, and should be resolved using the same mechanism the 'require' function. The 'worker' module may also export a 'name' property that indicates the name of the current worker (if started as a named SharedWorker).</text>
    </revision>
  </page>
  <page>
    <title>Talk:Modules/1.1</title>
    <id>342</id>
    <revision>
      <id>1858</id>
      <timestamp>2009-12-15T00:25:05Z</timestamp>
      <contributor>
        <username>IsaacSchlueter</username>
        <id>52</id>
      </contributor>
      <comment>link to setExports discussion</comment>
      <text xml:space="preserve">setExports function discussion: http://groups.google.com/group/commonjs/browse_thread/thread/11c6f25c46b3837b</text>
    </revision>
  </page>
  <page>
    <title>Modules/SetExports</title>
    <id>343</id>
    <revision>
      <id>2821</id>
      <timestamp>2010-06-12T01:26:03Z</timestamp>
      <contributor>
        <username>Jhuni</username>
        <id>106</id>
      </contributor>
      <text xml:space="preserve">'''STATUS: PROPOSAL, DISCUSSION'''

== Specification ==

This proposal amends [[Modules/1.1]].

* The &quot;module&quot; free variable exposes a &quot;setExports&quot; function.
* This function sets the module's export to the first argument, and returns it.
* To prevent problems with inconsistencies in the case of circular dependencies, if the module has already been required by another module, calling module.setExports() must throw an Error.

== Relevant Discussions ==

* http://groups.google.com/group/commonjs/browse_thread/thread/11c6f25c46b3837b/c208f92d98c4f72c

== Show of Hands ==

Those in favor of incorporating this proposal in the next minor revision of Modules/1:

* Isaac Schlueter
* Dean Landolt
* Kevin Dangoor
* Kris Zyp
* Francisco Tolmasky
* Jhuni

Those against:

* Mark S. Miller -- keep it simple. Why is there even a &quot;module&quot; free variable anyway?
* Ihab Awad
* Wes Garland
* Ondrej Zara -- a sane function (require) ought to return one data type
* Daniel Friesen
* Tom Robinson

== Prototypes ==

* Node (isaacs branch)
* Narwhal (kriskowal's refactor and using-packages branches, landing in the 0.3 timeframe if ratified)</text>
    </revision>
  </page>
  <page>
    <title>Packages</title>
    <id>344</id>
    <revision>
      <id>2769</id>
      <timestamp>2010-05-12T03:31:34Z</timestamp>
      <contributor>
        <username>Cadorn</username>
        <id>60</id>
      </contributor>
      <comment>/* Roadmap */</comment>
      <text xml:space="preserve">'''STATUS: [[/1.0|1.0]] RATIFIED'''

== Specifications ==
* [[Packages/1.0]] concerning the package layout format and package descriptor schema

== Roadmap ==

* System Packages [[/1.0|1.0]] (''ratified'')
* System Packages [[/1.1|1.1]] (''draft'')
* Package Catalogs
* Using Packages ([[/A|background]])

== Open Issues for Next Versions ==

* Make bugs optional [http://groups.google.com/group/commonjs/browse_thread/thread/c70af7ad188d6082]
* License is slightly misleading [http://groups.google.com/group/commonjs/browse_thread/thread/c70af7ad188d6082]
* Make repositories optional [http://groups.google.com/group/commonjs/browse_thread/thread/c70af7ad188d6082]
* Make depedencies optional [http://groups.google.com/group/commonjs/browse_thread/thread/c70af7ad188d6082]
* Make properties that start with &amp; and _ and possibly the &quot;type&quot; attribute reserved for package registries. [http://groups.google.com/group/commonjs/browse_thread/thread/c70af7ad188d6082]
* Make &quot;engines&quot; a map of engine names to required versions [http://groups.google.com/group/commonjs/browse_thread/thread/d079d42067a3598c]

== Proposals ==

* [[Packages/B]] concerning the package layout format, package descriptor schema, and eventually a catalog schema</text>
    </revision>
  </page>
  <page>
    <title>Packages/1.0</title>
    <id>345</id>
    <revision>
      <id>2900</id>
      <timestamp>2010-09-11T14:34:26Z</timestamp>
      <contributor>
        <username>AzaToth</username>
        <id>133</id>
      </contributor>
      <comment>/* Catalog Properties */ added note for chekcsums to be automatically added, also add example sha1,sha256 (undef which sums should be available)</comment>
      <text xml:space="preserve">{{Spec
|status=ratified
|standard=yes
}}

== Packages ==

This specification describes the CommonJS package format for distributing CommonJS programs and libraries. A CommonJS package is a cohesive wrapping of a collection of modules, code and other assets into a single form. It provides the basis for convenient delivery, installation and management of CommonJS components.

This specifies the CommonJS package descriptor file and package file format. It does not specify a package catalogue file or format; this is an exercise for future specifications.
The package descriptor file is a statement of known fact at the time the package is published and may not be modified without publishing a new release.

== Package Descriptor File ==

Each package must provide a top-level package descriptor file called &quot;package.json&quot;. This file is a JSON format file. Each package must provide all the following fields in its package descriptor file.

* name - the name of the package. This must be a unique, lowercase alpha-numeric name without spaces. It may include &quot;.&quot; or &quot;_&quot; or &quot;-&quot; characters. It is otherwise opaque.
* description - a brief description of the package. By convention, the first sentence (up to the first &quot;. &quot;) should be usable as a package title in listings.
* version - a version string conforming to the Semantic Versioning requirements (http://semver.org/).
* keywords - an Array of string keywords to assist users searching for the package in catalogs.
* maintainers - Array of maintainers of the package. Each maintainer is a hash which must have a &quot;name&quot; property and may optionally provide &quot;email&quot; and &quot;web&quot; properties. For example:  
 &quot;maintainers&quot;:[ {
    &quot;name&quot;: &quot;Bill Bloggs&quot;,
    &quot;email&quot;: &quot;billblogs@bblogmedia.com&quot;,
   &quot; web&quot;: &quot;http://www.bblogmedia.com&quot;,
 }]
* contributors - an Array of hashes each containing the details of a contributor. Format is the same as for author. By convention, the first contributor is the original author of the package.
* bugs - URL for submitting bugs. Can be mailto or http.
* licenses - array of licenses under which the package is provided. Each license is a hash with a &quot;type&quot; property specifying the type of license and a url property linking to the actual text. If the license is one of the [http://www.opensource.org/licenses/alphabetical official open source licenses] the official license name or its abbreviation may be explicated with the &quot;type&quot; property.  If an abbreviation is provided (in parentheses), the abbreviation must be used.
 &quot;licenses&quot;: [
    {
        &quot;type&quot;: &quot;GPLv2&quot;,
        &quot;url&quot;: &quot;http://www.example.com/licenses/gpl.html&quot;,
    }
 ]
* repositories - Array of repositories where the package can be located. Each repository is a hash with properties for the &quot;type&quot; and &quot;url&quot; location of the repository to clone/checkout the package. A &quot;path&quot; property may also be specified to locate the package in the repository if it does not reside at the root. For example: 
 &quot;repositories&quot;: [
        {
             &quot;type&quot;: &quot;git&quot;, 
             &quot;url&quot;: &quot;http://github.com/example.git&quot;,
             &quot;path&quot;: &quot;packages/mypackage&quot;
        }
 ]
* dependencies - Hash of prerequisite packages on which this package depends in order to install and run. Each dependency defines the lowest compatible MAJOR[.MINOR[.PATCH]] dependency versions (only one per MAJOR version) with which the package has been tested and is assured to work. The version may be a simple version string (see the version property for acceptable forms), or it may be a hash group of dependencies which define a set of options, any one of which satisfies the dependency. The ordering of the group is significant and earlier entries have higher priority. For example: 
 &quot;dependencies&quot;: {
        &quot;webkit&quot;: &quot;1.2&quot;,
        &quot;ssl&quot;: {
            &quot;gnutls&quot;: [&quot;1.0&quot;, &quot;2.0&quot;],
            &quot;openssl&quot;: &quot;0.9.8&quot;,
        },
 }

Optional Keywords
* &quot;homepage&quot; - URL string for the package web site
* &quot;os&quot; - Array of supported operating systems. If absent or set to the empty set, the package makes no platform assumptions. The set of valid os names includes: aix, freebsd, linux, macos,  solaris, vxworks, windows.
* &quot;cpu&quot; - Array of supported CPU architectures. If absent or set to the empty set, the package makes no platform assumptions. The set of valid cpu names includes: arm, mips, ppc, sparc, x86, x86_64.
* &quot;engine&quot; - Array of supported JavaScript engines. If absent or set to the empty set, the package makes no platform assumptions. The set of valid engine names includes: ejs, flusspferd, gpsee, jsc, spidermonkey, narwhal, node, rhino, v8.
* &quot;builtin&quot;- Boolean value indicating the package is built in as a standard component of the underlying platform
* directories - Object hash of package directories. Typical directories include &quot;lib&quot;, &quot;src&quot;, &quot;doc&quot;, &quot;jars&quot;, &quot;test&quot; and &quot;bin&quot;. Package manager tools must use these directory definitions to find various package components.
* implements - Array of relevant CommonJS specifications this package supports. A specification identifier is the WikiName of the specification prefixed by &quot;CommonJS/&quot;. Arbitrary URLs may also be specified to indicate support for externally published specifications.
   &quot;implements&quot;: [ &quot;CommonJS/Modules/1.0&quot;, &quot;CommonJS/JSGI/1.0&quot;]
* scripts - Object hash of scripts used in managing the package. A package manager tool may use these scripts to install, build, test or uninstall the package. For example:
    &quot;scripts&quot;: {
        &quot;install&quot;: &quot;install.js&quot;,
        &quot;uninstall&quot;: &quot;uninstall.js&quot;,
        &quot;build&quot;: &quot;build.js&quot;,
        &quot;doc&quot;: &quot;make-doc.js&quot;,
        &quot;test&quot;: &quot;test.js&quot;,
    }

Package managers and loaders should ignore unknown fields in the package descriptor file. The following fields are reserved for future expansion: build, default, email, external, files, imports, maintainer, paths, platform, require, summary, test, using, downloads, uid, type.  Extensions to the package descriptor specification should strive to avoid collisions for future standard names by name spacing their properties with innocuous names that do not have meanings relevant to general package management.

== Catalog Properties ==

When a package.json is included in a catalog of packages, the following fields should be present for each package. 

* checksums - Hash of package checksums. This checksum is used by package manager tools to verify the integrity of a package. For example:
 checksums: {
   &quot;md5&quot;: &quot;841959b03e98c92d938cdeade9e0784d&quot;,
   &quot;sha1&quot;: &quot; f8919b549295a259a6cef5b06e7c86607a3c3ab7&quot;,
   &quot;sha256&quot;: &quot;1abb530034bc88162e8427245839ec17c5515e01a5dede6e702932bbebbfe8a7&quot;
 }

This checksum is meant to be automatically added by the catalog service

== Package File Format ==

The package files shall be a simple archive of the package directory including the package.json file in a relative, ZIP archive format (Though this format may change in future revisions of this specification). The archive must have a single top level directory.

== Package Directory Layout == 

A CommonJS package will observe the following:
* A package.json file must be in the top level directory
* Binary files should be in the &quot;bin&quot; directory, 
* Javascript code should be under the &quot;lib&quot; directory
* Documentation should be under the &quot;doc&quot; directory
* Unit tests should be under the &quot;test&quot; directory

== Package Files ==

To install and uninstall a CommonJS package some local installation steps may be required. A package may specify various scripts to run via the &quot;scripts&quot; package.json field.

== Other Requirements ==

* All modules contained in packages must conform to the CommonJS Securable Modules specification.

== Example Package Descriptor File ==

 {
    &quot;name&quot;: &quot;mypackage&quot;,
    &quot;version&quot;: &quot;0.7.0&quot;,
    &quot;description&quot;: &quot;Sample package for CommonJS. This package demonstrates the required elements of a CommonJS package.&quot;,
    &quot;keywords&quot;: [
        &quot;package&quot;,
        &quot;example&quot; 
    ],
    &quot;maintainers&quot;: [
        {
            &quot;name&quot;: &quot;Bill Smith&quot;,
            &quot;email&quot;: &quot;bills@example.com&quot;,
            &quot;web&quot;: &quot;http://www.example.com&quot; 
        } 
    ],
    &quot;contributors&quot;: [
        {
            &quot;name&quot;: &quot;Mary Brown&quot;,
            &quot;email&quot;: &quot;maryb@embedthis.com&quot;,
            &quot;web&quot;: &quot;http://www.embedthis.com&quot; 
        } 
    ],
    &quot;bugs&quot;: {
        &quot;mail&quot;: &quot;dev@example.com&quot;,
        &quot;web&quot;: &quot;http://www.example.com/bugs&quot; 
    },
    &quot;licenses&quot;: [
        {
            &quot;type&quot;: &quot;GPLv2&quot;,
            &quot;url&quot;: &quot;http://www.example.org/licenses/gpl.html&quot; 
        } 
    ],
    &quot;repositories&quot;: [
        {
            &quot;type&quot;: &quot;git&quot;,
            &quot;url&quot;: &quot;http://hg.example.com/mypackage.git&quot; 
        } 
    ],
    &quot;dependencies&quot;: {
        &quot;webkit&quot;: &quot;1.2&quot;,
        &quot;ssl&quot;: {
            &quot;gnutls&quot;: [&quot;1.0&quot;, &quot;2.0&quot;],
            &quot;openssl&quot;: &quot;0.9.8&quot; 
        } 
    },
    &quot;implements&quot;: [&quot;cjs-module-0.3&quot;, &quot;cjs-jsgi-0.1&quot;],
    &quot;os&quot;: [&quot;linux&quot;, &quot;macos&quot;, &quot;win&quot;],
    &quot;cpu&quot;: [&quot;x86&quot;, &quot;ppc&quot;, &quot;x86_64&quot;],
    &quot;engines&quot;: [&quot;v8&quot;, &quot;ejs&quot;, &quot;node&quot;, &quot;rhino&quot;],
    &quot;scripts&quot;: {
        &quot;install&quot;: &quot;install.js&quot;,
        &quot;uninstall&quot;: &quot;uninstall.js&quot;,
        &quot;build&quot;: &quot;build.js&quot;,
        &quot;test&quot;: &quot;test.js&quot; 
    },
    &quot;directories&quot;: {
        &quot;lib&quot;: &quot;src/lib&quot;,
        &quot;bin&quot;: &quot;local/binaries&quot;,
        &quot;jars&quot;: &quot;java&quot; 
    } 
 }

== Editor Macros/Scripts ==

Remembering the format and typing the common bits can be boring.  So listed below are known editor scripts to make this easier:

* [http://gist.github.com/311512 commonjs-package-json.vim] written by Ashb.

== Background ==
* [[Packages-Background]] (discussion)
* [http://groups.google.com/group/commonjs/browse_thread/thread/9f73afe65dc33df7 modules packaging]
* [http://semver.org/ Semantic Versioning]
* [http://github.com/280north/narwhal/blob/master/docs/packages-howto.md How to make packages in Narwhal]</text>
    </revision>
  </page>
  <page>
    <title>PackagesDescriptors/0.1</title>
    <id>346</id>
    <revision>
      <id>1875</id>
      <timestamp>2009-12-16T21:10:24Z</timestamp>
      <contributor>
        <username>Mob</username>
        <id>56</id>
      </contributor>
      <comment>moved [[PackagesDescriptors/0.1]] to [[Packages/0.1]]:&amp;#32;Simple rename</comment>
      <text xml:space="preserve">#REDIRECT [[Packages/0.1]]</text>
    </revision>
  </page>
  <page>
    <title>Packages-Background</title>
    <id>347</id>
    <revision>
      <id>1882</id>
      <timestamp>2009-12-16T21:36:32Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Packages-Background]] to [[Packages/A]]:&amp;#32;organizing</comment>
      <text xml:space="preserve">#REDIRECT [[Packages/A]]</text>
    </revision>
  </page>
  <page>
    <title>Packages/0.1</title>
    <id>348</id>
    <revision>
      <id>1884</id>
      <timestamp>2009-12-16T21:37:17Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Packages/0.1]] to [[Packages/B]]:&amp;#32;organizing (not a versioned proposal yet)</comment>
      <text xml:space="preserve">#REDIRECT [[Packages/B]]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Transport/B</title>
    <id>349</id>
    <revision>
      <id>2498</id>
      <timestamp>2010-03-24T11:59:39Z</timestamp>
      <contributor>
        <username>Tobie</username>
        <id>102</id>
      </contributor>
      <comment>/* Philosophy */</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
|draft=2
|drafts=1:2344
}}

Module transport format is a content format that can be used to send module factories from a server to an asynchronous client-side module loader.  A module factory can then be used on the client to instantiate modules.  

== Specification ==

Content in module transport format is called a &quot;bundle&quot;.

# A bundle is a JavaScript program and consists only of any number of calls to a &quot;require.def&quot; function.
# &quot;require.def&quot; accepts a top-level module identifier and a &quot;module descriptor&quot; object.
# A &quot;module descriptor&quot; consists of:
## A &quot;factory&quot; function.  The factory function accepts an object that permits the loader to inject arbitrary dependencies, particularly &quot;require&quot;, &quot;exports&quot;, and &quot;module&quot; for CommonJS modules.  It is the purview of the module text to extract these values.
## A &quot;requires&quot; array of top-level module identifiers corresponding to the shallow dependencies of the given module factory, those that it directly &quot;requires&quot;.  A module factory must not be called until all of the module desciptors mentioned in the transitive &quot;requires&quot; have been given to a loader by calls to &quot;require.def&quot;.

== Non-normative Form ==

The following is an example of the structure of a module transport.  All capitals denote meta-syntactic variables; names that would be replaced.  Elisions imply continuation, either by repetition or extension as applicable in context.  Destructuring notation, as [http://wiki.ecmascript.org/doku.php?id=harmony:destructuring proposed for future ECMAScript] is used here to communicate that the injection argument to the module factory function does not have any particular name, and may not necessarily be bound as anything other than arguments[0], but that it can carry arbitrary values for use by the module; &quot;require&quot;, &quot;exports&quot;, and &quot;module&quot; are names that must be injected particularly and only necessarily for the case of CommonJS modules.

 require.def(ID, {
      &quot;factory&quot;: function ({require, exports, module, …}) {
         MODULE_TEXT
      },
      &quot;requires&quot;: […MODULE_IDS],
      …
 });
 …

== Example ==

Given a CommonJS module &quot;example/point&quot;:

 var Scalar = require(&quot;./scalar&quot;).Scalar;
 exports.Point = function (x, y) {
     return Object.create(exports.Point.prototype, {
         &quot;x&quot;: {&quot;get&quot;: function () {retun Scalar(x)}},
         &quot;y&quot;: {&quot;get&quot;: function () {retun Scalar(y)}}
     });
 }

This would be the bundle of &quot;example/point&quot;:

 require.def(&quot;example/point&quot;, {
     &quot;factory&quot;: function () {
         var exports = arguments[0].exports,
             require = arguments[0].require,
             module = arguments[0].module;
         var Scalar = require(&quot;./scalar&quot;).Scalar;
         exports.Point = function (x, y) {
             return Object.create(exports.Point.prototype, {
                 &quot;x&quot;: {&quot;get&quot;: function () {retun Scalar(x)}},
                 &quot;y&quot;: {&quot;get&quot;: function () {retun Scalar(y)}}
             });
         }
     },
     &quot;requires&quot;: [&quot;example/scalar&quot;]
 });

= Philosophy =

Module Transport Format is not intended to be written by hand; it is intended that modules conforming to the CommonJS [[Modules/1.1]] specification can be programmatically wrapped and bundled to Module Transport Format.  It would be harmful for modules to be crafted by hand in this format because individual modules and trees of modules would become atonomous and therefore tightly coupled to their module name space.

* modules can be dynamically complied to Module Transport Format
* all module factories can be registered in a single call, but also
* module transport format is concatenatable.
* the module descriptor is intentionally an extensible name space.  One obvious extension would be a &quot;deepRequires&quot; list that could be used by an asynchronous, client-side module loader that has not been provided fore-knowledge about the transitive dependencies of a module to initiate early and optimially ordered HTTP requests for those dependencies before their shallow dependees are downloaded and registered by &quot;require.def&quot;.  A good heuristic for optimal order of download for modules is largest to smallest.

[{{fullurl:Modules/Transport/B|oldid=2344}} Draft 1] called for &quot;require.def&quot; to accept an object mapping multiple top-level module identifiers to respective module descriptors.  In response to Tobie Langel's comment that this would necessitate onerous complication for loaders on Internet Explorer because of the [http://www.dhtmlkitchen.com/learn/js/enumeration/dontenum.jsp#JScriptDontEnumBug &quot;DontEnum&quot; bug], this proposal was revised to accept only one module for each call to &quot;require.def&quot;.</text>
    </revision>
  </page>
  <page>
    <title>Collections/A</title>
    <id>350</id>
    <revision>
      <id>1932</id>
      <timestamp>2009-12-23T07:48:19Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Recommended duck-type nomenclature for collection APIs</comment>
      <text xml:space="preserve">'''STATUS: RECOMMENDATION.  NOT STANDARDS TRACK'''

== Lookup Table ==

; del(key) this
* Deletes an item for a key.
* Returns the mutated collection.
* For ordered collections, accepts a beginning key and an ending key, deleting all items in that range of keys excluding the ending key.
* Implemented in terms of remove.
; set(key, value) this
* Adds or overwrites an item for a key.
* Returns the mutated collection.
* Implemented in terms of insert.
; cut(key, value_opt) Value
* Deletes an item for a key.
* If no item has the given key and no default value is provided, throws a KeyError.
* Returns the corresponding value, or the default value.
* Implemented in terms of get and del.
; has(key, eq_opt, hash_opt) Boolean
* Returns whether key is among items.
; put(key, value) Value
* Adds an item for a key.
* returns the mutated collection.
* In an ordered collection, reserves the right to change the keys of some other items to make room for the new item by shifting later items right.
* Throws a key error if there is already an item with that key and it cannot be moved to a different key.
* Implemented in terms of set and has.
; get(key, value_opt) Value
* Returns a value for the given key.
* If there is no value for the given key and no default value is provided, throws a KeyError.
* Implemented in terms of retrieve and has.
; getset(key, value) Value
* If there is no value for the given key, sets the value for the key to the given value.
* Returns the value for the given key.
* Implemented in terms of get and set.

; keys() Set of Key
; values() Array of Value
; items() Array of [Key, Value] pairs

== Lookup Set ==

; insert(item, eq_opt, hash_opt) this
* Adds or overwrites a value.
* Returns the mutated collection.
* Defaults to an implementation in terms of find and set.
; retrieve(item, eq_opt, hash_opt) Item
* Returns the contained value that is naturally equivalent to a given value.
* Throws a value error if none exists.
* Defaults to an implementation in terms of find and get.
; remove(item, eq_opt, hash_opt) this
* Removes a value.
* Throws a value error if the value isn't in the collection.
* Returns the mutated collection.
* Defaults to an implementation in terms of find and del.
; discard(item, eq_opt, hash_opt) this
* Removes a value if it exists.
* Returns the mutated collection.
* Implemented in terms of has and remove.
; find(item, eq_opt, hash_opt) Item
* Returns the key for a given value.
* Accepts an optional equivalence relation to override the default of eq.</text>
    </revision>
  </page>
  <page>
    <title>Modules/ProposalForNativeExtension</title>
    <id>351</id>
    <revision>
      <id>1944</id>
      <timestamp>2010-01-05T01:37:59Z</timestamp>
      <contributor>
        <username>SubtleGradient</username>
        <id>63</id>
      </contributor>
      <comment>This proposal is meant to recognize how some implementations already work and give a name to the two separate existing standards. That way everyone should know what the differences are and the implica</comment>
      <text xml:space="preserve">== Proposal ==

This is a proposal for addition to the CommonJS Modules spec to define the two separate options for the, as yet undefined, area of functionality surrounding modules and natives.

So far this area has been specifically left undefined as an implementation detail. However, it is the purpose of this proposal to recognize the necessity of explicitly specifying the two major options for how this should be implemented.

This proposal is meant to recognize how some implementations already work and give a name to the two separate existing standards. That way everyone should know what the differences are and the implications.


== Modules (with global natives) &quot;MGN&quot; ==

Uses the same natives at the script which loads it.

Modifying the prototype of a native from within an MGN module would NOT limit those changes to the scope of the module.

e.g. http://gist.github.com/269015

Prior art: script tags in an html page in any browser. Each script runs in the same environment with access to the same natives.


== Modules (with sandboxed natives) &quot;MSB&quot; ==

Uses fresh &quot;sandboxed&quot; natives.

Modifying the prototype of a native from within an MSB module would limit those changes to the scope of the module and its exports.

Instances of these &quot;sandboxed&quot; natives may be exported using `exports` or available from an exported closure.

e.g. http://gist.github.com/268551

Prior art: &quot;How To Subclass The JavaScript Array Object &quot; http://dean.edwards.name/weblog/2006/11/hooray/


== Why do we need to specify this? ==

Currently many real-world JavaScript libraries and frameworks expect to be able to modify the global environment by extending native prototypes. This is a core feature of JavaScript.

Also, making modules secure is a very important feature.

Not all implementations of CommonJS support the same things. It's important when talking about an environments support for CommonJS that we be explicit about exactly what level of support they have.

Giving these two Module options separate names and separate APIs is important in order to manage user expectation.

== API ==

This proposal is less interested in the specific API implementation of each of these options as it is with specifying that they are separate and important things.

One option for the API would be to use a separate function name for requiring:

MGN: `require('extend-my-natives')`

MSB: `requireSafe('sandbox-my-natives')`


An alternative options would be to pass an additional argument to `require`

MGN: `require('extend-my-natives')`

MSB: `require('sandbox-my-natives', true)`


&quot;I personally prefer having separate function names since that's a bit clearer when reading the code. But I'm sure other people care about it more.&quot; — Thomas Aylott


== Notes ==

These two specifications are not mutually exclusive.

An environment may claim CommonJS compliance if it implements at least one of these Modules specifications.

i.e. NodeJS could implement MGN and not MSB and still be a CommonJS compatible environment.

== Extending native prototypes is the devil ==

I know how many people personally feel about extending native prototypes. Many people hang their hearts on their sleeves by using the derogatory term &quot;polluting&quot;. I'm sure some would like to freeze the prototypes of all natives. But regardless of how we may personally feel about PrototypeJS, MooTools or whatever other JavaScript we've seen that has possibly abused prototypes in the past. We simply need to recognize that extending native prototypes is a very basic core feature of JavaScript that needs to be more easily and explicitly supported.</text>
    </revision>
  </page>
  <page>
    <title>Modules/Natives</title>
    <id>352</id>
    <revision>
      <id>2103</id>
      <timestamp>2010-02-14T05:39:55Z</timestamp>
      <contributor>
        <username>Intrader</username>
        <id>74</id>
      </contributor>
      <minor/>
      <comment>/* How Modules relate to Global Natives */</comment>
      <text xml:space="preserve">== How Modules relate to Global Natives ==

Currently as of Modules 1.1 the spec for how an environment chooses to implement native classes in Modules is &quot;undefined&quot;. That means it's up to each environment implementation to decide how it should work.

&quot;&quot;&quot;To a developer &quot;undefined&quot; means that you cannot count on any specific 
behavior. If you take advantage of an &quot;undefined&quot; behavior, that means that 
there's a chance that behavior could break in the future, or break on a 
different platform. If you don't monkey with the globals, your app will work 
fine across CommonJS implementations (barring other, unrelated, 
compatibility issues of course)&quot;&quot;&quot; — Kevin Dangoor

There's no way of knowing what will happen if you modify a native from inside a Module. So how would you safely go about doing it according to the current spec?

=== How to do it now ===

[http://gist.github.com/268543 Example of how to extend prototypes using a CommonJS Module]


=== Can this change in the future? ===

[[Modules/ProposalForNativeExtension|Proposal for explicit native use in Modules]]


=== Discussions ===

* http://groups.google.com/group/commonjs/browse_thread/thread/2e91a6f12b5c39d9?hl=en
* http://groups.google.com/group/commonjs/browse_thread/thread/3a0886456f9fb8cd?hl=en
* http://groups.google.com/group/commonjs/browse_thread/thread/87db792cd61d05c2?hl=en</text>
    </revision>
  </page>
  <page>
    <title>File:Preston-2009-03.jpg</title>
    <id>353</id>
    <revision>
      <id>1962</id>
      <timestamp>2010-01-12T01:24:24Z</timestamp>
      <contributor>
        <username>Pbannister</username>
        <id>65</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>User:Pbannister</title>
    <id>354</id>
    <revision>
      <id>1965</id>
      <timestamp>2010-01-12T01:50:22Z</timestamp>
      <contributor>
        <username>Pbannister</username>
        <id>65</id>
      </contributor>
      <text xml:space="preserve">Preston L. Bannister - [mailto:preston@bannister.us preston@bannister.us] / [http://bannister.us/ website] / [http://bannister.us/weblog/ weblog] / 1-949-588-0872

[[File:Preston-2009-03.jpg]]

&quot;Running Light without Overbyte&quot;</text>
    </revision>
  </page>
  <page>
    <title>Packages/B</title>
    <id>355</id>
    <revision>
      <id>1974</id>
      <timestamp>2010-01-12T18:53:40Z</timestamp>
      <contributor>
        <username>Mob</username>
        <id>56</id>
      </contributor>
      <comment>moved [[Packages/B]] to [[Packages/1.0]]:&amp;#32;Ratified</comment>
      <text xml:space="preserve">#REDIRECT [[Packages/1.0]]</text>
    </revision>
  </page>
  <page>
    <title>User:Alexandre.Morgaut</title>
    <id>356</id>
    <revision>
      <id>2817</id>
      <timestamp>2010-06-01T14:40:40Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">
Product Manager at [http://www.4d.com 4D]

Member of the [http://www.wakandasoft.com Wakanda] Project Team</text>
    </revision>
  </page>
  <page>
    <title>Binary/E</title>
    <id>357</id>
    <revision>
      <id>1996</id>
      <timestamp>2010-01-17T08:05:59Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Created page with ''''STATUS: PROPOSAL'''  This proposal, based on [[Binary/D]], defines types and methods for constructing, manipulating, and transcoding binary data in both mutable and immutable …'</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

This proposal, based on [[Binary/D]], defines types and methods for constructing, manipulating, and transcoding binary data in both mutable and immutable forms.  ByteString resembles its immutable text analog, String, and ByteArray resembles its mutable analog, Array.  Both types constrain their data to the byte domain and provide a memory-safe interface to underlying continguous, random-access byte collections.

An [http://spreadsheets.google.com/ccc?key=0An5phhxDkYDPdDB1MDZDdGdwbXNxLUFUOFFSX0trVWc&amp;hl=en overview] of the supported types, methods, signatures, and corresponding return types is on Google Docs.

= Specification =

The &quot;binary&quot; top-level module must export ByteArray, ByteString, and Range.

; Binary
: a non-constructable base type for ByteString and ByteArray
; ByteString
: immutable, byte quantized
; ByteArray
: mutable, explicitly resizable, byte quantized
; Range
: a sub-range wrapper object

== Binary ==

A base type for ByteString and ByteArray.  Calling and constructing Binary must throw a TypeError.

== ByteString ==

A ByteString is an immutable, fixed-width representation of a C unsigned char (byte) array that does not implicitly terminate at the first 0-valued byte.

ByteString instances are comparable with the &lt;tt&gt;==&lt;/tt&gt; and &lt;tt&gt;===&lt;/tt&gt; operators based on equal order and respective values of their content.

=== Constructor ===

A ByteString function must exist.  Both calling and constructing must return a ByteString Object.

&lt;source&gt;
ByteString() instanceof ByteString;
new ByteString() instanceof ByteString;
ByteString() instanceof Binary;
new ByteString() instanceof Binary;
typeof ByteString() === &quot;object&quot;;
typeof new ByteString() === &quot;object&quot;;
&lt;/source&gt;

; ByteString()
: Construct an empty byte string.
; ByteString(byteString)
: Copies byteString.
; ByteString(byteArray)
: Use the contents of byteArray.  For performance, transparently to the layer specified here, the &quot;ByteArray&quot; may relinquish ownership of its underlying byte buffer and switch to a copy-on-write mode.
; ByteString(arrayOfNumbers)
: Use the numbers in arrayOfNumbers as the bytes.  Coerces Numbers to bytes by selecting their least significant eight bits.
; ByteString(string, charset)
: Convert a string. The ByteString will contain string encoded with charset.

=== Prototype Properties ===

; toByteArray() ByteArray
: Returns a byte for byte copy in a ByteArray.
: ''Note: for best performance, implementations should transfer ownership of the underlying buffer and flag the original owner to copy-on-write.''
; toByteArray(sourceCharset, targetCharset) ByteArray
: Returns this transcoded from the source charset to the target charset as a ByteArray.  The source and target charset are internally cast to String with the String constructor.
; toByteString() ByteString
: Returns this ByteString.
; toByteString(sourceCharset, targetCharset) ByteString
: Returns this transcoded from the source charset to the target charset as a ByteString.  The source and target charset are internally cast to String with the String constructor.
; toString() String
: Returns a debug representation like &quot;&lt;tt&gt;[ByteString 10]&lt;/tt&gt;&quot;, where 10 is the length this ByteString.
; toString(charset) String
: Decodes this ByteString according to the given character set and returns the String from the corresponding unicode points.  May throw a ValueError if the byte string is malformed or if any of the code points are out of the implementation's supported range.
; toArray() Array
: Returns an Array containing the bytes as Numbers.
; toSource() String
: returns &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteString([])&lt;/tt&gt;&quot; for a null byte string or &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteString([0, 1, 2])&lt;/tt&gt;&quot; for a byte string of length 3 with bytes 0, 1, and 2.
; valueAt(offset_opt) Number
: Returns the byte at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; indexOf(values, start_opt, stop_opt) Number
: Returns the index of the first occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; lastIndexOf(values, start_opt, stop_opt) Number
: Returns the index of the last occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; range(start_opt, stop_opt) Range
: Returns a Range object.  The value of stop defaults to the length of this.  The value of start defaults to 0.  Uses this for the Range's ref property.
; copy(target, targetStart, start, stop) ByteString
: Copies the Number values of each byte from this between start and stop to a target ByteArray or Array at the targetStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; slice(start_opt, stop_opt) ByteString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; substr(start_opt, length_opt) ByteString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substr String.prototype.substr]
; substring(start_opt, last_opt) ByteString
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/substring String.prototype.substring]
; concat(...) ByteString
: Returns a ByteString composed of itself concatenated with the given ByteString, ByteArray, and Array values.  Throws a TypeError if any of the arguments are not a ByteString, ByteArray, or Array of Numbers.  Coerces Numbers to bytes by selecting their least significant eight bits.
; join(array) ByteString
: Returns a ByteString of the ByteStrings, ByteArrays, Arrays of Numbers, or a combination thereof, delimited by this.  Arrays of Numbers are converted to ByteArrays.  Coerces Numbers to bytes by selecting their least significant eight bits.
; split(delimiter_opt, max_opt) Array
: Returns an Array of ByteStrings pared from the ByteString between strings of ByteStrings that match the given delimiter for up to the maximum number of delimiters, starting from the left.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.
; splitRight(delimiter_opt, max_opt) Array
: Returns an Array of ByteStrings pared from the ByteString between strings of ByteStrings that match the given delimiter for up to the maximum number of delimiters, starting from the right.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteString.  The delimiter is internally coerced to a ByteString with the ByteString constructor.
; Content
: an alias of Number, indicating that Number is the type of what &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; returns.

=== Internal Properties ===

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; Number
: Returns the byte at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt;
: throws a TypeError.

=== Instance Properties ===

; length
: The length in bytes. Not &lt;nowiki&gt;[[Writable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.

== ByteArray ==

A ByteArray is a mutable, flexible (explicitly growable and shrinkable) representation of a C unsigned char (byte) array.

=== Constructor ===

A ByteArray function must exist.  Calling and constructing a ByteArray both return a new ByteArray instance.

&lt;source&gt;
ByteArray() instanceof ByteArray;
new ByteArray() instanceof ByteArray;
ByteArray() instanceof Binary;
new ByteArray() instanceof Binary;
typeof ByteArray() === &quot;object&quot;;
typeof new ByteArray() === &quot;object&quot;;
&lt;/source&gt;

; ByteArray()
: New, empty ByteArray.
; ByteArray(length Number, fill_opt Number)
: New ByteArray of the given length, with the given fill number at all offsets.  The default filler is 0.
; ByteArray(byteArray)
: Copy byteArray.
; ByteArray(byteString)
: Copy contents of byteString.
; ByteArray(arrayOfBytes)
: Use numbers in arrayOfBytes as contents.  Coerces Numbers to bytes by selecting their least significant eight bits.
; ByteArray(string, charset)
: Create a &quot;ByteArray&quot; from a &quot;String&quot;, the result being encoded with charset.

=== Prototype Properties ===

; toByteArray() ByteArray
: Returns a byte for byte copy in a ByteArray.
: ''Note: for best performance, implementations should transfer ownership of the underlying buffer and flag the original owner to copy-on-write.''
; toByteArray(sourceCharset, targetCharset) ByteArray
: Returns this transcoded from the source charset to the target charset as a ByteArray.  The source and target charset are internally cast to String with the String constructor.
; toByteString() ByteString
: Returns a byte for byte copy in a ByteString.
: ''Note: for best performance, implementations should transfer ownership of the underlying buffer and flag the original owner to copy-on-write.''
; toByteString(sourceCharset, targetCharset) ByteString
: Returns this transcoded from the source charset to the target charset as a ByteString.  The source and target charset are internally cast to String with the String constructor.
; toString() String
: Returns a debug representation like &quot;&lt;tt&gt;[ByteArray 10]&lt;/tt&gt;&quot;, where 10 is the length this ByteArray.
; toString(charset) String
: Decodes this according to the given character set and returns the String from the corresponding unicode points.  May throw a ValueError if the byte string is malformed or if any of the code points are out of the implementation's supported range.
; toArray() Array
: Returns an Array containing the bytes as Numbers.
; toSource() String
: returns &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteArray([])&lt;/tt&gt;&quot; for a null byte string or &quot;&lt;tt&gt;require(&quot;binary&quot;).ByteArray([0, 1, 2])&lt;/tt&gt;&quot; for a byte string of length 3 with bytes 0, 1, and 2.
; valueAt(offset_opt) Number
: Returns the byte at offset as a Number.  The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; byteStringAt(offset_opt) ByteString
: Returns a unary (length 1) ByteString of the byte at the given offset. The offset is coerced internally with the Number constructor.  Thus, if it is omitted or passed as undefined, it defaults to getting the value at offset 0.
; indexOf(values, start_opt, stop_opt) Number
: Returns the index of the first occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; lastIndexOf(values, start_opt, stop_opt) Number
: Returns the index of the last occurence of of a byte or consecutive bytes as represented by a Number, ByteString, or ByteArray of any length, or returns -1 if no match was found. If start and/or stop are specified, only elements between the the indexes start and stop are searched.  start defaults to 0 and stop defaults to the length of this.
; range(start_opt, stop_opt) Range
: Returns a Range object.  The value of stop defaults to the length of this.  The value of start defaults to 0.  Uses this for the Range's ref property.
; copy(target, targetStart, start, stop) ByteArray
: Copies the Number values of each byte from this between start and stop to a target ByteArray or Array at the targetStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; copyFrom(source, sourceStart, start, stop) ByteArray
: Copies the Number values of each byte from a given ByteArray or ByteString into this from start to stop at the given sourceStart offset.  If undefined or omitted, stop is presumed to be the length of this.  targetStart, start, and stop are internally coerced to Numbers with the Number constructor.  Throws a TypeError if the target is not a ByteArray or Array.  Returns this.
; fill(value, start_opt, stop_opt) ByteArray
: Fills each of the contained bytes with the given value (either a unary ByteString, ByteArray, or a Number) from the start offset to the stop offset.  start and stop must be numbers, undefined, or omitted.  If omitted, start is presumed to be 0.  If omitted, stop is presumed to beh the length of this ByteArray.  If omitted, &quot;value&quot; is presumed to be 0.  Returns this.
; splice(start_opt, stop_opt, ...values) ByteArray
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/splice Array.prototype.splice]
; slice(start_opt, stop_opt) ByteArray
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/slice Array.prototype.slice]
; split(delimiter_opt, max_opt) Array
: Returns an Array of ByteArrays pared from the ByteArrays between strings of ByteArrays that match the given delimiter for up to the maximum number of delimiters, starting from the left.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteArray.  The dlimiter is internally coerced to a ByteArray with the ByteArray constructor.
; splitRight(delimiter_opt, max_opt) Array
: Returns an Array of ByteArrays pared from the ByteArray between strings of ByteArrays that match the given delimiter for up to the maximum number of delimiters, starting from the right.  If omitted, the maximum defaults to Infinity.  The delimiter defaults to an empty ByteArray.  The delimiter is internally coerced to a ByteArray with the ByteArray constructor.
; forEach(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach Array.prototype.forEach]
; every(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/every Array.prototype.every]
; some(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/some Array.prototype.some]
; map(callback[, thisObject])
: See [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/map Array.prototype.map]
; Content
: an alias of Number, indicating that Number is the type of what &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; returns.

=== Internal Properties ===

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; Number
: Returns the Number value of a the byte at the given offset.
; &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt; Number
: Sets the byte value at the given offset.  Throws a ValueError if the index is beyond the current bounds of the byte array (byte arrays can be grown or shrunk by explicitly assigning a new length).  Implicitly coerces the value to a Number and masks it with 0xFF.

=== Instance Properties ===

; length
: The length in bytes. Not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.  Assigning to the length of a ByteArray causes the array to reallocate its underlying buffer to the given size, copying the original buffer up to the length of the new buffer if it is less, and filling all bytes beyond the length of the original buffer with the value 0.

== Range ==

A range object is a convenience for copying ranges from one ByteArray or ByteString to another ByteArray.

=== Constructor ===

; new Range({ref, start, stop})
: returns a Range object with the respective properties.

=== Prototype Properties ===

; copy(target, start_opt, stop_opt)
: generically calls &lt;codee&gt;this.ref.copy(target, this.start, Math.min(this.stop, this.start + target.length - start), start)&lt;/code&gt;.  The default value of stop is the target length.
; copyFrom(source, start_opt, stop_opt)
: generically calls &lt;code&gt;this.ref.copyFrom(source, this.start, Math.min(this.stop, this.start + source.length - start), start)&lt;/code&gt;.  The default value of stop is the source length.
; fill(value)
: generically calls &lt;code&gt;this.ref.fill(value, this.start, this.stop)&lt;/code&gt;
; splice(start_opt, stop_opt, ...values)
: generically calls &lt;code&gt;this.ref.splice.apply(this.ref, arguments)&lt;/code&gt;

== General Requirements ==

All of the properties specified on prototypes are not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt; on instances.

Any operation that requires encoding, decoding, or transcoding among charsets may throw an error if that charset is not supported by the implementation.  All implementations MUST support &quot;us-ascii&quot;, &quot;utf-8&quot;, and &quot;utf-16&quot;.

Charset strings are as defined by IANA http://www.iana.org/assignments/character-sets.

Charsets are case insensitive.

Endianness arguments are case insensitive.

= Rationale =

The idea of using the particular ByteString and ByteArray types and their respective names originated with Jason Orendorff in the [http://groups.google.com/group/commonjs/msg/89808c05d46b92d0 Binary API Brouhaha] discussion.

== Structures ==

This proposal is not an object oriented variation on Perl, PHP, Python, or Ruby's pack, unpack, and calcsize with notions of inherent endianness, read/write head position, or intrinsic codec or charset information.  The objects described in this proposal are merely for the storage and direct manipulation of strings and arrays of byte data.  Some object oriented conveniences are made, but the exercise of implementing pack, unpack, or an object-oriented analog thereof are left as an exercise for a future proposal of a more abstract type or a 'struct' module (as mentioned by Ionut Gabriel Stan on [http://groups.google.com/group/commonjs/msg/592442ba98c6c70e the list]).  This goes against most mentioned [[../|prior art]].

== Encoding Methods ==

This proposal also does not provide separate member functions for any particular subset of the possible charsets, encodings, compression algorithms, or consistent hash digests that might operate on a byte string or array, for example &quot;toBase64&quot;, &quot;toMd5&quot;, or &quot;toUtf8&quot; are not specified.  Instead, &quot;toString&quot; accepts IANA charset names and radix numbers for charsets and encodings.  The intent is that implementations will opt to make this extensible by falling back to an &quot;encodings&quot; module and searching for modules by the same name and calling &quot;encode&quot; or &quot;decode&quot; exports on those modules if they exist.  (As supported originally by Robert Schultz, Davey Waterson, Ross Boucher, and tacitly myself, Kris Kowal, on the [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst First proposition] thread on the mailing list).  This proposal does not address the need for stream objects to support pipelined codecs and hash digests (mentioned by Tom Robinson and Robert Schultz in the same conversation).

== &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; and &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt; ==

This proposal also reflects both group sentiment and a pragmatic point about properties.  This isn't a decree that properties like &quot;length&quot; should be consistently used throughout the CommonJS APIs.  However, given that all platforms support properties at the native level (to host String and Array objects) and that byte strings and arrays will require support at the native level, pursuing client-side interoperability is beyond the scope of this proposal and therefore properties have been specified.  (See comments by Kris Zyp about the implementability of properties in all platforms, comments by Davey Waterson from Aptana about the counter-productivity of attempting to support this API in browsers, and support properties over accessor and mutator functions by Ionut Gabriel Stand and Cameron McCormack on the [http://groups.google.com/group/commonjs/browse_thread/thread/be72ef3d8146731d/06c27162b698eef5?lnk=gst mailing list]).

== Future Proofing ==

This proposal suggests that the specified data types should be exported by a &quot;binary&quot; module.  The intent is that eventually ECMAScript will specify native types to replace these, and these new types would be hosted as &quot;primordials&quot;, free variables available in all top-level scopes.  Because these types are specified to be exported by the &quot;binary&quot; module, there is some ambiguity of whether &quot;instanceof&quot; relationships would be maintained when references are passed among global contexts.  It would be valuable for these identities to be preserved.  For module systems that share a common global scope, this would suggest that the binary types should be patched into some commonly shared object, like the global scope, only if they do not yet exist.  That would permit the first, permissive context to construct the types, and all subsequent sandboxes to share them.  Secure sandboxes would have to make other accomodations.

== Memory Optimization ==

In contrast to Maciej Stachowiak's [https://mail.mozilla.org/pipermail/es-discuss/2009-November/010132.html proposal], there are no methods for explicitly managing the mutability of the underlying buffer.  Since it is possible for implementations to explicitly use ownership and copy-on-write flags, it is desirable to keep the memory management beneath the surface of JavaScript.  For example, with freezing semantics as proposed by Maciej, freezing a mutable byte array could produce an immutable byte string that usurps ownership of the original byte array's buffer, so there would be no need for allocation.  However, this would render the original byte array unusable, and all persisting references to that array would be broken and we would have to define failure modes for that object.  Alternately, the byte array and byte string could share the buffer.  The byte string would be guaranteed to not modify the content of the buffer, and if the owner of the original byte array were to perform a modifying operation on the byte array, the implementation could at that time incur the cost of copying the buffer.  Similar optimizations could be applied by all ByteString and ByteArray constructors and conversion functions.

== Genericity ==

In accordance with Daniel Friesen's [[Binary/C]], a high priority in this proposal was duck typing.

; a generic way to get a value in the Content type of a ByteArray, ByteString, or String
: &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
; a generic way to get the type of what is returned by &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; for ByteArray, ByteString, and String (Number, ByteString, and String respectively):
: Content
; a generic way to get a ByteString for the value at an offset for either ByteArray or ByteString
: byteStringAt(offset) ByteString
; a generic way to get a ByteArray for the value at an offset for either ByteArray or ByteString
: would have been wasteful to include since byte arrays are meant for assembling large byte buffers through copying data from other binary collections, not for allocation churn.
; a generic way to get a Number for the value at an offset for any ByteArray, ByteString, Array, or String
: valueAt(offset) Number
; a generic way to get an object of length one in the same type that contains just the value at a given offset for any ByteArray, ByteString, Array, or String
: slice(offset, offset + 1)

The following methods and properties are interoperable among ByteArray, ByteString, Array, and String:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* indexOf
* lastIndexOf
* slice

The following methods and properties are interoperable among ByteArray, ByteString, and String:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* Content
* valueAt
* join
* split
* splitRight
* indexOf
* lastIndexOf
* slice

The following methods and properties are interoperable between ByteArray and ByteString:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* Content
* valueAt
* byteStringAt
* indexOf
* lastIndexOf
* slice
* copy
* range

The following methods and properties are interoperable between ByteString and String:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* Content
* valueAt
* indexOf
* lastIndexOf
* slice
* substr
* substring

The following methods are interoperable between ByteArray and Array:
* &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt;
* indexOf
* lastIndexOf
* slice
* forEach
* every
* some
* map

== Idempotence ==

[[Binary/B]] had a &quot;decodeToString&quot; method and &quot;toString&quot; was required to be distinct, to avoid decoding and encoding hazards.  However, in keeping with the existing Number.prototype.toString(radix), for subjective aesthetic reasons having worked with prototypes of both, and because it easier to remember which way encoding and decoding go with &quot;toString&quot;, &quot;toByteString&quot;, and &quot;toByteArray&quot; than with &quot;encode&quot; and &quot;decode&quot;, this proposal eschews &quot;decodeToString&quot;.  This has the side effect of making the generic &quot;toByteString&quot; and &quot;toString&quot; methods idempotent for converting to and from a charset.  For example, if you receive an object that may be a ByteString or a String, but if it is a String it will need to be converted to a ByteString with a given charset, you can simply call &quot;toByteString&quot; with that charset, even repeatedly.  Likewise, if you receive a ByteString or a String and you need it to be a String, you can simply call &quot;toString&quot; with the desired charset, allowing a succession of adapters or decorators to make the conversion at any point along the way.

== Miscelaneous ==

&quot;ByteString&quot; does not implement &quot;toUpperCase&quot; or &quot;toLowerCase&quot; since they are not meaningful without the context of a charset.

Unlike the &quot;Array&quot;, the &quot;ByteArray&quot; is not variadic so that its initial length constructor is not ambiguous with its copy constructor.

The [[Binary/B]] proposal, at Ash Berlin's recommendation, had split methods on both ByteStrings and ByteArrays that accepted as their optional second argument, an object of options for both the number of delimiters to match, but whether to include the delimiter on the right side of each term, presumably including a terminal delimiter that would obviate an empty collection from being returned as the last value.  This has been left as an exercise for a byte reader stream's &quot;readLine(delimiter)&quot; method, so that this proposal's split and splitRight methods may more closely resemble their cousins on existing Strings in JavaScript and other languages.

The &quot;join&quot; methods on &quot;ByteArray&quot; and &quot;ByteString&quot; differ from what you would expect in JavaScript based on Array joins, in a way that will be familiar and probably upsetting coming from Python.  The delimiter is the left side of the expression.  This is because the Array joining method can not be practically extended to determine whether to return a String, ByteString, or ByteArray based on the types of all of the values it contains.  It is far more practical to multi-plex the return type based on the type of the left hand side of the expression.

The &quot;Content&quot; property begins with a capital letter to distinguish it as a factory method like the constructor function to which it always refers, albeit ByteString, ByteArray, or Number.  To date, this remains a point of discussion.  Daniel Friesen's proposal [[Binary/C]] uses the name &quot;contentConstructor&quot;.

== Errata ==

This proposal is a strict subset of [[Binary/D]] with a few exceptions: the Content type and return value of &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; for ByteString has been changed to Number; ByteString and ByteArray are object types instead of anticipating future-compatibility with &quot;bytestring&quot; and &quot;bytearray&quot; types; and the Binary type has been reintroduced.  Bit types, radix encoding (base8...base64), and consistency shims for existing primordial types have been removed and are possible candidates for extensions to future revisions of this specification.

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a8d3a91af37fd355 ByteArray: byteAt method]
* [http://groups.google.com/group/commonjs/browse_thread/thread/45190ac89d7b422a Binary/B Extension Proposals and Implementation Notes]
* [http://groups.google.com/group/commonjs/browse_thread/thread/98c51580a47e855e Binary D ready for review]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f609c72c9749e2c3 Binary/D Draft 2]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Transport/C</title>
    <id>358</id>
    <revision>
      <id>2897</id>
      <timestamp>2010-09-10T01:57:09Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <comment>Redirect to asynchronous module definition</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
|implementations=Yabble,RequireJS
}}

== Format ==

The Transport/C proposal has moved to [http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition].</text>
    </revision>
  </page>
  <page>
    <title>User:KrisKowal</title>
    <id>359</id>
    <revision>
      <id>2241</id>
      <timestamp>2010-03-13T04:21:07Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Licensed</comment>
      <text xml:space="preserve">[[Real Name::Kris Kowal| ]]
* http://askawizard.blogspot.com
* http://github.com/kriskowal

Working on Narwhal, Chiron, and with ECMA

I assign the MIT License to all of my contributions under http://wiki.commonjs.org</text>
    </revision>
  </page>
  <page>
    <title>Encodings</title>
    <id>360</id>
    <revision>
      <id>2756</id>
      <timestamp>2010-04-29T21:03:59Z</timestamp>
      <contributor>
        <username>Hannesw</username>
        <id>10</id>
      </contributor>
      <text xml:space="preserve"># [[Encodings/A]]
# [[Encodings/B]]
# [[Encodings/C]]</text>
    </revision>
  </page>
  <page>
    <title>Encodings/A</title>
    <id>361</id>
    <revision>
      <id>2545</id>
      <timestamp>2010-03-31T14:16:41Z</timestamp>
      <contributor>
        <username>Aristid</username>
        <id>46</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposal
|implementations=Flusspferd
}}

For Streams, we need encodings support. There also should be a low-level API available for this.

= Specification =

== Encoding Names ==

The encoding names should be among those supported by ICONV, which seem to be a superset of http://www.iana.org/assignments/character-sets.

The following encodings are required:
* US-ASCII
* UTF-8
* UTF-16
* ISO-8859-1

Encoding names &lt;b&gt;must&lt;/b&gt; be case &lt;b&gt;insensitive&lt;/b&gt;

== API ==

OK, so probably this should be a module:

&lt;source&gt;
var enc = require('encodings')
&lt;/source&gt;

=== Simple methods ===

For convenience, there should be these easy methods for converting between encodings:

; string = enc.convertToString(sourceEncoding, byteStringOrArray)
: Converts a ByteString or a ByteArray to a Javascript string.
; byteString = enc.convertFromString(targetEncoding, string)
: Converts a Javascript string to a ByteString.
; byteString = enc.convert(sourceEncoding, targetEncoding, byteStringOrArray)
: Converts a ByteString or a ByteArray to a ByteString.

=== Checking for available encodings ===

; enc.supports(encodingName)
: Checks if encodingName is supported and return true if so, false otherwise.
;  enc.listEncodings([encodingCheckerFunction or regex])
: encodingCheckerFunction takes the encoding name as a parameter and returns true-ish if the encoding should be listed. Regexes should also be supported. If the parameter is missing, returns all supported encodings.

=== Class: Transcoder ===

There also should be a class enc.Transcoder for general transcoding conversion (between ByteStrings or ByteArrays).

; [Constructor] Transcoder(from, to)
: Where from and to are the encoding names.
; [Constant] sourceCharset
: String containing the (possibly normalised) source charset name.
; [Constant] destinationCharset
: String containing the (possibly normalised) destination charset name.
; [Method] push(byteStringOrArray[, outputByteArray])
: Convert input from a ByteString or ByteArray. Those parts of byteStringOrArray that could not be converted (for multi-byte encodings) are stored in a buffer. If outputByteArray is passed, the results are ''appended'' to outputByteArray.
: If outputByteArray was passed, returns outputByteArray, otherwise returns &lt;u&gt;the converted bytes as a ByteString&lt;/u&gt;.
: &lt;u&gt;The result will also contain bytes accumulated in prior calls to pushAccumulate.&lt;/u&gt;
; &lt;u&gt;[Method] pushAccumulate(byteStringOrArray)&lt;/u&gt;
: &lt;u&gt;Convert input from a ByteString or ByteArray into an internal buffer that will be read out the next time push or close is called.&lt;/u&gt;
; [Method] close([outputByteArray])
: Close the stream. Throws an exception if there was a conversion error (specifically, a partial multibyte character).
: &lt;u&gt;Writes the remaining output bytes (including those that were accumulated in pushAccumulate) into the here given outputByteArray (appended) or a new ByteString. If outputByteArray is given, it is returned, otherwise the ByteString is returned.&lt;/u&gt;
: &lt;u&gt;Also adds initial shift state sequences if required by the encoding.&lt;/u&gt;

'''TODO''': Which exception to throw on error?

= Usage examples =

Example:

&lt;source&gt;
Transcoder = require('encodings').Transcoder
transcoder = new Transcoder('iso-8859-1', 'utf-32')
transcoder.pushAccumulate(input) // input is a ByteString
output = transcoder.close() // and output is a ByteString too
&lt;/source&gt;

Another example:

&lt;source&gt;
transcoder = new Transcoder('utf-32', 'utf-8')
output = new ByteArray()
while (input = readSomeByteFromSomewhere()) {
        transcoder.push(input, output)
}
transcoder.close(output)
// output is the complete conversion of all the input chunks concatenated now
&lt;/source&gt;

(See [[Encodings/OldClass]] for another API.)

== Stateful encodings ==

Some encodings can carry state across many characters - state which has to be reset at the end of a conversion. This creates the need to ''always'' call transcoder.close(output) after converting. The simple methods take care of that already. An example of such an encoding would be [http://en.wikipedia.org/wiki/ISO/IEC_2022 ISO-2022-JP], a Japanese encoding. This encoding is compatible with ASCII as long as it is in the initial state. But there is an escape sequence (actually more than one: &lt;tt&gt;ESC ( J&lt;/tt&gt;, &lt;tt&gt;ESC $ @&lt;/tt&gt; and &lt;tt&gt;ESC $ B&lt;/tt&gt;) to get into Kana/Kanji mode, and another escape sequence to get back into ASCII mode: &lt;tt&gt;ESC ( B&lt;/tt&gt;. So a reader of ISO-2022-JP content assumes that, initially, the encoding is in ASCII mode, and as soon as it sees an escape sequence, switches into another mode. Therefore, in order to be able to concatenate files, ISO-2022-JP files should end with &lt;tt&gt;ESC ( B&lt;/tt&gt; if they are in non-ASCII mode at the end.

&lt;source&gt;
      // Te Su To - thanks to miwagawa
      katakana_string = &quot;\u30c6\u30b9\u30c8&quot;,
      katakana_shift_jis = binary.ByteString([
        0x83,0x65,
        0x83,0x58,
        0x83,0x67
      ]),
 
      // Shift to JIS X 0208-1983
      iso2022_FROM_ascii = [ 0x1b,0x24,0x42 ],
      // Shift to ASCII
      iso2022_TO_ascii   = [ 0x1b,0x28,0x42 ],
 
      katakana_iso2022 = binary.ByteString(
        iso2022_FROM_ascii.concat([
          0x25,0x46,
          0x25,0x39,
          0x25,0x48,
        ], iso2022_TO_ascii)
      );
&lt;/source&gt;

If you transcode as in the examples above, this should work.

Flusspferd has some tests for these things in http://github.com/ruediger/flusspferd/blob/master/test/js/encodings.t.js

= Implementation Recommendations =

First of all, it is recommended to implement convertToString, convertFromString and convert with Transcoder.

Secondly, you should make sure that initial shift state support is properly implemented. When you're using iconv, you need to call iconv(cd, 0, 0, &amp;ob, &amp;ol) in Transcoder.close(). An example of what an initial shift state is: In the Japanese ISO-2022-JP encoding, the default state are ASCII bytes. However, the state can be switched to Japanese with an escape sequence. To make sure that at the end of the text, the state is ASCII again, iconv will emit another escape sequence to switch back again. This is important if you want to concatenate ISO-2022-JP texts, and an implementation of Transcoder that doesn't properly emit these sequences is &lt;b&gt;broken&lt;/b&gt;.

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/6365b2a54615a134 Proposal: Encodings API (independent from Streams)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/3faf4a067973a71a How to make Encodings]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f9fcf27e1dd4a8b1 Who's implementing the Encodings API?]

= Other =

[http://flusspferd.org Flusspferd]'s implementation is documented [http://flusspferd.org/docs/js/commonjs%20core/encodings.html here] and [http://flusspferd.org/docs/js/commonjs%20core/encodings/transcoder.html here].</text>
    </revision>
  </page>
  <page>
    <title>Encodings/OldClass</title>
    <id>362</id>
    <revision>
      <id>2019</id>
      <timestamp>2010-01-24T01:24:55Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Encodings/OldClass]] to [[Encodings/A/OldClass]]:&amp;#32;putting in the proposal name space (non-versioned, lettered)</comment>
      <text xml:space="preserve">#REDIRECT [[Encodings/A/OldClass]]</text>
    </revision>
  </page>
  <page>
    <title>Binary/Lite</title>
    <id>363</id>
    <revision>
      <id>2042</id>
      <timestamp>2010-01-25T18:03:43Z</timestamp>
      <contributor>
        <username>Aristid</username>
        <id>46</id>
      </contributor>
      <comment>/* Transcoding */</comment>
      <text xml:space="preserve">== Philosophy ==

There are already numerous proposals for Binary datatype out there (Binary/[A-E]). I personally find all of these too complex and cumbersome; aimed at ducktyping and multi-argument-type methods. The Binary/Lite proposal aims to provide a simplified data type which maintains the core functionality.

There is only one object specified in this proposal: the &lt;code&gt;Binary&lt;/code&gt; function. It is essentialy a (mutable) array of &lt;code&gt;Numbers&lt;/code&gt;. However, when compared with native &lt;code&gt;Array&lt;/code&gt;, this object offers these advantages:

* automatic conversion to &lt;code&gt;Number&lt;/code&gt; and masking by 0xFF,
* flat structure,
* built-in transcoding methods.


== Specification ==

=== Construction ===

The &lt;code&gt;Binary&lt;/code&gt; object has only one constructor form.

 /**
  * @param {int} length Initial length of this binary
  */
 var Binary = exports.Binary = function(length = 0) {};


=== Correspondence with Array ===

There is a strong similarity with &lt;code&gt;Array&lt;/code&gt;.
 Binary.prototype = [];

This way, we automatically have all those iterative methods, such as &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt; etc. On client side, this is achieved by
 var Binary = exports.Binary = Array;


=== Cooperation with other data types ===

To create &lt;code&gt;Binary&lt;/code&gt; from other data types, we use factory methods.
 var b1 = Binary.fromArray([1, 2, 3]);
 var b2 = Binary.fromString(&quot;hello ondřej&quot;, &quot;utf-8&quot;);

Converting back to standard types is very similar. Note that there are no monkey-patching efforts.
 var array = b1.toArray();
 var string = b1.decodeToString(charset);

The default &quot;toString&quot; is reserved for debugging purposes.
 Binary.prototype.toString = function() {
   return &quot;[Binary &quot; + this.length + &quot;]&quot;;
 }


=== Basic usage ===

The &lt;code&gt;length&lt;/code&gt; property specifies the size. It is possible to resize the binary object by assigning to &lt;code&gt;length&lt;/code&gt;. Newly created values are zero-filled.
 var b1 = Binary.fromArray([1, 2, 3]);
 var length = b1.length; /* 3 */
 b1.length = 10;

The '''[]''' operator is used to retrieve byte values (as &lt;code&gt;Number&lt;/code&gt;s) as well as modify the binary object. One can freely modify non-existant index - in this case, the object is first resized accordingly.
 var b1 = Binary.fromArray([1, 2, 3]);
 b1[3] = 123; /* b1 == [1, 2, 3, 123] */


=== Array methods ===

These methods return a &lt;code&gt;Number&lt;/code&gt; and resize the buffer accordingly: 
* &lt;code&gt;pop&lt;/code&gt;
* &lt;code&gt;shift&lt;/code&gt;

These methods accept a variadic list of &lt;code&gt;Number&lt;/code&gt;s and resize the buffer accordingly:
* &lt;code&gt;push&lt;/code&gt;
* &lt;code&gt;unshift&lt;/code&gt;

These methods return a &lt;code&gt;Binary&lt;/code&gt;: 
* &lt;code&gt;slice&lt;/code&gt;
* &lt;code&gt;splice&lt;/code&gt;


=== Miscellaneous ===
 /**
  * Appends contents of other variadic Binary instance(s) to the end of this one.
  */
 Binary.prototype.extendRight = function() {};

 /**
  * Appends contents of other variadic Binary instance(s) to the beginning of this one.
  */
 Binary.prototype.extendLeft = function() {};

 /**
  * Converts contents from one encoding to another
  */
 Binary.prototype.transcode = function(fromCharset, toCharset) {};

 /**
  * Returns a copy of this Binary
  */
 Binary.prototype.clone = function() {};


== Place for improvements ==

=== Naming ===

Current naming scheme does not anticipate the existency of an immutable binary data type. If we decide that an immutable binary is a must, I suggest picking one of these approaches:

* leaving ''Binary'' as is, creating an ''ImmutableBinary'' type. The awkward name corresponds to the fact that in most situations, a mutable Binary is sufficient.
* switching back to ByteString and ByteArray variants. I am still unsure what is the overall attitude regarding the number of Binary data types we really want.


=== Transcoding ===

As mentioned by [[User:MrN|MisterN]], everything related to transcoding might get separated into a different module. This clearly makes sense, as the set of tasks related to transcoding might get larger in the future. On the other hand, converting Strings to Binary has little sense without specifying a charset to be used.</text>
    </revision>
  </page>
  <page>
    <title>Talk:Encodings/A</title>
    <id>364</id>
    <revision>
      <id>2032</id>
      <timestamp>2010-01-25T12:53:56Z</timestamp>
      <contributor>
        <username>Aristid</username>
        <id>46</id>
      </contributor>
      <comment>reply</comment>
      <text xml:space="preserve">It seems that iso-8859-1 (Latin-0) has become much less relevant than [http://en.wikipedia.org/wiki/ISO-8859-15 iso-8859-15] (Latin-9), notably due to use of the euro directly in documents instead of being used as a named entity. It would therefore make sense to either replace iso-8859-1 with it, or add it to the list. --Fgm

:To the list of required encodings? I'm not sure how many encodings we should require. --[[User:MrN|MrN]] 12:53, 25 January 2010 (UTC)</text>
    </revision>
  </page>
  <page>
    <title>User:Aristid</title>
    <id>365</id>
    <revision>
      <id>2339</id>
      <timestamp>2010-03-13T20:09:41Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[User:MrN]] to [[User:Aristid]]</comment>
      <text xml:space="preserve">In the list, I'm also known as [[Real Name::Aristid Breitkreuz]].</text>
    </revision>
  </page>
  <page>
    <title>User:Ondras</title>
    <id>366</id>
    <revision>
      <id>2480</id>
      <timestamp>2010-03-19T10:41:55Z</timestamp>
      <contributor>
        <username>Ondras</username>
        <id>57</id>
      </contributor>
      <text xml:space="preserve">This is [[Real Name::Ondřej Žára]].</text>
    </revision>
  </page>
  <page>
    <title>JSGI/StreamExtension</title>
    <id>367</id>
    <revision>
      <id>2048</id>
      <timestamp>2010-01-29T01:52:27Z</timestamp>
      <contributor>
        <username>IsaacSchlueter</username>
        <id>52</id>
      </contributor>
      <minor/>
      <text xml:space="preserve">&lt;h1 id=&quot;jsgi_extension_proposal_evented_streaming_jsgi&quot;&gt;JSGI Extension Proposal - Evented Streaming JSGI&lt;/h1&gt;

&lt;h2 id=&quot;status_proposed&quot;&gt;Status: Proposed&lt;/h2&gt;

&lt;p&gt;Extension name: &lt;code&gt;stream&lt;/code&gt; &lt;br&gt;
Extension version: &lt;code&gt;0.1&lt;/code&gt; &lt;br&gt;
Reference Implementation: http://github.com/isaacs/ejsgi&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;Simplify the input, error, and response body objects to a single non-blocking data stream class.&lt;/p&gt;

&lt;p&gt;Support reading the input request and writing the response body without ever having to hold the entire body in memory.&lt;/p&gt;

&lt;h2 id=&quot;changes_from_jsgi_03&quot;&gt;Changes from JSGI 0.3&lt;/h2&gt;

&lt;h3 id=&quot;specification_changes&quot;&gt;Specification Changes&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;add &lt;code&gt;url&lt;/code&gt; member to the request object, which is the requested URL exactly as it appears on the first line of the HTTP request.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;request.input&lt;/code&gt; MUST be a Stream object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;response.body&lt;/code&gt; MUST be a Stream object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;request.jsgi.error&lt;/code&gt; MUST be a Stream object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;request.jsgi.stream&lt;/code&gt; MUST be a reference to the Stream implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;stream_objects&quot;&gt;Stream Objects&lt;/h3&gt;

&lt;p&gt;Stream Objects are representations of a stream of data in an asynchronous evented paradigm.&lt;/p&gt;

&lt;h4 id=&quot;methods&quot;&gt;Methods&lt;/h4&gt;

&lt;p&gt;Stream Objects have the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;write&lt;/strong&gt; - Send data down the stream.  If the stream is closed, then throw an Error.  This must not actually perform the write until after the current scope of execution is completed.  The order of written data MUST be consistent with the order in which &lt;code&gt;write&lt;/code&gt; is called.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;close&lt;/strong&gt; - Close the stream.  Once closed, no more data may be written to the Stream.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pause&lt;/strong&gt; - Temporarily prevent the firing of &lt;code&gt;data&lt;/code&gt; events.  This is useful when a reader needs to throttle a stream of incoming data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;resume&lt;/strong&gt; - Resume a paused thread, so that &lt;code&gt;data&lt;/code&gt; events will begin firing again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;addListener&lt;/strong&gt; - Attach an event handler to an event.  The first argument is the event name, and the second is the callback.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;events&quot;&gt;Events&lt;/h4&gt;

&lt;p&gt;Stream Objects emit the following events&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;data&lt;/strong&gt; - All the data that is passed through &lt;code&gt;write&lt;/code&gt; eventually triggers a &lt;code&gt;data&lt;/code&gt; event.  The argument is the data that was written.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;eof&lt;/strong&gt; - Emitted when all data has been written, and the stream is closed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;drain&lt;/strong&gt; - Emitted when the internal buffer empties.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pause&lt;/strong&gt; - Emitted when the stream is paused with the &lt;code&gt;pause&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;resume&lt;/strong&gt; - Emitted when the stream is resumed with the &lt;code&gt;resume&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;timing&quot;&gt;Timing&lt;/h4&gt;

&lt;p&gt;Stream objects MUST implement some sort of &amp;#8220;event queue&amp;#8221; in order to defer callbacks until after the current execution context has exited.  Specifically, the &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;eof&lt;/code&gt;, and &lt;code&gt;drain&lt;/code&gt; events MUST NOT be fired immediately after the corresponding calls to &lt;code&gt;write()&lt;/code&gt;, &lt;code&gt;close()&lt;/code&gt;, and &lt;code&gt;resume()&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;read_write&quot;&gt;Read/Write&lt;/h4&gt;

&lt;p&gt;All streams SHOULD be both readable and writeable.  This allows for middleware to step into the flow and filter the input or output to/from an app.&lt;/p&gt;

&lt;h2 id=&quot;backward_compatibility&quot;&gt;Backward Compatibility&lt;/h2&gt;

&lt;p&gt;For the purposes of this spec, &amp;#8220;compliant&amp;#8221; applications are applications that return a stream as the response body.&lt;/p&gt;

&lt;p&gt;However, non-streaming JSGI applications can easily be supported using a middleware adapter.  See the &lt;code&gt;array-to-stream.js&lt;/code&gt; and &lt;code&gt;string-to-stream.js&lt;/code&gt; examples included in the reference implementation.&lt;/p&gt;</text>
    </revision>
  </page>
  <page>
    <title>JSGI/StreamExtension/vote</title>
    <id>368</id>
    <revision>
      <id>2119</id>
      <timestamp>2010-02-19T09:24:04Z</timestamp>
      <contributor>
        <username>Mikewse</username>
        <id>9</id>
      </contributor>
      <comment>/* forEach+promise or streaming jsgi is... */</comment>
      <text xml:space="preserve">== Options for Asyncing up the response ==

&lt;ol&gt;&lt;li&gt;forEach() that returns a promise which is resolved when it's done&lt;/li&gt;&lt;li&gt;response.body is a stream (and we'll talk about what that is, exactly)&lt;/li&gt;&lt;li&gt;Async responses don't belong in the spec.  Just use threads.&lt;/li&gt;&lt;li&gt;Something else entirely&lt;/li&gt;&lt;/ol&gt;

Please add your name here, with your vote for 1, 2, 3, or 4.

* isaacs 2
* hassox 2
* mikeal 2
* tlrobinson 1
* mikewse 2

== request.input --&gt; request.body ==

Please add your name here with either &quot;yes&quot; or &quot;no&quot; for this change.

* isaacs yes
* mikeal yes
* deanlandolt yes, please!
* hassox yes
* tlrobinson yes
* mikewse yes

== forEach+promise or streaming jsgi is... ==

&lt;ol&gt;
&lt;li&gt;An extension&lt;/li&gt;
&lt;li&gt;A proposal for the next version of JSGI (0.4)&lt;/li&gt;
&lt;li&gt;Not something that we should bother with&lt;/li&gt;
&lt;/ol&gt;

Please add your name here with either 1, 2, or 3.

* deanlandolt: 2 if it is incompatible with the widely-adopted bits of 0.3, 1 if it can be made compatible
* mikewse: can &quot;streaming is a layer below forEach/Promise-based JSGI&quot; fit into 1?</text>
    </revision>
  </page>
  <page>
    <title>JSGI/ForEachStreaming</title>
    <id>369</id>
    <revision>
      <id>2159</id>
      <timestamp>2010-03-12T13:44:06Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <text xml:space="preserve">&lt;h1&gt;JSGI Streaming Body Using forEach&lt;/h1&gt;

&lt;h2 id=&quot;status_proposed&quot;&gt;Status: Proposed&lt;/h2&gt;

&lt;p&gt;
Reference Implementation: http://github.com/kriszyp/jsgi-node&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;KISS - Make it as simple as possible to return a response.&lt;/p&gt;

&lt;p&gt;Read request input and write to the response body without buffering data without requiring extra effort on the part of the programmer.&lt;/p&gt;

&lt;p&gt;Consistency between synchronous and asynchronous streaming of the body with backwards compatibility with JSGI 0.3.&lt;/p&gt;

&lt;p&gt;Consistency with the API on how asynchronous actions are modeled, keeping in mind that in JSGI, response status and headers are asynchronously provided using promises.&lt;/p&gt;

&lt;h2 id=&quot;changes_from_jsgi_03&quot;&gt;Addition JSGI 0.3&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;add &lt;code&gt;url&lt;/code&gt; member to the request object, which is the requested URL exactly as it appears on the first line of the HTTP request.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;request.body&lt;/code&gt; MUST be a forEach-able Stream object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;response.body&lt;/code&gt; MUST be a forEach-able Stream object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;request.jsgi.error&lt;/code&gt; MUST be a forEach-able Stream object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;stream_objects&quot;&gt;Stream Objects&lt;/h3&gt;

&lt;p&gt;forEach-able Stream Objects are representations of a stream of data.&lt;/p&gt;

&lt;h4 id=&quot;methods&quot;&gt;Methods&lt;/h4&gt;

&lt;p&gt;forEach-able Stream Objects have the following method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;forEach(write)&lt;/strong&gt; - When the stream can be written to, this will be called. The first parameter, write, MUST be a function. The forEach function can call the write function to write strings to the stream. The stream will be closed when forEach returns with any value that does not have a then() function, or if it returns a then() function (a promise), then() should be called with a callback that can be called when the stream is finished.

Each time the write callback is called, it may optionally also return a promise with a then() function if wishes to indicate that it has not yet completed handling processing the data. Once the data consumer is ready to continue receiving data, it call the callbacks to indicate that the forEach should continue. This allows for throttling of data.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;methods&quot;&gt;Properties&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;charset&lt;/strong&gt; - This property can be set to the desired charset to use for encoding or decoding strings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;examples&quot;&gt;Examples&lt;/h4&gt;
Simple sync app:
&lt;pre&gt;
app = function(request){
  return {
    status: 200,
    headers: {},
    body: [&quot;hello&quot;, &quot;world&quot;]
  }
};
&lt;/pre&gt;
Streaming app, this could be sync or async, as along as &quot;data&quot; is a forEach-able source data structure:
&lt;pre&gt;
app = function(request){
  return {
    status: 200,
    headers: {},
    body: {
      forEach: function(write){
        return data.forEach(function(item){
          return serialize(item);
        })
      }
    }
  }
};
&lt;/pre&gt;

Reading input:
&lt;pre&gt;
app = function(request){
  var file = new File(&quot;fileToSave&quot;);
  var fileUpload = request.body.forEach(function(data){
    file.write(data);
  }).then(file.close);

  return fileUpload.then(function(){
    return {
      status: 200,
      headers: {},
      body: [&quot;file successfully uploaded&quot;]
    };
  };
};
&lt;/pre&gt;
Streaming app, where the source is an event emitter:
&lt;pre&gt;
app = function(request){
  return {
    status: 200,
    headers: {},
    body: {
      forEach: function(write){
        var promise = new Promise();
        someEventSource.addListener(&quot;data&quot;, function(data){ write(data); });
        someEventSource.addListener(&quot;finished&quot;, function(data){ promise.resolve() });
        return promise;
      }
    }
  }
};
&lt;/pre&gt;

Middleware:
&lt;pre&gt;
MiddleWare = function(nextApp){
  return function(request){
    var response = nextApp(request);
    var inBody = response.body;
    response.body = {
      forEach: function(write){
        return inBody.forEach(function(block){
          return modify(block);
        })
      }
    }
    return response;
  }
};
&lt;/pre&gt;</text>
    </revision>
  </page>
  <page>
    <title>User:Tlrobinson</title>
    <id>370</id>
    <revision>
      <id>2064</id>
      <timestamp>2010-02-02T01:15:08Z</timestamp>
      <contributor>
        <username>Tlrobinson</username>
        <id>2</id>
      </contributor>
      <text xml:space="preserve">Tom Robinson

Projects:

* [http://narwhaljs.org http://narwhaljs.org/]
* [http://jackjs.org/ http://jackjs.org/]
* [http://cappuccino.org/ http://cappuccino.org/]

Websites:

* [http://tlrobinson.net/ http://tlrobinson.net/]
* [http://280north.com/ http://280north.com/]</text>
    </revision>
  </page>
  <page>
    <title>IO/C/Stream</title>
    <id>371</id>
    <revision>
      <id>2079</id>
      <timestamp>2010-02-03T18:19:44Z</timestamp>
      <contributor>
        <username>Mob</username>
        <id>56</id>
      </contributor>
      <comment>Clarify</comment>
      <text xml:space="preserve">This proposal defines a ''''Stream'''' class suitable for use in async and sync programs. 

== Preamble ==
Stream objects represent flows of data that pass data elements between an endpoint known as a source or sink and a consumer or producer. Streams may be half or full duplex and may be stacked where intermediate streams are be used as filters or data mutators. Example endpoints are the File, Socket, and Http classes. The TextStream is an example of a filter stream. Streams may buffer the incoming data or not. Streams will issue events to registered listeners for topics of interest. Streams may be used in both synchronous and asynchronous programs.

The Stream interface is an interface for concrete classes. Stream classes will typically augment the Stream class with extra user-facing methods and functionality.

== Interface api ==

;'''function Stream(stream: Stream = null)'''
:Creates a new stream instance. If another stream is provided as an argument to the constructor, the new stream instance will be stacked upon it. Reads and writes from the stream will be relayed to the connected stream and so-on along the stream chain.

;'''function addListener(name: [String | Array], listener: Function): void'''
:Add a listener for events on the stream. Events are issued for important state changes on the stream. Events are issued in both sync and async modes if listeners are registered.

:''name'' Name can be a string event name or it can be an array of event names.
:''listener'' Callback function to be invoked when the event is emitted.

;'''function get async(): Boolean'''
:Test if the stream is operating in async mode. In async mode, read, write and close methods will not block.

:''Returns'' True if the stream is in async mode, otherwise false.

;'''function set async(enable: Boolean): void'''
:Set the streams operating mode. Used to put the stream into async or sync mode.

:''enable'' Set to true to put the stream into async mode. Set to false to put the stream into sync mode

;'''function close(): void'''
:Close the stream.
:''Events''  The ''close'' event is issued when closing the stream.

;'''function read(buffer: ByteArray, offset: Number = 0, count: Number = -1): Number'''
:Read data from the stream. If data is available, the call will return immediately with data. If no data is available and the stream is in sync mode, the call will block until data is available. If no data is available and the stream is in async mode, the call will not block and will return immediately. A &quot;readable&quot; event will be issued if data becomes available for reading. 

:''buffer'' Destination byte array for read data.
:''offset'' Integer offset in the byte array to place the data. If the offset is -1, then data is appended to the buffer.
:''count'' Integer count of the number of bytes to read. Read up to this number of bytes. If -1, read as much as the buffer will hold up. If the stream is of fixed and known length (such as a file) and the buffer is of sufficient size or is growable, read the entire stream.
:''Returns'' an integer count of the bytes actually read. Returns null on eof.
:''Events'' The ''readable'' event may be listened to be notified when new read data becomes available.

;'''function removeListener(name: [String | Array], listener: Function): void
:Remoe a listener from the stream. 

:''name'' Name can be a string event name or it can be an array of event names.
:''listener'' Callback function specified when the listener was previously added.

;'''function write(...data): Number
:Write data to the stream. If the stream can accept all the write data, the call returns immediately with the number of elements written. If writing more data than the stream can absorb in sync mode, the call will block until the data is written. If writing more data than the stream can absorb in async mode, the call will not block and will return immediately. A &quot;writable&quot; event will be issued when all the data has been written.

:''data'' Variable number of data objects to write. It is stream specific how the written data will be converted or encoded.
:''Returns'' an integer count of the bytes actually written. Returns null on a write error.
:''Events'' The ''writable'' event is issued when the stream becomes empty and it is ready to be written to.</text>
    </revision>
  </page>
  <page>
    <title>Events/A</title>
    <id>372</id>
    <revision>
      <id>2759</id>
      <timestamp>2010-05-02T02:09:53Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>related discussions</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

* [http://wiki.commonjs.org/index.php?title=Events/A&amp;oldid=2082 Draft 1]
* [http://wiki.commonjs.org/index.php?title=Events/A&amp;oldid=2088 Draft 2]
* Draft 3

== Proposal ==

=== NameEmitter ===

; NameEmitter() NameEmitter
: creates a name emitter with an empty internal emitter memo.
; observe(name String, observer Function) Emitter
: gets or creates an internal emitter with the given name.  Calls and returns the result of the &quot;observe&quot; method on the internal emitter, passing the given observer function.
; emit(name String, ...args) Undefined
: gets or creates an internal emitter with the given name.  Applies and returns the result of the &quot;emit&quot; method on the internal emitter, passing the rest of the arguments.
; emitter(name String) Emitter
: gets or creates an internal emitter with the given name.

=== Emitter ===

; Emitter(defaultAction_opt Function, dismiss_opt Function) Emitter
: creates a emitter with an optional default action and an empty observer array.
; observe(observer Function) Emitter
: creates a new Emitter from the given action and a dismissal function, and pushes that emitter onto an internal array of observers.  The dismissal function, when called, removes the child emitter from the parent emitter's array of observers.
; emit(...args) Undefined
: uses &quot;this&quot; as an &quot;Event&quot; instance, creating a new one if necessary, and iteratively emits the event as the this object and the given arguments to each of its own observers until the event says it should no longer propagate, and then calls and returns the result of the default action if the event says it should still default.
; dismiss() Undefined
: if the emitter was constructed with a dismissal function, calls that function.


=== Event ===

; Event()
: creates a new Event that should still propagate and cause the corresponding emitter's default action to occur
; stopPropagation() Undefined
: prevents the event from propagating to further observers
; cancelDefault() Undefined
: cancels the corresponding emitter's default action
; stop() Undefined
: stops propagation and cancels the default action
; propagating() Boolean
: returns whether the event should continue propagating to further observers
; defaulting() Boolean
: returns whether the default action of the corresponding emitter should be called

== Examples ==

=== Dismissing an Observer ===

 var nameEmitter = new NameEmitter();
 var emitter = nameEmitter.observe(&quot;foo&quot;, function () {
 });
 emitter.dismiss();

=== Observing Before Another Observer ===

 var parent = nameEmitter.observe(&quot;foo&quot;, function () {print(&quot;parent&quot;)});
 var child = parent.observe(function () {print(&quot;child&quot;)});
 var beforeChild = child.observe(function () {print(&quot;beforeChild&quot;);});
 nameEmitter.emit(&quot;foo&quot;);

 beforeChild
 child
 parent

=== Observing After an Observer ===

 var parent = new Emitter(function () {print(&quot;parent&quot;)});
 var child = parent.observe(function () {print(&quot;child&quot;);});
 var afterChild = parent.observe(function () {print(&quot;afterChild&quot;)});
 parent.emit();

 child
 afterChild
 parent

=== Emit Arguments ===

 var emitter = new Emitter(function (a, b, c) {
     print(a, b, c);
 });
 emitter.emit(1, 2, 3);

 1 2 3

== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/9bd7b457d0bdc85f/bfccd9961dea4335 Events A]
* [http://groups.google.com/group/commonjs/browse_thread/thread/70c0d276dc5fa267/6118058542d95d78 Events A Continued]</text>
    </revision>
  </page>
  <page>
    <title>Events/B</title>
    <id>373</id>
    <revision>
      <id>2083</id>
      <timestamp>2010-02-04T00:37:49Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>even more brain-dead events proposal</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

== Proposal ==

=== Emitter ===

An emitter internally contains a memo of names to signal objects, which are created on-demand internally.

; observe(name String, callback Function) Undefined
: gets the internal signal or creates and sets the internal signal for the given name and calls the observe method of that signal with the given callback.
; emit(name String, ...args) Undefined
: gets the internal signal or creates and sets the internal signal for the given name and applies the emit method of that signal with the given arguments.

=== Signal ===

; Signal() Signal
: creates a signal with an empty observer array.
; observe(callback Function) Undefined
: pushes the callback on the internal observer array.
; emit(...args) Undefined
: applies each internal callback in order with the given arguments.</text>
    </revision>
  </page>
  <page>
    <title>User:Fbraem</title>
    <id>374</id>
    <revision>
      <id>2093</id>
      <timestamp>2010-02-05T13:38:32Z</timestamp>
      <contributor>
        <username>Fbraem</username>
        <id>68</id>
      </contributor>
      <text xml:space="preserve">Franky Braem is the project leader and developer of the GLUEscript project: http://gluescript.sf.net

Follow GLUEscript on Twitter: http://twitter.com/gluescript

My LinkedIn profile: http://be.linkedin.com/in/frankybraem</text>
    </revision>
  </page>
  <page>
    <title>Events/C</title>
    <id>375</id>
    <revision>
      <id>2096</id>
      <timestamp>2010-02-07T13:14:16Z</timestamp>
      <contributor>
        <username>Zimbatm</username>
        <id>72</id>
      </contributor>
      <minor/>
      <comment>/* NameEmitter */ Signal -&gt; Emitter</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

Based on [[Events/A]]:

* without event objects, so stopping propagation or default actions is not possible
* renaming Signal to Emitter and Emitter to NameEmitter
* addition of emitter method to NameEmitter

== Proposal ==

=== Emitter ===

; Emitter(defaultAction_opt Function, dismiss_opt Function)
: creates an emitter with an optional default action and an empty observer array.
; observe(observer Function) Emitter
: creates a new Emitter from the given action and a dismissal function, and pushes that emitter onto an internal array of observers.  The dismissal function, when called, removes the child emitter from the parent emitter's array of observers.
; emit(...args) Undefined
: calls each observer's emit method with the given arguments, and then calls and returns the result of the default action with the given arguments.
; dismiss() Undefined
: if the emitter was constructed with a dismissal function, calls that function.  Otherwise, does nothing.

=== NameEmitter ===

; observe(name String, observer Function) Emitter
: gets or creates an internal emitter with the given name.  Calls and returns the result of the &quot;observe&quot; method on the internal emitter, passing the given observer function.
; emit(name String, ...args) Undefined
: gets or creates an internal emitter with the given name.  Applies and returns the result of the &quot;emit&quot; method on the internal emitter, passing the rest of the arguments.
; emitter(name String) Emitter
: gets or creates an internal emitter with the given name and returns that emitter object.</text>
    </revision>
  </page>
  <page>
    <title>Events/D</title>
    <id>376</id>
    <revision>
      <id>2097</id>
      <timestamp>2010-02-07T17:46:10Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>DOM2-like API</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL'''

This proposal is a strict subset of the DOM2 events API [http://www.w3.org/TR/DOM-Level-2-Events/idl-definitions.html].

== Proposal ==

; createEvent(type String) Undefined
: constructs and returns a new Event with the given type

=== EventTarget ===

; addEventListener(type String, listener Function)
: pushes an event listener onto the internal array of listener functions for the given event type.
; removeEventListener(type String, listener Function)
: removes the given listener function from the internal array of listener functions for the given type.
; dispatchEvent(event Event) Boolean throws EventException
: sets the event's target to this object and calls each listener function in order with the given event as an argument until the event's stopPropagation method is called.

=== Event ===

No constructor; use &lt;code&gt;createEvent&lt;/code&gt;.

; initEvent()
: initializes the event.  Must be called before dispatching.
; type String
: the type name of the event, as set by &lt;code&gt;createEvent&lt;/code&gt;
; target EventTarget
: the target of the event, as set by &lt;code&gt;dispatchEvent&lt;/code&gt;
; stopPropagation() Undefined
: prevents an event from being propagated to further listeners.
; preventDefault() Undefined
: this specification does not provide a mechanism for defining default actions for event types, so this is a no-op unless implementations of dispatchEvent for particular objects opt to define the behavior for particular event types on particular targets.

=== EventException ===

; code Number
: implementation defined.

== Examples ==

=== Removing a Listener ===

 var listener = function (event) {};
 var target = new EventTarget();
 target.addEventListener(&quot;foo&quot;, listener);
 target.removeEventListener(&quot;foo&quot;, listener);

=== Listening Before Another Listener ===

Not supported.

=== Listening After another Listener ===

 var target = new EventTarget();
 target.addEventListener(&quot;foo&quot;, function (event) {print(&quot;before&quot;)});
 target.addEventListener(&quot;foo&quot;, function (event) {print(&quot;after&quot;)});
 var event = createEvent();
 event.initEvent();
 target.dispatch(event)

 before
 after

=== Emit Arguments ===

Not supported.</text>
    </revision>
  </page>
  <page>
    <title>Talk:Reactor</title>
    <id>377</id>
    <revision>
      <id>2099</id>
      <timestamp>2010-02-09T14:44:13Z</timestamp>
      <contributor>
        <username>Darren</username>
        <id>73</id>
      </contributor>
      <comment>Is the Reactor module needed?</comment>
      <text xml:space="preserve">Given the limitations of the browser event loop and the overlap with the worker module, is the Reactor module genuinely required? What benefits does it offer that aren't already covered?</text>
    </revision>
  </page>
  <page>
    <title>User:Ruediger</title>
    <id>378</id>
    <revision>
      <id>2228</id>
      <timestamp>2010-03-13T00:45:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Adding real name semantic.</comment>
      <text xml:space="preserve">[[Real Name::Rüdiger Sonderfeld| ]]
Hi,
I'm a member of the [http://flusspferd.org Flusspferd Team].</text>
    </revision>
  </page>
  <page>
    <title>Subprocess</title>
    <id>379</id>
    <revision>
      <id>2111</id>
      <timestamp>2010-02-18T21:28:23Z</timestamp>
      <contributor>
        <username>Ruediger</username>
        <id>75</id>
      </contributor>
      <comment>Created page with 'This API should provide a way to start and communicate with subprocesses.  == Prior Art == * [http://github.com/280north/narwhal/blob/master/engines/rhino/lib/os-engine.js#L69 na…'</comment>
      <text xml:space="preserve">This API should provide a way to start and communicate with subprocesses.

== Prior Art ==
* [http://github.com/280north/narwhal/blob/master/engines/rhino/lib/os-engine.js#L69 narwhal's os-engine]
* [http://flusspferd.org/docs/js/bundled%20modules/subprocess.html Flusspferd's subprocess module]

=== Other Languages ===
* popen(3) in POSIX.1-2001
* [http://docs.python.org/library/subprocess.html Subprocess module in Python]</text>
    </revision>
  </page>
  <page>
    <title>Promises/A</title>
    <id>380</id>
    <revision>
      <id>2123</id>
      <timestamp>2010-02-21T02:23:38Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Noted implementations</comment>
      <text xml:space="preserve">'''STATUS: PROPOSAL''' by Kris Zyp

= Proposal =

A promise represents the eventual value returned from the single completion of an operation. A promise may be in one of the three states, unfulfilled, fulfilled, and failed. The promise may only move from unfulfilled to fulfilled, or unfulfilled to failed. Once a promise is fulfilled or failed, the promise's value MUST not be changed, just as a values in JavaScript, primitives and object identities, can not change (although objects themselves may always be mutable even if there identity isn't). The immutable characteristic of promises are important for avoiding side-effects from listeners that can create unanticipated changes in behavior and allows promises to be passed to other functions without affecting the caller, in same way that primitives can be passed to functions without any concern that the caller's variable will be modified by the callee.

This API does not define how promises are created, but only defines the necessary interface that a promise must provide for promise consumers to interact with it. Implementors are free to define how promises are generated. Some promises may be provide their own functions to fulfill the promise, and other promises may be fulfilled by mechanisms that are not visible to the promise consumer. See the [Promise Manager] API for a proposal for useful convenience functions. Promises itself may include other additional convenience methods as well. For example, one could implement Dojo's Deferred functions on promises such as addCallback and addBoth.

A promise is defined as an object that has a function as the value for the property 'then':

; then(fulfilledHandler, errorHandler, progressHandler)
: Adds a fulfilledHandler, errorHandler, and progressHandler to be called for completion of a promise. The fulfilledHandler is called when the promise is fulfilled. The errorHandler is called when a promise fails. The progressHandler is called for progress events. All arguments are optional and non-function values are ignored. The progressHandler is not only an optional argument, but progress events are purely optional. Promise implementors are not required to ever call a progressHandler (the progressHandler may be ignored), this parameter exists so that implementors may call it if they have progress events to report.

This function should return a new promise that is fulfilled when the given fulfilledHandler or errorHandler callback is finished. This allows promise operations to be chained together. The value returned from the callback handler is the fulfillment value for the returned promise. If the callback throws an error, the returned promise will be moved to failed state.

An example of using a CommonJS compliant promise:

   &gt;asyncComputeTheAnswerToEverything().
     then(addTwo).
     then(printResult, onError);
   44

An interactive-promise is an extended promise that supports the following additional functions:

; get(propertyName)
: Requests the given property from the target of this promise. Returns a promise to provide the value of the stated property from this promise's target.
; call(functionName, arg1, arg2, ...)
: Request to call the given method/function on the target of this promise. Returns a promise to provide the return value of the requested function call.

= Open Issues =

Should calls to the callback handlers be put on the event queue or executed immediately? - Currently unspecified, and I don't know for sure what is best.

= Implementations =

* http://github.com/kriszyp/node-promise Promises for NodeJS
* http://github.com/280north/narwhal/blob/master/lib/promise.js Promises for Narwhal
* http://github.com/280north/narwhal/blob/master/lib/events.js Experimental Promises on Emitters

= Related Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/e93f73ef97e88439/9cdb490abb8edfa6 Promise API Proposal]</text>
    </revision>
  </page>
  <page>
    <title>Binary/F</title>
    <id>381</id>
    <revision>
      <id>2751</id>
      <timestamp>2010-04-28T20:45:36Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Removed old general requirements.</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
|draft=3
|drafts=1:2128, 2:2403
}}

This proposal, based on [[Binary/E]] and [[Binary/F/Wes]], defines a single, mutable, fixed-length, numeric byte storage type.

= Specification =

The &quot;common/buffer&quot; module exports a &quot;Buffer&quot; type that meets the following criteria.

A Buffer is a mutable, fixed-length, representation of a C unsigned char (byte) array.

== Constructor ==

# A Buffer function must exist.
# Calling and constructing a Buffer both return a new Buffer instance.
# Buffers are instances of Buffer and Object.
# The type of a Buffer is &quot;object&quot;.
# Any call or construction of Buffer that does not have a Number, Buffer, Array, or String as its first argument throws a TypeError.

; Buffer(length Number, Number(fill_opt))
# New Buffer of the given length, with the given fill number at all offsets.
# The default filler is 0.
; Buffer(source Buffer, Number(start_opt), Number(stop_opt), Boolean(copy_opt))
# New Buffer that is either a copy or a view of the allocation as the given buffer, from &quot;start&quot; to &quot;stop&quot;.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is the other buffer's length if undefined or omitted.
# &quot;start&quot; and &quot;stop&quot; may both be negative numbers, in which case they correspond to offsets counting from the length of the buffer.
# &quot;copy&quot; is true if undefined or omitted
# When true, &quot;copy&quot; indicates that the buffer must have its own copy of the allocation.
# When false, &quot;copy&quot; indicates that the buffer must share its allocation with the given buffer.
; Buffer(source Array, Number(start_opt), Number(stop_opt))
# New Buffer that contains the respective values from the given array, from &quot;start&quot; to &quot;stop&quot;.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is the array's &quot;length&quot; if undefined or omitted.
# The &quot;length&quot; of the new buffer is exactly the length from &quot;start&quot; to &quot;stop&quot;.
# &quot;start&quot; and &quot;stop&quot; may both be negative numbers, in which case they correspond to offsets counting from the length of the array.
; Buffer(string String, String(charset))
# Create a buffer from a string, the result being encoded with &quot;charset&quot;.

== Prototype Properties ==

; toString() String
# Returns a debug representation like &quot;&lt;tt&gt;[Buffer 10]&lt;/tt&gt;&quot;, where 10 is the length this Buffer.
# This signature of &quot;toString&quot; applies if the &quot;arguments.length&quot; is 0.
; toString(String(charset), Number(start_opt), Number(stop_opt)) String
# Decodes this between &quot;start&quot; and &quot;stop&quot; according to the given character set and returns the String from the corresponding unicode points.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is the length of this buffer if undefined or omitted.
# &quot;start&quot; and &quot;stop&quot; may be negative numbers, in which case they correspond to an offset counting from this buffer's length.
# Must throw a RangeError if the buffer is malformed, undefined, out of range, or incomplete for the given character set.
# &quot;charset&quot; must be one of &quot;UTF-8&quot;, &quot;UTF-16&quot;, &quot;ISO-8859-1&quot;, &quot;ASCII&quot;, &quot;BINARY&quot;.  Any other &quot;charset&quot; throws a RangeError.
## &quot;ASCII&quot; must properly transcode all 7-bit ASCII code points..
## ''Note: &quot;ASCII&quot; is not required to properly transcode any code points outside its seven bit domain.  &quot;ASCII&quot; may be an alias of &quot;UTF-8&quot; or &quot;ISO-8859-1&quot;.  For highest performance, &quot;ASCII&quot; may opt to ignore bits outside its domain.''
## &quot;BINARY&quot; must properly transcode all 8-bit ISO-8859-1 code points.
## ''Note: &quot;BINARY&quot; is not required to properly transcode any code points outside its eight bit domain.  &quot;BINARY&quot; may be an alias of &quot;ISO-8859-1&quot;.  For highest performance, &quot;BINARY&quot; may opt to ignore bits outside its domain.''
# This signature of &quot;toString&quot; applies if the &quot;arguments.length&quot; is not 0.
; toSource() String
# Returns &quot;&lt;tt&gt;require(&quot;binary&quot;).Buffer([])&lt;/tt&gt;&quot; for a null buffer or &quot;&lt;tt&gt;require(&quot;binary&quot;).Buffer([0, 1, 2])&lt;/tt&gt;&quot; for a buffer of length 3 with bytes 0, 1, and 2.
; range(Number(start_opt), Number(stop_opt)) Buffer
# Returns a Buffer that views the given range of the same allocated byte buffer.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is the length of this buffer if undefined or omitted.
# &quot;start&quot; and &quot;stop&quot; may be negative numbers, in which case they correspond to an offset counting from this buffer's length.
# The length of &quot;range&quot; is 2.
; slice(Number(start_opt), Number(stop_opt)) Buffer
# Returns a Buffer with a new internal allocation, containing a copy of this buffer from &quot;start&quot; to &quot;stop&quot; offsets.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is this buffer's length if undefined or omitted.
# &quot;start&quot; and &quot;stop&quot; may be negative numbers, in which case they correspond to an offset counting from this buffer's length.
; copy(target, Number(targetStart_opt), Number(start_opt)), Number(stop_opt)) Buffer
# Copies the Number values of each byte from this between &quot;start&quot; and &quot;stop&quot; to a &quot;target&quot; Buffer or Array at the &quot;targetStart&quot; offset.
# &quot;stop&quot; is the length of this if undefined or omitted.
# &quot;targetStart&quot;, &quot;start&quot;, and &quot;stop&quot; are internally coerced to Numbers with the Number constructor.
# &quot;targetStart&quot; may be negative, in which case it corresponds to an offset counting from the length of the target.
# &quot;start&quot; and &quot;stop&quot; may be negative, in which case they correspond to an offset counting from this buffer's length.
# Throws a TypeError if the target is not a Buffer or Array.
# Returns this.
; copyFrom(source, Number(sourceStart_opt), Number(start_opt), Number(stop_opt)) Buffer
# Copies the Number values of each byte from a given Buffer or Array into this from &quot;start&quot; to &quot;stop&quot; from the given &quot;sourceStart&quot; offset.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is the length of this buffer if undefined or omitted.
# &quot;sourceStart&quot; may be negative, in which case it corresponds to an offset counting from this buffer's length.
# &quot;start&quot; and &quot;stop&quot; may be negative, in which case they correspond to offsets counting from the length of the source.
# &quot;sourceStart&quot;, &quot;start&quot;, and &quot;stop&quot; are internally coerced to Numbers with the Number constructor.
# If the source is an Array, all values of that array are coerced to Numbers and masked with 0xFF.
# Throws a TypeError if the target is not a Buffer or Array.
# Returns this.
; read(String(charset), state Object, Number(start_opt), Number(stop_opt)) String
# Decodes as many complete and well formed character codes as possible between &quot;start&quot; and &quot;stop&quot; to a String from the given character set.
# &quot;charset&quot; must be one of &quot;UTF-8&quot;, &quot;UTF-16&quot;, &quot;ISO-8859-1&quot;, &quot;ASCII&quot;, &quot;BINARY&quot;.  Any other &quot;charset&quot; throws a RangeError.
# Assumes that the given byte range begins at the beginning of a code point.
# Stops decoding after the last complete code point byte sequence.
# Returns the decoded String.
# Sets the &quot;bytes&quot; property of the &quot;state&quot; object to the number of bytes transcoded.
# Sets the &quot;characters&quot; property of the &quot;state&quot; object to the number of characters transcoded.
# Sets the &quot;error&quot; property of the &quot;state&quot; object to &quot;malformed&quot; if reading stops at the beginning of a malformed byte sequence.
# The actual stop offset must be either equal to &quot;stop&quot; or at the beginning of the first incomplete code point byte sequence.
; write(source String, String(charset), state Object, Number(start_opt), Number(stop_opt)) Number
# Encodes as much as possible of a String in a given character set into this buffer from &quot;source&quot; to &quot;stop&quot;, using the source string, and returns the actual stop index of the source string.
# &quot;charset&quot; must be one of &quot;UTF-8&quot;, &quot;UTF-16&quot;, &quot;ISO-8859-1&quot;, &quot;ASCII&quot;, &quot;BINARY&quot;.  Any other &quot;charset&quot; throws a RangeError.
# &quot;start&quot; is 0 if undefined or omitted and measures bytes.
# &quot;stop&quot; is this buffer's length if undefined or omitted, measured in bytes.
# &quot;start&quot; and &quot;stop&quot; may be negative, in which case they correspond to offsets counting from the length of the source.
# Sets the &quot;characters&quot; property of the &quot;state&quot; object to the number of characters encoded.
# Sets the &quot;bytes&quot; property of the &quot;state&quot; object to the number of bytes written.
# Returns the number of bytes written.
; fill(Number(value), Number(start_opt), Number(stop_opt)) Buffer
# Fills all of this buffer's bytes with the given value as a Number from the &quot;start&quot; offset to the &quot;stop&quot; offset.
# &quot;start&quot; is 0 if undefined or omitted.
# &quot;stop&quot; is the length of this buffer if undefined or omitted.
# &quot;start&quot; and &quot;stop&quot; may be negative, in which case they correspond to offsets counting from the length of this buffer.
# &quot;value&quot; is 0 if undefined or omitted.
# &quot;value&quot; is coerced to Number and masked with 0xFF.
# Returns this.
; Content
# an alias of Number, indicating that Number is the type of what &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; returns.

== Internal Properties ==

; &lt;nowiki&gt;[[Get]]&lt;/nowiki&gt; Number
# Returns the Number value of a the byte at the given offset.
; &lt;nowiki&gt;[[Put]]&lt;/nowiki&gt; Number
# Sets the byte value at the given offset.
# Throws a RangeError if the index is beyond the current bounds of the buffer.
# Implicitly coerces the value to a Number and masks it with 0xFF.

== Instance Properties ==

; length
# The length in bytes.
# Not &lt;nowiki&gt;[[Configurable]]&lt;/nowiki&gt;, not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt;.  &lt;nowiki&gt;[[ReadOnly]]&lt;/nowiki&gt;.

== Notation ==

# The notation &lt;nowiki&gt;functionName(argument Type)&lt;/nowiki&gt; indicates that the given behavior only occurs when the argument pattern matches the given &quot;Type&quot;.
# If the &lt;nowiki&gt;functionName(argument Type)&lt;/nowiki&gt; is mentioned for an argument and none of the given forms match the types of the argument, the function must throw a TypeError.
# The notation &lt;nowiki&gt;functionName(argument_opt)&lt;/nowiki&gt; indicates that the argument may be undefined or omitted.
# The distinction between an omitted or undefined argument is only detectable by checking the &lt;code&gt;arguments.length&lt;/code&gt;
# The notation &lt;nowiki&gt;function(Type(argument))&lt;/nowiki&gt; implies that any type matches the argument and that it must be internally coerced to the &quot;Type&quot;.
# Extra arguments are ignored.

== General Requirements ==

# All of the properties specified on prototypes are not &lt;nowiki&gt;[[Enumerable]]&lt;/nowiki&gt; on instances.
# All operations that copy values to a byte in the byte buffer implicitly coerce the value to a Number and bit mask such values with 0xFF.

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/f8ad81201f7b121b ByteArray and ByteString proposal]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a8d3a91af37fd355 ByteArray: byteAt method]
* [http://groups.google.com/group/commonjs/browse_thread/thread/45190ac89d7b422a Binary/B Extension Proposals and Implementation Notes]
* [http://groups.google.com/group/commonjs/browse_thread/thread/98c51580a47e855e Binary D ready for review]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f609c72c9749e2c3 Binary/D Draft 2]</text>
    </revision>
  </page>
  <page>
    <title>User talk:Luoliwe</title>
    <id>382</id>
    <revision>
      <id>2138</id>
      <timestamp>2010-03-04T09:03:20Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Replaced content with 'Redacted SPAM.'</comment>
      <text xml:space="preserve">Redacted SPAM.</text>
    </revision>
  </page>
  <page>
    <title>Binary/F/Wes</title>
    <id>383</id>
    <revision>
      <id>2139</id>
      <timestamp>2010-03-06T10:01:57Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Created page with 'The following is a proposal to revise [[Binary/F]] by Wes Garland for the handling of transcoding.  = Design Notes =  * The basic idea is that the binary API needs  ** fast conve…'</comment>
      <text xml:space="preserve">The following is a proposal to revise [[Binary/F]] by Wes Garland for the handling of transcoding.

= Design Notes =

* The basic idea is that the binary API needs 
** fast conversion between Unicode buffers and Strings, without forcing intermediary object allocation
** Simple line-oriented character set encoding/decoding (iconv charsets)
** More complicated charset work (non-Unicode byte streams) should be pushed into Encodings API
* Observations:
** All Unicode encodings sets can represent 100% of Unicode
** It is possible to transcode &quot;bad&quot; Unicode from one encoding to another
** Correcly transcoding between UTF-8, -16 and -32 can be implemented by an average programmer without difficulty or the need for libiconv
** All Unicode encodings &quot;know&quot; how many code points are required to represent an entire character by looking at only the first code point. This makes handling truncated sequences possible.
* The reason I have added the optional Object o to some function signatures is to allow multiple out parameters without incurring new object construction overhead.
* The way JavaScript Strings are treated in this specification fragment makes it possible and reasonable for implementations that have underlying UTF-8 Strings (like v8) to implement utf8-buffer -&gt; String without any actual conversion.

The Unicode character sets, for the purposes of this specification are:

* UTF-8
* UTF-16
* UTF-32

UCS-4 will be accepted as an alias for UTF-32. UCS-2 and UTF-7 are not supported by the &quot;Unicode&quot; functions, although may be recognized as non-special character sets.

In this specification, Strings will be considered to be UTF-16, encoded with the native byte order, with no leading BOM. This is equivalent to the iconv encoding UTF-16BE on Big-Endian machines and UTF-16LE on Little Endian machines. This consideration does not reflect actual implementation detail in the underlying engine, but rather the view offered to script.

For performance reasons, this specification does not require implementations to perform transcoding validation when converting between Unicode character sets; instead, it is acceptable to transcode invalid code points from one Unicode encoding to another. Implementations are, however, encouraged to provide a method for performing transcoding validation for at least debugging builds of the underlying platform.

== Definitions ==

; Encode: to transform a String to a byte-oriented buffer
; Decode: to transform a byte-oriented buffer into a String
; Transcode: to transform one byte-oriented buffer into another


== Constructor Methods ==

; Object Buffer(String string, String charset, [Number length])
* creates and returns a new Object having a buffer of length bytes. If length is unspecified, the buffer will be exactly big enough to hold the encoded data
* string is encoded to the character set identified by charset in the new buffer
* throws an Error if encode fails, even if failure is due to under-sized buffer
* if buffer is undersized and charset is a Unicode character set, the Error object will be augmented with a &quot;commonjs.binary.encode_buffer_underrun&quot; property indicating how many more bytes would have been required to succeed
* if buffer is undersized and charset is not a Unicode character set (but is a valid iconv character set), the Error object will be augmented with a &quot;commonjs.binary.encode_buffer_underrun&quot; property having an undefined value

== Static Methods ==

; Object unicodeTranscode({Object buffer, [String charset, [Number offset, [Number length]]]} target, {Object buffer, [String charset, [Number offset, [Number length]]]} source, [Object o])
* Copies from source's buffer to target's buffer, transcoding from one Unicode character set to another, returning an object o
* The default values for charset, offset, and length are &quot;UTF-8&quot;, 0, and buffer.length for both source and target
* Transcode behaviour is unspecified if source === target and the ranges [source.offset...source.offset + length] and [target.offset...target.offset + length] overlap
* Transcode input is source.buffer[offset] through source.buffer[offset+length]; only entire characters are transcoded; a trailing partial character is not an error
* o.encoded holds the number of bytes from source.buffer which were transcoded by this operation
* o.used holds the number of bytes written into the target.buffer by this operation
* transcoding errors will throw an exception, with the Error object augmented with a &quot;commonjs.binary.transcode_error_offset&quot; property containing the position in the source buffer which held the leading byte of the unencodeable character
* The contents of o.encoded and o.used are unaffected if this function throws an exception
* No properties other than o.encoded and o.used will be affected by this method

== Instance Methods ==

; String toString([String charset, [Number offset, [Number length]]])
* decodes this buffer, starting at byte offset for length bytes, as though this buffer was encoded with the character set identified by charset, returning a new String
* The default values for charset, offset, and length are &quot;UTF-8&quot;, 0, and this.length respectively.
* This routine operates only on whole strings; truncated Unicode characters are to be treated as transcoding errors
* A transcoding error will throw an exception, with the Error object augmented with a &quot;commonjs.binary.transcode_error_offset&quot; property 
* If charset identifies a Unicode character set, Error[&quot;commonjs.binary.transcode_error_offset&quot;] will contain the number of bytes between the first byte to be decoded and the leading byte of the encoded character which could not be decoded. For example, a buffer containing a three-byte UTF-8 sequence with a corrupted third byte would set Error[&quot;commonjs.binary.transcode_error_offset&quot;] to 0.
* If charset does not identify a Unicode character set, Error[&quot;commonjs.binary.transcode_error_offset&quot;] will have an undefined value.
; String unicodeToString([String charset, [Number offset, [Number length, [Object o]]]])
* decodes this buffer, starting at byte offset for length bytes, as though this buffer was encoded with the character set identified by charset, returning a new String
* The default values for charset, offset, and length are &quot;UTF-8&quot;, 0, and this.length respectively.
* Specifying a non-Unicode character set name in charset will cause this function to throw an Error
* Only entire characters are decoded - a trailing partial character is not an error
* o.encoded holds the number of bytes from this buffer which were decoded by this operation
* Decoding error will throw an exception, with the Error object augmented with a &quot;commonjs.binary.transcode_error_offset&quot; property containing the position in this buffer which held the leading byte of the unencodeable character
* The contents of o.encoded is unaffected if this function throws an exception
* No properties other than o.encoded will be affected by this method
; Object unicodeFromString(String string, [String charset, [Number offset, [Number length, [Object o]]]]) 
* encodes this buffer, starting at byte offset for at most length bytes, encoding string to the character set identified by charset, returning the object o
* The default values for charset, offset, length, and o are &quot;UTF-8&quot;, 0, this.length, and {} respectively
* Specifying a non-Unicode character set in charset will cause this function to throw an Error
* o.encoded holds the number of characters encoded from String
* o.used holds the number of bytes written into this buffer by this operation
* Only complete characters will be decoded: a string whose last position contains the first half of a surrogate pair will have o.encoded === string.length - 1. This is not an error condition.
* transcoding error will throw an exception, with the Error object augmented with a &quot;commonjs.binary.transcode_error_offset&quot; property containing the position in string which held the unencodeable character
* The contents of o.encoded and o.used are unaffected if this function throws an exception
* No properties other than o.encoded and o.used will be affected by this method</text>
    </revision>
  </page>
  <page>
    <title>Logos</title>
    <id>384</id>
    <revision>
      <id>2405</id>
      <timestamp>2010-03-15T19:13:31Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <text xml:space="preserve">* Proposal A http://wiki.commonjs.org/images/b/bc/Wiki.png Daniel Friesen
* Proposal B http://commonjs.org/images/logo.png Kevin Dangoor
* Proposal C http://brevityos.org/common-js-logo.html Alexander Teinum
* Proposal D http://www.users.abo.fi/kherler/commonjs/logo.png Karl Herler
* Proposal E http://wiki.commonjs.org/wiki/File:Commonjs-zach.png Zach Carter
* Proposal F http://deanlandolt.com/cjs-logo.svg Dean Landolt
* Proposal G http://dl.dropbox.com/u/1688099/commonjs.png [png] http://dl.dropbox.com/u/1688099/commonjs.svg [svg]
* Proposal H http://wiki.commonjs.org/wiki/File:Logos_Common_JS.jpg Mario Valente - 1st and 2ns with a rhino. Could be a monkey. Or both :-)... 3rd one based on a stylized coffee bean
* Proposal I http://wiki.commonjs.org/wiki/File:AP_CommonJS.jpg Mario Valente - Based on a stylized coffee cup
* Proposal J http://wiki.commonjs.org/wiki/File:Common_JS_2leva.jpg Mario Valente - First couple based on the hedgehog/Array concept. 2nd one based on a bee for the &quot;working community&quot; concept. 4th one is just a plain &quot;community&quot; symbol.
* Proposal K http://www.page.ca/~wes/coffee-cjs.jpg Mario Valente 99.999% Wes Garland 0.001% - Variant on I with coffee ring forming letter C so that badge says CJS
* Proposal L http://wiki.commonjs.org/wiki/File:AP_CommonJS_2.jpg Proposal K, with designer finishing</text>
    </revision>
  </page>
  <page>
    <title>File:Commonjs-zach.png</title>
    <id>385</id>
    <revision>
      <id>2151</id>
      <timestamp>2010-03-10T15:38:37Z</timestamp>
      <contributor>
        <username>ZachCarter</username>
        <id>23</id>
      </contributor>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Logos Common JS.jpg</title>
    <id>386</id>
    <revision>
      <id>2155</id>
      <timestamp>2010-03-12T13:23:02Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <comment>CommonJS logo proposals
1st and 2nd one with rhino. Could be a monkey... Or both :-)
3rd one is based on a stylized coffee bean</comment>
      <text xml:space="preserve">CommonJS logo proposals
1st and 2nd one with rhino. Could be a monkey... Or both :-)
3rd one is based on a stylized coffee bean</text>
    </revision>
  </page>
  <page>
    <title>File:AP CommonJS.jpg</title>
    <id>387</id>
    <revision>
      <id>2156</id>
      <timestamp>2010-03-12T13:24:06Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <comment>CommonJS logo proposal. Based on a stylized coffee cup stain.</comment>
      <text xml:space="preserve">CommonJS logo proposal. Based on a stylized coffee cup stain.</text>
    </revision>
  </page>
  <page>
    <title>File:Common JS 2leva.jpg</title>
    <id>388</id>
    <revision>
      <id>2160</id>
      <timestamp>2010-03-12T18:21:03Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <comment>Another bunch of proposals for the CommonJS logo. The first two are based on the &quot;Hedgehog&quot; idea (a String of Hedgehogs). The 3rd one uses a &quot;bee&quot; (for the working community effect). The 4th one is just a plain &quot;community&quot; symbol.</comment>
      <text xml:space="preserve">Another bunch of proposals for the CommonJS logo. The first two are based on the &quot;Hedgehog&quot; idea (a String of Hedgehogs). The 3rd one uses a &quot;bee&quot; (for the working community effect). The 4th one is just a plain &quot;community&quot; symbol.</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Narwhal</title>
    <id>389</id>
    <revision>
      <id>2386</id>
      <timestamp>2010-03-15T12:03:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=Narwhal
|url=http://github.com/tlrobinson/narwhal
|engines=Rhino, v8, JSC
|authors=Tlrobinson, KrisKowal
}}</text>
    </revision>
  </page>
  <page>
    <title>Template:Implementation</title>
    <id>390</id>
    <revision>
      <id>2473</id>
      <timestamp>2010-03-19T08:55:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">;Name: [[Name::{{{name|}}}]]
;URL: [[URL::{{{url|}}}]]
;Engine(s): {{#arraymap:{{{engines|}}}|,|!|[[Engine::!]]}}
;Author(s): &lt;includeonly&gt;{{#arraymap:{{{authors|}}}|,|!|[[Author::User:!|{{author name|!}}]]}}&lt;/includeonly&gt;
;Implementations
{{#ask: [[Implementation of::+]] [[Implemented by::{{FULLPAGENAME}}]]
| mainlabel=-
| ?Implementation of=
| ?Implementation state=
| format=ul
}}
{{#declare:Description=description}}{{{description|}}}
&lt;includeonly&gt;[[Category:Implementations|{{{name|}}}]]&lt;/includeonly&gt;</text>
    </revision>
  </page>
  <page>
    <title>Category:Implementations</title>
    <id>391</id>
    <revision>
      <id>2472</id>
      <timestamp>2010-03-19T08:54:39Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">[[CommonJS]] [[implementations]].

See [[Special:BrowseData/Implementations]] for a drilldown.

[[Has default form::Form:Implementation| ]]

[[Has filter::Filter:Author| ]]
[[Has filter::Filter:Engine| ]]</text>
    </revision>
  </page>
  <page>
    <title>Property:Author</title>
    <id>392</id>
    <revision>
      <id>2167</id>
      <timestamp>2010-03-12T21:36:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::page]] property links to a author's userpage.'</comment>
      <text xml:space="preserve">This [[has type::page]] property links to a author's userpage.</text>
    </revision>
  </page>
  <page>
    <title>Property:Engine</title>
    <id>393</id>
    <revision>
      <id>2383</id>
      <timestamp>2010-03-15T12:02:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>moved [[Property:Embedding]] to [[Property:Engine]]</comment>
      <text xml:space="preserve">This [[has type::string]] property notes what engine is used by an implementation; SpiderMonkey/C, Rhino, etc...</text>
    </revision>
  </page>
  <page>
    <title>Property:Name</title>
    <id>394</id>
    <revision>
      <id>2169</id>
      <timestamp>2010-03-12T21:37:09Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::string]] property lists the name of something.'</comment>
      <text xml:space="preserve">This [[has type::string]] property lists the name of something.</text>
    </revision>
  </page>
  <page>
    <title>Property:URL</title>
    <id>395</id>
    <revision>
      <id>2173</id>
      <timestamp>2010-03-12T21:39:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">This [[has type::URL]] property links to something's website.</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Flusspferd</title>
    <id>396</id>
    <revision>
      <id>2381</id>
      <timestamp>2010-03-15T12:00:46Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=Flusspferd
|url=http://flusspferd.org/
|engines=Spidermonkey/C++
|authors=Ashb, Aristid, Ruediger
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/RingoJS</title>
    <id>397</id>
    <revision>
      <id>2388</id>
      <timestamp>2010-03-15T12:03:39Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=RingoJS
|url=http://ringojs.org/
|engines=Rhino
|authors=Hannesw
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/v8cgi</title>
    <id>398</id>
    <revision>
      <id>2479</id>
      <timestamp>2010-03-19T10:41:31Z</timestamp>
      <contributor>
        <username>Ondras</username>
        <id>57</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=v8cgi
|url=http://code.google.com/p/v8cgi/
|engines=v8
|authors=Ondras
|description=V8 embedding written in C++. Aims for webpage development scenarios, high CommonJS compliance and ease of use.
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/GPSEE</title>
    <id>399</id>
    <revision>
      <id>2482</id>
      <timestamp>2010-03-19T16:15:17Z</timestamp>
      <contributor>
        <username>Hdon</username>
        <id>101</id>
      </contributor>
      <comment>added myself as an author</comment>
      <text xml:space="preserve">{{Implementation
|name=GPSEE
|url=http://code.google.com/p/gpsee/
|engines=SpiderMonkey/C
|authors=Wesgarland,hdon
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Chiron</title>
    <id>400</id>
    <revision>
      <id>2483</id>
      <timestamp>2010-03-19T18:13:35Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <text xml:space="preserve">Chiron has been refactored as a Narwhal package and no longer has its own [[Modules/1.0]] implementation.

- [[User:KrisKowal|Kris Kowal]]</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Persevere</title>
    <id>401</id>
    <revision>
      <id>2387</id>
      <timestamp>2010-03-15T12:03:35Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=Persevere
|url=http://www.persvr.org/
|engines=Rhino
|authors=Kriszyp
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/node.js</title>
    <id>402</id>
    <revision>
      <id>2390</id>
      <timestamp>2010-03-15T12:04:04Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=node.js
|url=http://nodejs.org/
|engines=v8
|authors=Ry
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/SproutCore</title>
    <id>403</id>
    <revision>
      <id>2389</id>
      <timestamp>2010-03-15T12:03:45Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=SproutCore 1.1/Tiki
|url=http://www.sproutcore.com/
|engines=web browsers
|authors=CharlesJolley
}}</text>
    </revision>
  </page>
  <page>
    <title>Template:Implementation-short</title>
    <id>404</id>
    <revision>
      <id>2396</id>
      <timestamp>2010-03-15T12:08:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">[[{{{1}}}|{{{2}}}]] ({{{3}}}; {{#arraymap:{{{4}}}|,|!|[[!|{{author name from page|!}}]]}})</text>
    </revision>
  </page>
  <page>
    <title>Implementations</title>
    <id>405</id>
    <revision>
      <id>2729</id>
      <timestamp>2010-04-25T00:35:09Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{#ask: [[Category:Implementations]]
|?Name
|?Engine
|?Author
|format=ul
|template=implementation-short
|link=none
}}

;Identifiers: {{#ask: [[Category:Implementations]] | template=page to identifier | link=none }}

{{#forminput:Implementation| |&lt;identifier&gt;|Add implementation|super_page=Implementations}}

== See also ==
* [[:Category:Implementations|The category]]
* [[Special:BrowseData/Implementations|The drilldown page]]</text>
    </revision>
  </page>
  <page>
    <title>Template:Page to identifier</title>
    <id>406</id>
    <revision>
      <id>2187</id>
      <timestamp>2010-03-12T22:05:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '{{SUBPAGENAME:{{{1}}}}}'</comment>
      <text xml:space="preserve">{{SUBPAGENAME:{{{1}}}}}</text>
    </revision>
  </page>
  <page>
    <title>Template:Spec</title>
    <id>407</id>
    <revision>
      <id>2456</id>
      <timestamp>2010-03-19T07:58:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{#if:{{NAMESPACE}}||{{#if:{{{by|}}}|{{#switch:{{uc:{{{status}}}}}|SUPERSEDED=[[Superseded by::{{#ifexist:{{BASEPAGENAME}}/{{{by}}}|{{BASEPAGENAME}}/{{{by}}}|{{{by}}}}}| ]]}}}}
'''STATUS: {{uc:{{{status}}}}}{{#if:{{{by|}}}|&lt;nowiki/&gt; BY {{#ifexist:{{BASEPAGENAME}}/{{{by}}}|[[{{BASEPAGENAME}}/{{{by}}}|{{{by}}}]]|[[{{{by}}}]]}}}}'''
{{#declare:Published=published}}[[Is standard::{{#ifeq:{{{standard|}}}|yes|Yes|No}}| ]]{{#if:{{{participants|}}}|
;Pardicipants:
:{{{participants}}} ([{{{discussion}}} Discussion])
}}{{#if:{{{implementations|}}}|[[Has implementations::yes| ]]
;Implementations: {{#arraymap:{{{implementations}}}|,|!|{{#if:{{#explode:!|=|1}}|{{Spec/implementation|implementation={{#explode:!|=|0}}|state={{#explode:!|=|1}}}}|{{Spec/implementation|implementation=!|state=yes}}}}}}}}
&lt;includeonly&gt;[[Category:Spec]]&lt;/includeonly&gt;
}}{{#if:{{{draft|}}}|
* Draft {{{draft|}}}}}{{#if:{{{drafts|}}}|{{#arraymap:{{{drafts}}}|,|!|
* [{{fullurl:{{FULLPAGENAME}}|oldid={{#explode:!|:|1}}}} Draft {{#explode:!|:|0}}]| }}}}</text>
    </revision>
  </page>
  <page>
    <title>Template:Implementation name</title>
    <id>409</id>
    <revision>
      <id>2204</id>
      <timestamp>2010-03-12T22:33:11Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{#show:Implementations/{{{1|-}}}|?Name}}</text>
    </revision>
  </page>
  <page>
    <title>Template:Implementation link</title>
    <id>410</id>
    <revision>
      <id>2205</id>
      <timestamp>2010-03-12T22:34:25Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '[[Implementations/{{{1}}}|{{implementation name|{{{1}}}}}]]'</comment>
      <text xml:space="preserve">[[Implementations/{{{1}}}|{{implementation name|{{{1}}}}}]]</text>
    </revision>
  </page>
  <page>
    <title>Category:Spec</title>
    <id>411</id>
    <revision>
      <id>2214</id>
      <timestamp>2010-03-12T22:46:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '[[CommonJS]] specs.'</comment>
      <text xml:space="preserve">[[CommonJS]] specs.</text>
    </revision>
  </page>
  <page>
    <title>Template:Spec/implementation</title>
    <id>412</id>
    <revision>
      <id>2366</id>
      <timestamp>2010-03-15T07:51:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;includeonly&gt;{{implementation link|{{{implementation}}}}}{{#ifeq:{{{state|yes}}}|yes||&lt;nowiki/&gt; ({{{state|yes}}})}}&lt;!--
--&gt;{{#set_internal:Implementation of
|Implemented by=Implementations/{{{implementation}}}
|Implementation state={{{state|yes}}}
}}&lt;!--
--&gt;&lt;/includeonly&gt;</text>
    </revision>
  </page>
  <page>
    <title>Property:Implementation of</title>
    <id>413</id>
    <revision>
      <id>2220</id>
      <timestamp>2010-03-13T00:34:40Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::page]] property notes what spec an implementation internal object implements.'</comment>
      <text xml:space="preserve">This [[has type::page]] property notes what spec an implementation internal object implements.</text>
    </revision>
  </page>
  <page>
    <title>Property:Implemented by</title>
    <id>414</id>
    <revision>
      <id>2221</id>
      <timestamp>2010-03-13T00:35:05Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::page]] property notes what implementation an implementation internal object is implemented by.'</comment>
      <text xml:space="preserve">This [[has type::page]] property notes what implementation an implementation internal object is implemented by.</text>
    </revision>
  </page>
  <page>
    <title>Property:Implementation state</title>
    <id>415</id>
    <revision>
      <id>2223</id>
      <timestamp>2010-03-13T00:35:42Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">This [[has type::string]] property notes what state of implementation an implementation internal object is at.</text>
    </revision>
  </page>
  <page>
    <title>User:Dantman</title>
    <id>416</id>
    <revision>
      <id>2225</id>
      <timestamp>2010-03-13T00:41:24Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with ''''[[Real Name::Daniel Friesen]]''' (also known as Dantman or Nadir-Seen-Fire)  ;Homepage : [http://daniel.friesen.name/ daniel.friesen.name] ;E-Mail : [mailto:nadir.seen.fire@gm…'</comment>
      <text xml:space="preserve">'''[[Real Name::Daniel Friesen]]''' (also known as Dantman or Nadir-Seen-Fire)

;Homepage
: [http://daniel.friesen.name/ daniel.friesen.name]
;E-Mail
: [mailto:nadir.seen.fire@gmail.com nadir.seen.fire@gmail.com]
;IRC@freenode.net
: Dantman, DanielFriesen, Nadir_Seen_Fire</text>
    </revision>
  </page>
  <page>
    <title>Property:Real Name</title>
    <id>417</id>
    <revision>
      <id>2226</id>
      <timestamp>2010-03-13T00:42:21Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::string]] property lists the real name of a user.'</comment>
      <text xml:space="preserve">This [[has type::string]] property lists the real name of a user.</text>
    </revision>
  </page>
  <page>
    <title>Template:Author name</title>
    <id>418</id>
    <revision>
      <id>2231</id>
      <timestamp>2010-03-13T00:51:38Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;includeonly&gt;{{or|{{#show:User:{{{1}}}| ?Real Name }}|{{{1}}}}}&lt;/includeonly&gt;</text>
    </revision>
  </page>
  <page>
    <title>Template:Or</title>
    <id>419</id>
    <revision>
      <id>2232</id>
      <timestamp>2010-03-13T00:52:26Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '{{#if:{{{1|}}}|{{{1}}}|{{{2}}}}}'</comment>
      <text xml:space="preserve">{{#if:{{{1|}}}|{{{1}}}|{{{2}}}}}</text>
    </revision>
  </page>
  <page>
    <title>User:Ashb</title>
    <id>420</id>
    <revision>
      <id>2234</id>
      <timestamp>2010-03-13T02:28:35Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '[[Real Name::Ash Berlin| ]]'</comment>
      <text xml:space="preserve">[[Real Name::Ash Berlin| ]]</text>
    </revision>
  </page>
  <page>
    <title>CommonJS:Sandbox</title>
    <id>421</id>
    <revision>
      <id>2457</id>
      <timestamp>2010-03-19T08:05:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">;Implementations
{{#ask: [[Implementation of::+]] [[Implemented by::Implementations/Flusspferd]]
| mainlabel=-
| ?Implementation of=
| ?Implementation state=
| format=ul
}}
----
{{:CommonJS:Sandbox/table
|standards={{#ask: [[Category:Spec]] [[Is standard::yes]] | link=none }}
|non-standards={{#ask: [[Category:Spec]] [[Is standard::no]] [[Has implementations::yes]] | link=none }}
}}
----
{{#ask: [[Category:Implementations]]
| mainlabel=-
| ?Name=
| format=ul
}}
----
{{#ask: [[Implementation of::+]] [[Implemented by::+]]
| mainlabel=-
| ?Implemented by=
| ?Implementation of=
| ?Implementation state=
| format=ul
}}</text>
    </revision>
  </page>
  <page>
    <title>Website:Index</title>
    <id>422</id>
    <revision>
      <id>2427</id>
      <timestamp>2010-03-17T09:11:27Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">= CommonJS =
JavaScript is a powerful object oriented language with some of the fastest dynamic language interpreters around. The official JavaScript specification defines APIs for some objects that are useful for building browser-based applications. However, the spec does not define a standard library that is useful for building a broader range of applications.

The CommonJS API will fill that gap by defining APIs that handle many common application needs, ultimately providing a standard library as rich as those of Python, Ruby and Java. The intention is that an application developer will be able to write an application using the CommonJS APIs and then run that application across different JavaScript interpreters and host environments. With CommonJS-compliant systems, you can use JavaScript to write:
* Server-side JavaScript applications
* Command line tools
* Desktop GUI-based applications
* Hybrid applications (Titanium, Adobe AIR)
Read an [http://arstechnica.com/web/news/2009/12/commonjs-effort-sets-javascript-on-path-for-world-domination.ars additional introduction by Kris Kowal at Ars Technica].

== More information about CommonJS ==
* [[/specs|Specifications and proposals]]
* [[/impl|Implementations]]
* [[/process|Group Process]]
* [[/history|Project History]]</text>
    </revision>
  </page>
  <page>
    <title>Website:Redirects</title>
    <id>423</id>
    <revision>
      <id>2431</id>
      <timestamp>2010-03-17T09:24:35Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirect the old 0.1 and 0.5 pages to the new /specs/ page.</comment>
      <text xml:space="preserve">* /(.+/|)index.html -&gt; /$1
* /(.+).html -&gt; /$1/
* /specs/0\.[15](/.+)? -&gt; /specs/</text>
    </revision>
  </page>
  <page>
    <title>Website:Home</title>
    <id>424</id>
    <revision>
      <id>2249</id>
      <timestamp>2010-03-13T05:56:58Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Website:Home]] to [[Website:Index]]</comment>
      <text xml:space="preserve">#REDIRECT [[Website:Index]]</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/specs/0.1</title>
    <id>425</id>
    <revision>
      <id>2429</id>
      <timestamp>2010-03-17T09:22:01Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Replaced content with '&lt;--404--&gt;'</comment>
      <text xml:space="preserve">&lt;--404--&gt;</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/specs/modules/1.0</title>
    <id>426</id>
    <revision>
      <id>2257</id>
      <timestamp>2010-03-13T06:16:49Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">= CommonJS Modules =
{{:Modules/1.0}}
__NOTOC__</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/specs/0.5</title>
    <id>427</id>
    <revision>
      <id>2430</id>
      <timestamp>2010-03-17T09:22:24Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Replaced content with '&lt;--404--&gt;'</comment>
      <text xml:space="preserve">&lt;--404--&gt;</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/impl</title>
    <id>428</id>
    <revision>
      <id>2468</id>
      <timestamp>2010-03-19T08:49:41Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">= Getting CommonJS =
There are several implementations of the CommonJS standard, and you can choose the one that fits what you're trying to do.

{{#ask: [[Category:Implementations]]
| ?Name | ?URL | ?Engine | ?Author | ?Description
| format=template | template=Website:Implementation template | link=none }}

__NOTOC__</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/process</title>
    <id>429</id>
    <revision>
      <id>2260</id>
      <timestamp>2010-03-13T07:31:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Another page coppied from CommonJS.org</comment>
      <text xml:space="preserve">= CommonJS Process =
The CommonJS group has, to date, operated in an informal manner. Our goal is to make meaningful progress toward these goals:
# Design reasonable APIs for common application needs
# Document those designs
# Implement those designs in different interpreters and environments

The process followed through the development of CommonJS 0.5 has been:
# Discussion of an API area is started on the mailing list
# A page is created on the wiki to collect proposals and prior art
# Further discussion and iteration on the proposals
# A rough consensus is reached
# The proposal graduates from the wiki to this website

So far, achieving rough consensus among the group has been a successful route to meeting these goals. Everyone involved has interoperability on their mind and interop necessarily involves compromise and minimal [[Wikipedia:Parkinson's Law of Triviality|bikeshedding]].

As applications built upon the CommonJS APIs start appearing, we will likely need more process to handle changes to the API.

== Further reading ==
For an interesting take on API design from a highly regarded master, take a look at [http://www.youtube.com/watch?v=aAb7hSCtvGw this tech talk by Josh Bloch].</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/history</title>
    <id>430</id>
    <revision>
      <id>2261</id>
      <timestamp>2010-03-13T07:32:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '= CommonJS Project History = * January 2009: the group was formed as &quot;ServerJS&quot; following a blog post on Kevin Dangoor's Blue Sky on Mars * March 2009: the dust had settled aroun…'</comment>
      <text xml:space="preserve">= CommonJS Project History =
* January 2009: the group was formed as &quot;ServerJS&quot; following a blog post on Kevin Dangoor's Blue Sky on Mars
* March 2009: the dust had settled around &quot;securable modules&quot; as the module style for the group. This is CommonJS API 0.1
* April 2009: CommonJS modules were shown off with several implementations at the first JSConf in Washington, DC.
* August 2009: The group name was formally changed to CommonJS to reflect the broader applicability of the APIs.</text>
    </revision>
  </page>
  <page>
    <title>Website:Sidebar</title>
    <id>431</id>
    <revision>
      <id>2428</id>
      <timestamp>2010-03-17T09:14:47Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;div class=&quot;news-top&quot;&gt;
= Site Updates =
&lt;/div&gt;
&lt;div class=&quot;news_items&quot;&gt;
* // Formatting has been cleaned up around the site and on the [[Website:Index/specs/modules/1.0|Modules 1.0]] page.
* // This website has been replaced with a new one backed by the wiki so it can be edited by the whole commonjs community.
* // We are no longer using the bulk 0.1 and 0.5 specification version numbers. Specs individually are marked as standards.

= CommonJS Links =
* // [http://wiki.commonjs.org/ Wiki] (standards-in-training!)
* // [http://groups.google.com/group/commonjs/ Mailing list]
* // [http://twitter.com/commonjs Twitter]
* // [irc://irc.freenode.net/commonjs #commonjs on irc.freenode.net]
&lt;/div&gt;</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/contributors</title>
    <id>432</id>
    <revision>
      <id>2264</id>
      <timestamp>2010-03-13T07:49:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '= The CommonJS Contributors = Creating the CommonJS APIs has been a volunteer effort, and the people below have contributed their time and energy to creating a consensus around t…'</comment>
      <text xml:space="preserve">= The CommonJS Contributors =
Creating the CommonJS APIs has been a volunteer effort, and the people below have contributed their time and energy to creating a consensus around these APIs. Without working through the details and making compromises, we would never have standardized anything or seen any implementations come into existence.

The following people have contributed substantially to the work of creating the CommonJS APIs:
* Ihab Awad
* Ash Berlin
* Aristid Breitkreuz
* Kevin Dangoor
* Daniel Friesen
* Wes Garland
* Kris Kowal
* Dean Landolt
* Peter Michaux
* George Moschovitis
* Michael O'Brien
* Tom Robinson
* Hannes Wallnoefer
* Mike Wilson
* Ondrej Zara
* Chris Zumbrunn
* Kris Zyp

My apologies to any contributor whose name was omitted. With thousands of messages of discussion during 2009, there are many people who have come and pitched in to the project with their ideas.

Additionally, thanks are due to all of the people who have been involved in building the implementations of the CommonJS APIs. Many of the people on the list above are implementers, but there are many other people involved in their projects and many other projects that are not represented here.

Thanks to you all for making this project a success!</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/license</title>
    <id>433</id>
    <revision>
      <id>2267</id>
      <timestamp>2010-03-13T07:51:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">= CommonJS Documentation and Code License =
The output of the CommonJS group is protected under copyright laws, but is intended for the good of the JavaScript development community. CommonJS related projects are licensed under whatever terms the author(s) wish to apply, but the CommonJS specifications and test suites are all licensed under the MIT-style license presented below.

Copyright © 2009 - Kevin Dangoor and many [[../contributors/|CommonJS contributors]].

== License ==
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &quot;Software&quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</text>
    </revision>
  </page>
  <page>
    <title>Website:Style.css</title>
    <id>434</id>
    <revision>
      <id>2443</id>
      <timestamp>2010-03-19T06:58:06Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">@charset &quot;UTF-8&quot;;


/** css/styles.css **/
body {
	background-color: #3c3c3c;
	font-family: Helvetica, Arial, sans-serif;
	margin: 0px;
	padding: 0px;
	font-size: 14px;
	line-height: 18px;
}
.col_level {
	font-size: 0px;
	clear: both;
	height: 1px;
}


/* PAGE HEADER */

.header_wrapper {
	height: 107px;
	background-image: url(http://wiki.commonjs.org/images/1/19/Header_wrapper_bg.png);
	background-repeat: repeat-x;
}
.header_bg {
	width: 970px;
	margin-right: auto;
	margin-left: auto;
	height: 107px;
	background-image: url(http://wiki.commonjs.org/images/9/9c/Header_gradient.jpg);
	background-repeat: no-repeat;
	background-position: center;
}
.tagline {
	float: left;
	margin-left: 15px;
	line-height: 107px;
	font-size: 18px;
	color: #9f9f9f;
}
img.logo {
	float: left;
	margin-top: 24px;
	margin-left: 0px;
}
.nav_wrapper {
	float: right;
	height: 107px;
}
.nav_item {
	float: right;
	width: 125px;
	color: #FFFFFF;
	text-align: center;
	padding-top: 60px;
	height: 47px;
	font-size: 22px;
	font-weight: normal;
}
.nav_item a:link, .nav_item a:visited {
	color: #FFFFFF;
	text-decoration: none;
}
.nav_item a:hover {
	color: #CCCCCC;
}
.nav1 {
	background-image: url(http://wiki.commonjs.org/images/d/d0/Nav_js.png);
	background-repeat: repeat-x;
	background-position: bottom;
}
body.specs .nav1 { background-image: url(http://wiki.commonjs.org/images/7/73/Nav_js_on.png); /*turn on the corresponding nav item*/ }
.nav2 {
	background-image: url(http://wiki.commonjs.org/images/8/89/Nav_commonjs.png);
	background-repeat: repeat-x;
	background-position: bottom;
}
body.impl .nav2 { background-image: url(http://wiki.commonjs.org/images/6/67/Nav_commonjs_on.png); /*turn on the corresponding nav item*/ }
.nav3 {
	background-image: url(../images/nav_browsers.png);
	background-repeat: repeat-x;
	background-position: bottom;
}
.nav_div {
	float: right;
	background-image: url(http://wiki.commonjs.org/images/9/97/Nav_div.png);
	width: 1px;
	background-position: bottom;
	height: 107px;
	background-repeat: no-repeat;
}




/* PAGE BODY */

.content_wrapper {
	background-image: url(http://wiki.commonjs.org/images/a/a4/Content-wrapper_bg.png);
	background-repeat: repeat-x;
	background-color: #efefef;
}

.content_bg {
	width: 1000px;
	margin-right: auto;
	margin-left: auto;
	background-image: url(http://wiki.commonjs.org/images/1/1e/Content_bg.png);
	background-repeat: repeat-y;
}

.content {
	position: relative;
	background-image: url(http://wiki.commonjs.org/images/2/2c/Banner_home.jpg);
	background-repeat: no-repeat;
	background-position: center 11px;
}
body.status404 .content { background-image: url(http://wiki.commonjs.org/images/3/3a/Banner_gray.jpg) }
body.specs .content { background-image: url(http://wiki.commonjs.org/images/8/82/Banner_blue.jpg) }
body.impl .content { background-image: url(http://wiki.commonjs.org/images/9/99/Banner_green.jpg) }
.content-left {
	width: 680px;
	margin-left: 42px;
	margin-top: 180px;
	float: left;
	padding-bottom: 20px;
}
.content-left h1 {
	font-size: 28px;
	color: #863e3e;
	font-weight: normal;
	margin-top: 0px;
	margin-right: 0px;
	margin-bottom: 6px;
	margin-left: 0px;
}
body.status404 .content-left h1 { color: #ccc; }
body.specs .content-left h1 { color: #266790; /*change the color of page headers*/ }
body.impl .content-left h1 { color: #4e5d2e; /*change the color of page headers*/ }


/* NEWS */

.news_wrapper {
	width: 219px;
	right: 14px;
	float: right;
	margin-right: 27px;
	margin-top: 152px;
	font-size: 12px;
	line-height: 13px;
}
.news-top {
	background-image: url(http://wiki.commonjs.org/images/c/c6/News_bg-top.png);
	background-repeat: no-repeat;
	height: 25px;
	background-position: left top;
	padding-left: 24px;
	vertical-align: bottom;
	padding-top: 20px;
}
.news_items {
	background-image: url(http://wiki.commonjs.org/images/a/a9/News_bg-btm.png);
	background-repeat: no-repeat;
	background-position: left bottom;
	padding-left: 24px;
	color: #9d9d9d;
	padding-right: 12px;
}
.news_items ul {
	list-style: none;
	margin-left: 0;
	padding-left: 1em;
	text-indent: -.9em;
	margin-top: 0px;
}
.news_items li {
	margin-bottom: 8px;
	margin-left: 8px;
}
.news_items a:link, .news_items a:visited {
	color: #90d5ff;
	text-decoration: none;
}
.news_items a:hover {
	text-decoration: underline;
}
.news_wrapper  h1 {
	font-weight: normal;
	font-size: 16px;
	margin-bottom: 8px;
	color: #636363;
	margin-top: 0px;
}




/* PAGE FOOT */

.footer_wrapper {
	font-size: 10px;
	border-top-width: 10px;
	border-top-style: solid;
	border-top-color: #636363;
	text-align: center;
	padding-top: 10px;
	padding-bottom: 10px;
	color: #999999;
}
.footer_wrapper a { color: #bbb }
.footer_bg {
	width: 970px;
	margin-right: auto;
	margin-left: auto;
}

/** css/colorful.css **/
.codehilite .hll { background-color: #ffffcc }
.codehilite .c { color: #808080 } /* Comment */
.codehilite .err { color: #F00000; background-color: #F0A0A0 } /* Error */
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
.codehilite .o { color: #303030 } /* Operator */
.codehilite .cm { color: #808080 } /* Comment.Multiline */
.codehilite .cp { color: #507090 } /* Comment.Preproc */
.codehilite .c1 { color: #808080 } /* Comment.Single */
.codehilite .cs { color: #cc0000; font-weight: bold } /* Comment.Special */
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
.codehilite .ge { font-style: italic } /* Generic.Emph */
.codehilite .gr { color: #FF0000 } /* Generic.Error */
.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #00A000 } /* Generic.Inserted */
.codehilite .go { color: #808080 } /* Generic.Output */
.codehilite .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.codehilite .gs { font-weight: bold } /* Generic.Strong */
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.codehilite .gt { color: #0040D0 } /* Generic.Traceback */
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.codehilite .kp { color: #003080; font-weight: bold } /* Keyword.Pseudo */
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.codehilite .kt { color: #303090; font-weight: bold } /* Keyword.Type */
.codehilite .m { color: #6000E0; font-weight: bold } /* Literal.Number */
.codehilite .s { background-color: #fff0f0 } /* Literal.String */
.codehilite .na { color: #0000C0 } /* Name.Attribute */
.codehilite .nb { color: #007020 } /* Name.Builtin */
.codehilite .nc { color: #B00060; font-weight: bold } /* Name.Class */
.codehilite .no { color: #003060; font-weight: bold } /* Name.Constant */
.codehilite .nd { color: #505050; font-weight: bold } /* Name.Decorator */
.codehilite .ni { color: #800000; font-weight: bold } /* Name.Entity */
.codehilite .ne { color: #F00000; font-weight: bold } /* Name.Exception */
.codehilite .nf { color: #0060B0; font-weight: bold } /* Name.Function */
.codehilite .nl { color: #907000; font-weight: bold } /* Name.Label */
.codehilite .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.codehilite .nt { color: #007000 } /* Name.Tag */
.codehilite .nv { color: #906030 } /* Name.Variable */
.codehilite .ow { color: #000000; font-weight: bold } /* Operator.Word */
.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
.codehilite .mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */
.codehilite .mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */
.codehilite .mi { color: #0000D0; font-weight: bold } /* Literal.Number.Integer */
.codehilite .mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */
.codehilite .sb { background-color: #fff0f0 } /* Literal.String.Backtick */
.codehilite .sc { color: #0040D0 } /* Literal.String.Char */
.codehilite .sd { color: #D04020 } /* Literal.String.Doc */
.codehilite .s2 { background-color: #fff0f0 } /* Literal.String.Double */
.codehilite .se { color: #606060; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */
.codehilite .sh { background-color: #fff0f0 } /* Literal.String.Heredoc */
.codehilite .si { background-color: #e0e0e0 } /* Literal.String.Interpol */
.codehilite .sx { color: #D02000; background-color: #fff0f0 } /* Literal.String.Other */
.codehilite .sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */
.codehilite .s1 { background-color: #fff0f0 } /* Literal.String.Single */
.codehilite .ss { color: #A06000 } /* Literal.String.Symbol */
.codehilite .bp { color: #007020 } /* Name.Builtin.Pseudo */
.codehilite .vc { color: #306090 } /* Name.Variable.Class */
.codehilite .vg { color: #d07000; font-weight: bold } /* Name.Variable.Global */
.codehilite .vi { color: #3030B0 } /* Name.Variable.Instance */
.codehilite .il { color: #0000D0; font-weight: bold } /* Literal.Number.Integer.Long */

/** Geshi; We only use a few langs so we'll just hardcode them into the site styles **/
.source-javascript {line-height: normal;}
.source-javascript li, .source-javascript pre {
	line-height: normal; border: 0px none white;
}
/**
 * GeSHi Dynamically Generated Stylesheet
 * --------------------------------------
 * Dynamically generated stylesheet for javascript
 * CSS class: source-javascript, CSS id: 
 * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
 * (http://qbnz.com/highlighter/ and http://geshi.org/)
 * --------------------------------------
 */
.javascript.source-javascript .de1, .javascript.source-javascript .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
.javascript.source-javascript  {font-family:monospace;}
.javascript.source-javascript .imp {font-weight: bold; color: red;}
.javascript.source-javascript li, .javascript.source-javascript .li1 {font-weight: normal; vertical-align:top;}
.javascript.source-javascript .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
.javascript.source-javascript .li2 {font-weight: bold; vertical-align:top;}
.javascript.source-javascript .kw1 {color: #000066; font-weight: bold;}
.javascript.source-javascript .kw2 {color: #003366; font-weight: bold;}
.javascript.source-javascript .kw3 {color: #000066;}
.javascript.source-javascript .co1 {color: #006600; font-style: italic;}
.javascript.source-javascript .co2 {color: #009966; font-style: italic;}
.javascript.source-javascript .coMULTI {color: #006600; font-style: italic;}
.javascript.source-javascript .es0 {color: #000099; font-weight: bold;}
.javascript.source-javascript .br0 {color: #009900;}
.javascript.source-javascript .sy0 {color: #339933;}
.javascript.source-javascript .st0 {color: #3366CC;}
.javascript.source-javascript .nu0 {color: #CC0000;}
.javascript.source-javascript .me1 {color: #660066;}
.javascript.source-javascript .ln-xtra, .javascript.source-javascript li.ln-xtra, .javascript.source-javascript div.ln-xtra {background-color: #ffc;}
.javascript.source-javascript span.xtra { display:block; }


table.wikitable {
    margin: 1em 1em 1em 0;
    background: #f9f9f9;
    border: 1px #aaa solid;
    border-collapse: collapse;
}
table.wikitable th, .wikitable td {
    border: 1px #aaa solid;
    padding: 0.2em;
}
table.wikitable th {
    background: #f2f2f2;
    text-align: center;
}
table.wikitable caption {
    font-weight: bold;
}</text>
    </revision>
  </page>
  <page>
    <title>File:Website-Logo.png</title>
    <id>435</id>
    <revision>
      <id>2270</id>
      <timestamp>2010-03-13T08:11:59Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Website-Logo.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:News bg-top.png</title>
    <id>436</id>
    <revision>
      <id>2272</id>
      <timestamp>2010-03-13T08:20:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:News bg-top.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:News bg-btm.png</title>
    <id>437</id>
    <revision>
      <id>2293</id>
      <timestamp>2010-03-13T08:31:49Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:News bg-btm.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Nav js.png</title>
    <id>438</id>
    <revision>
      <id>2292</id>
      <timestamp>2010-03-13T08:31:45Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Nav js.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Nav div.png</title>
    <id>439</id>
    <revision>
      <id>2291</id>
      <timestamp>2010-03-13T08:31:41Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Nav div.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Nav commonjs.png</title>
    <id>440</id>
    <revision>
      <id>2290</id>
      <timestamp>2010-03-13T08:31:36Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Nav commonjs.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Header wrapper bg.png</title>
    <id>441</id>
    <revision>
      <id>2289</id>
      <timestamp>2010-03-13T08:31:32Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Header wrapper bg.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Header gradient.jpg</title>
    <id>442</id>
    <revision>
      <id>2288</id>
      <timestamp>2010-03-13T08:31:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Header gradient.jpg]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Content bg.png</title>
    <id>443</id>
    <revision>
      <id>2287</id>
      <timestamp>2010-03-13T08:31:23Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Content bg.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Content-wrapper bg.png</title>
    <id>444</id>
    <revision>
      <id>2286</id>
      <timestamp>2010-03-13T08:31:19Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Content-wrapper bg.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Banner home.jpg</title>
    <id>445</id>
    <revision>
      <id>2285</id>
      <timestamp>2010-03-13T08:31:14Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Banner home.jpg]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Banner gray.jpg</title>
    <id>446</id>
    <revision>
      <id>2283</id>
      <timestamp>2010-03-13T08:29:27Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Banner gray.jpg]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Banner blue.jpg</title>
    <id>447</id>
    <revision>
      <id>2301</id>
      <timestamp>2010-03-13T08:45:38Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Banner blue.jpg]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Banner green.jpg</title>
    <id>448</id>
    <revision>
      <id>2302</id>
      <timestamp>2010-03-13T08:46:08Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Banner green.jpg]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>Website:404</title>
    <id>450</id>
    <revision>
      <id>2304</id>
      <timestamp>2010-03-13T08:49:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '= 404 = Sorry the page you requested could not be found.'</comment>
      <text xml:space="preserve">= 404 =
Sorry the page you requested could not be found.</text>
    </revision>
  </page>
  <page>
    <title>File:Nav js on.png</title>
    <id>451</id>
    <revision>
      <id>2306</id>
      <timestamp>2010-03-13T08:59:03Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Nav js on.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>File:Nav commonjs on.png</title>
    <id>452</id>
    <revision>
      <id>2308</id>
      <timestamp>2010-03-13T09:03:23Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Protected &quot;[[File:Nav commonjs on.png]]&quot; ([edit=sysop] (indefinite) [move=sysop] (indefinite))</comment>
      <text xml:space="preserve" />
    </revision>
  </page>
  <page>
    <title>Filter:Author</title>
    <id>453</id>
    <revision>
      <id>2317</id>
      <timestamp>2010-03-13T12:00:02Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This filter covers the property [[Covers property::Author]].'</comment>
      <text xml:space="preserve">This filter covers the property [[Covers property::Author]].</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Revreview-status</title>
    <id>455</id>
    <revision>
      <id>2322</id>
      <timestamp>2010-03-13T13:14:47Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'Status'</comment>
      <text xml:space="preserve">Status</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Revreview-status-0</title>
    <id>456</id>
    <revision>
      <id>2323</id>
      <timestamp>2010-03-13T13:15:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'Unpublished'</comment>
      <text xml:space="preserve">Unpublished</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Revreview-status-1</title>
    <id>457</id>
    <revision>
      <id>2324</id>
      <timestamp>2010-03-13T13:15:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'Published'</comment>
      <text xml:space="preserve">Published</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Revreview-status-2</title>
    <id>458</id>
    <revision>
      <id>2327</id>
      <timestamp>2010-03-13T13:16:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">Pristine</text>
    </revision>
  </page>
  <page>
    <title>User:MrN</title>
    <id>459</id>
    <revision>
      <id>2340</id>
      <timestamp>2010-03-13T20:09:41Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[User:MrN]] to [[User:Aristid]]</comment>
      <text xml:space="preserve">#REDIRECT [[User:Aristid]]</text>
    </revision>
  </page>
  <page>
    <title>Website:Robots.txt</title>
    <id>460</id>
    <revision>
      <id>2345</id>
      <timestamp>2010-03-14T06:33:12Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with ' # &lt;pre&gt; # CommonJS.org Robots.txt   User-agent: * Disallow:   # &lt;/pre&gt;'</comment>
      <text xml:space="preserve"> # &lt;pre&gt;
# CommonJS.org Robots.txt 

User-agent: *
Disallow: 

# &lt;/pre&gt;</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Common.js</title>
    <id>462</id>
    <revision>
      <id>2353</id>
      <timestamp>2010-03-14T08:33:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">jQuery(function($) {
  var showDraft = wgCurRevisionId !== wgStableRevisionId &amp;&amp; wgViewRevisionId === wgCurRevisionId;
  if ( /^Website:Index(\/.+)?$/.test(wgPageName) ) {
    $(&quot;&lt;a class=website_link&gt;View on &quot;+(showDraft?&quot;draft &quot;:&quot;&quot;)+&quot;website&lt;/a&gt;&quot;).attr({href: wgPageName.replace(&quot;Website:Index&quot;, showDraft?&quot;http://draft.commonjs.org&quot;:&quot;http://commonjs.org&quot;)+&quot;/&quot;}).prependTo(&quot;#firstHeading&quot;);
  }
});</text>
    </revision>
  </page>
  <page>
    <title>Sandbox</title>
    <id>463</id>
    <revision>
      <id>2370</id>
      <timestamp>2010-03-15T11:00:16Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Redirected page to [[CommonJS:Sandbox]]</comment>
      <text xml:space="preserve">#REDIRECT [[Project:Sandbox]]</text>
    </revision>
  </page>
  <page>
    <title>Property:Embedding</title>
    <id>464</id>
    <revision>
      <id>2384</id>
      <timestamp>2010-03-15T12:02:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>moved [[Property:Embedding]] to [[Property:Engine]]</comment>
      <text xml:space="preserve">#REDIRECT [[Property:Engine]]</text>
    </revision>
  </page>
  <page>
    <title>Filter:Engine</title>
    <id>465</id>
    <revision>
      <id>2394</id>
      <timestamp>2010-03-15T12:06:30Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This filter covers the property [[Covers property::Engine]].'</comment>
      <text xml:space="preserve">This filter covers the property [[Covers property::Engine]].</text>
    </revision>
  </page>
  <page>
    <title>Template:Author name from page</title>
    <id>466</id>
    <revision>
      <id>2398</id>
      <timestamp>2010-03-15T12:09:57Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;includeonly&gt;{{or|{{#show:{{{1}}}| ?Real Name }}|{{#explode:{{{1}}}|:|1}}}}&lt;/includeonly&gt;</text>
    </revision>
  </page>
  <page>
    <title>File:AP CommonJS 2.jpg</title>
    <id>467</id>
    <revision>
      <id>2404</id>
      <timestamp>2010-03-15T19:11:42Z</timestamp>
      <contributor>
        <username>Mvalente</username>
        <id>14</id>
      </contributor>
      <comment>CommonJS logo proposal, a reworked and finished version of the 99% Mario,1% Wes solution</comment>
      <text xml:space="preserve">CommonJS logo proposal, a reworked and finished version of the 99% Mario,1% Wes solution</text>
    </revision>
  </page>
  <page>
    <title>Modules/Transport/D</title>
    <id>468</id>
    <revision>
      <id>2775</id>
      <timestamp>2010-05-17T11:11:10Z</timestamp>
      <contributor>
        <username>Jhuni</username>
        <id>106</id>
      </contributor>
      <comment>I changed my mind, nothing wrong with any particular transport format...</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
|implementations=Yabble
}}

Module transport format is a content format that can be used to send module factories from a server to an asynchronous client-side module loader.  A module factory can then be used on the client to instantiate modules.  


== Example ==

 require.define({ // transport the math/add module
   &quot;math/add&quot;: function(require, exports, module){
     var sum = require(&quot;./general&quot;).sum;
     exports.plusTwo = function(a){
       return sum(a, 2);
     };
   }
 },[&quot;math/general&quot;]); // list deps

== Specification ==

This specification defines a require.define function that can be called to provide modules to a loader. 

# JavaScript script may consist of any number of calls to a &quot;require.define&quot; function.
# &quot;require.define&quot; accepts a module set, which is an object where each property name represents a top-level module identifier and every value is a &quot;module descriptor&quot;.
# A &quot;module descriptor&quot; can be a function or an object:
## If the &quot;module descriptor&quot; is a function, it is is the factory function.
## If the &quot;module descriptor&quot; is an object, it can have the following properties
## An &quot;injects&quot; array of the known free-variables that are applicable (&quot;require&quot;, &quot;exports&quot;, or &quot;module&quot;). Each of these variables should be passed to the factory function at the corresponding parameter positions.
## A &quot;factory&quot; function.  The factory function for the module. The &quot;injects&quot; property may define the arguments passed to the factory function. If &quot;injects&quot; is omitted then the arguments should default to the free variables for the module format (&quot;require&quot;, &quot;exports&quot;, or &quot;module&quot; for CommonJS modules).
# The second parameter of require.define is an array of top-level module identifiers corresponding to the shallow dependencies of the given module factory, those that it directly &quot;requires&quot;.  Module factories must not be called until all of the module desciptors mentioned in the transitive &quot;requires&quot; have been given to a loader by calls to &quot;require.define&quot;. This parameter is optional. If omitted, the set of dependencies is empty.

Calling require.define does not guarantee that the module's factory will be immediately executed even if the dependencies are available. Module factories generally should not be executed until they are requested by a require, require.ensure, or other module requesting mechanism. If multiple require.define exists in one script, care must be taken to ensure the correct order, module transport writers must not assume that the modules from future require.define (later in a script) calls will be available to previous calls. In other words this will likely trigger an unnecessary request for module &quot;b&quot;:

     require.define({'a': function() {}}, ['b']);
     require.define({'b': function() {}});

=== Non-Normative Optional Extensions ===

These capabilities are not required, but some loaders may support:

# If the factory value is a string, some loaders may support evaluating the string to a factory function
# Some loaders may support module-specific dependency lists, read from the module descriptor object's &quot;dependencies&quot; property.

== Format ==

 require.define({
   &quot;MODULE_ID&quot;: FACTORY_FUNCTION or {injects: [INJECTIONS], factory: FACTORY_FUNCTION}, 
   ...
 }, [ARRAY_OF_DEPENDENCY_MODULE_IDS]);

== Examples ==

=== Transporting a set of CommonJS modules ===

Transports CommonJS modules &quot;alpha&quot; and &quot;beta&quot;, which depend on &quot;gamma&quot;:

 require.define({
   &quot;alpha&quot;: function (require, exports, module) {
     exports.verb = function() {
       return require(&quot;beta&quot;).action();
     }
   },
   &quot;beta&quot;: function (require, exports, module) {
     exports.action = function() {
       return require(&quot;gamma&quot;).something();
     }
   },
 }, [&quot;gamma&quot;]);

=== Defining a module ===

Defining a module using module injection:

 require.define({
   &quot;alpha&quot;: {
     injects: [&quot;require&quot;, &quot;module&quot;, &quot;exports&quot;],
     factory: function (require, module, exports) {
       exports.verb = function() {
         return require(&quot;beta&quot;).action();
       }
     }
   }
 });

= Implementation/Usage Notes =

Just like any JavaScript object literal, the use of property names that correspond to the property names on Object.prototype will not be enumerable in older versions of Internet Explorer, and modules with such names might not be detected by a loader unless it specifically checks for them. Also, duplicate module ids MUST not be included in object literals, different JavaScript VMs treat duplicates differently.

= Philosophy =

Module Transport Format is optimized for auto-generated transportation of modules, but can be written by hand if necessary. It is intended that modules conforming to the CommonJS [[Modules/1.1]] specification can be programmatically wrapped and bundled to Module Transport Format.  Crafting by hand in this format introduces fragility because individual modules and trees of modules become autonomous and therefore tightly coupled to their module name space.

* modules can be dynamically compiled to Module Transport Format by simply wrapping, internal modification to modules is not necessary
* all module factories can be registered in a single call with minimal boilerplate, but also
* module transport format is concatenatable.
* module namespace domain for declaring modules and specifying dependencies is not reduced by free variables (like require, exports, module).
* modules can be injected as arguments to the factory to ease referencing other modules.
* the module descriptor is an extensible name space.
* dependency sets can be defined after modules to reduce memory usage in generation implementors.

== Considerations for transport when used in the browser ==

* Relative module names that start with &quot;.&quot; and &quot;..&quot; are not supported in the top level module IDs, particularly if many modules are being transported from different paths.

== Show of Hands ==
* In favor of Transport/D:
** Kris Zyp
** Kris Kowal

* Opposed to Transport/D:
** Tobie Langel

If opposed or in favor with reservations, vote on changes that you want:

* A bundle should consist of a '''single''' call to a &quot;require.define&quot; function.
** Tobie Langel
* require.define should only take a single module (instead of module set hash). require.pause and require.resume should be added to define modules with circular dependencies.
* Each module descriptor should allow for a dependency list
** Tobie Langel (this list should be somehow made optional)
* The dependency list should be the first argument
* Strings should be accepted as factory values (and eval'd with a CommonJS wrapper)
* Allow for module ids in the injects array</text>
    </revision>
  </page>
  <page>
    <title>Property:Is standard</title>
    <id>469</id>
    <revision>
      <id>2412</id>
      <timestamp>2010-03-17T08:15:33Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::boolean]] property notes whether a spec has become a final standard or not.'</comment>
      <text xml:space="preserve">This [[has type::boolean]] property notes whether a spec has become a final standard or not.</text>
    </revision>
  </page>
  <page>
    <title>Property:Published</title>
    <id>470</id>
    <revision>
      <id>2416</id>
      <timestamp>2010-03-17T08:42:52Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::page]] property lists the published version of a spec.'</comment>
      <text xml:space="preserve">This [[has type::page]] property lists the published version of a spec.</text>
    </revision>
  </page>
  <page>
    <title>Template:Spec-list-item</title>
    <id>471</id>
    <revision>
      <id>2425</id>
      <timestamp>2010-03-17T09:08:31Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{{#if:{{{5}}}
|{{#if:{{{3|}}}|[[{{{3}}}|{{or|{{{2}}}|{{{1}}}}}]]|{{or|{{{2}}}|{{{1}}}}}}} &lt;sup&gt;[[{{{1}}}|&amp;#91;draft&amp;#93;]]&lt;/sup&gt;{{#if:{{{4|}}}|&lt;nowiki/&gt; &lt;sup&gt;(Superseded by {{spec name|{{{4}}}}})&lt;/sup&gt;}}
|[[{{{1}}}|{{or|{{{2}}}|{{{1}}}}}]]
}}</text>
    </revision>
  </page>
  <page>
    <title>Property:Superseded by</title>
    <id>472</id>
    <revision>
      <id>2422</id>
      <timestamp>2010-03-17T09:06:00Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'This [[has type::page]] property defines a spec that has superseded the spec it is placed on.'</comment>
      <text xml:space="preserve">This [[has type::page]] property defines a spec that has superseded the spec it is placed on.</text>
    </revision>
  </page>
  <page>
    <title>Template:Spec name</title>
    <id>473</id>
    <revision>
      <id>2423</id>
      <timestamp>2010-03-17T09:07:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '&lt;includeonly&gt;{{or|{{#show:{{{1}}}| ?Name }}|{{{1}}}}}&lt;/includeonly&gt;'</comment>
      <text xml:space="preserve">&lt;includeonly&gt;{{or|{{#show:{{{1}}}| ?Name }}|{{{1}}}}}&lt;/includeonly&gt;</text>
    </revision>
  </page>
  <page>
    <title>Website:Index/specs</title>
    <id>474</id>
    <revision>
      <id>2426</id>
      <timestamp>2010-03-17T09:08:58Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '= CommonJS API = == Current Specifications == {{#ask: [[Category:Spec]] [[Is standard::yes]] | ?Name | ?Published | ?Superseded by | ?Is standard#yes, | format=ul | template=spec…'</comment>
      <text xml:space="preserve">= CommonJS API =
== Current Specifications ==
{{#ask: [[Category:Spec]] [[Is standard::yes]] | ?Name | ?Published | ?Superseded by | ?Is standard#yes, | format=ul | template=spec-list-item | link=none }}

== Proposals and standards in development ==
{{#ask: [[Category:Spec]] [[Is standard::no]] | ?Name | ?Published | ?Superseded by | ?Is standard#yes, | format=ul | template=spec-list-item | link=none }}</text>
    </revision>
  </page>
  <page>
    <title>Template:Arraycount</title>
    <id>475</id>
    <revision>
      <id>2439</id>
      <timestamp>2010-03-19T06:50:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '{{#expr:{{#arraymap:{{{1}}}|{{{2|,}}}|!|1|+}}}}'</comment>
      <text xml:space="preserve">{{#expr:{{#arraymap:{{{1}}}|{{{2|,}}}|!|1|+}}}}</text>
    </revision>
  </page>
  <page>
    <title>CommonJS:Sandbox/table</title>
    <id>476</id>
    <revision>
      <id>2451</id>
      <timestamp>2010-03-19T07:28:54Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{| class=wikitable
|-
!rowspan=2| Implementations
!colspan={{arraycount|{{{standards}}}}}| Standards
!colspan={{arraycount|{{{non-standards}}}}}| Proposals and standards in development
|-
! {{#arraymap:{{{standards}}}|,|!|[[!]]| !! }}
! {{#arraymap:{{{non-standards}}}|,|!|[[!]]| !! }}
{{#arraymap:{{#ask:[[Category:Implementations]]|link=none}}|,|!|&lt;nowiki/&gt;
{{CommonJS:Sandbox/table/row
|implementation=!
|standards={{{standards}}}
|non-standards={{{non-standards}}}
}}
| }}
|}</text>
    </revision>
  </page>
  <page>
    <title>CommonJS:Sandbox/table/row</title>
    <id>477</id>
    <revision>
      <id>2455</id>
      <timestamp>2010-03-19T07:55:07Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">|-
| {{implementation link|{{page to identifier|{{{implementation}}}}}}}&lt;!--
--&gt;{{#arraymap:{{{standards}}}, {{{non-standards}}}|,|%spec%|&lt;nowiki/&gt;
{{!}} {{#ask: [[Implementation of::%spec%]] [[Implemented by::{{{implementation}}}]] | mainlabel=- | ?Implementation state= }}
| }}</text>
    </revision>
  </page>
  <page>
    <title>Template:!</title>
    <id>478</id>
    <revision>
      <id>2448</id>
      <timestamp>2010-03-19T07:21:20Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '|'</comment>
      <text xml:space="preserve">|</text>
    </revision>
  </page>
  <page>
    <title>Template:ImplementationsTable</title>
    <id>479</id>
    <revision>
      <id>2546</id>
      <timestamp>2010-04-01T20:32:35Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">{| class=wikitable width=100%
|-
!rowspan=2| [[Implementations]]
!colspan={{arraycount|{{{standards}}}}}| Standards
!colspan={{arraycount|{{{non-standards}}}}}| Proposals and standards in development
|-
! {{#arraymap:{{{standards}}}|,|!|[[!]]| !! }}
! {{#arraymap:{{{non-standards}}}|,|!|[[!]]| !! }}
{{#arraymap:{{#ask:[[Category:Implementations]]|link=none}}|,|!|&lt;nowiki/&gt;
{{ImplementationsTable/row
|implementation=!
|standards={{{standards}}}
|non-standards={{{non-standards}}}
}}
| }}
|}</text>
    </revision>
  </page>
  <page>
    <title>Template:ImplementationsTable/row</title>
    <id>480</id>
    <revision>
      <id>2459</id>
      <timestamp>2010-03-19T08:13:17Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with '|- | {{implementation link|{{page to identifier|{{{implementation}}}}}}}&lt;!-- --&gt;{{#arraymap:{{{standards}}}, {{{non-standards}}}|,|%spec%|&lt;nowiki/&gt; {{!}} {{#ask: [[Implementation…'</comment>
      <text xml:space="preserve">|-
| {{implementation link|{{page to identifier|{{{implementation}}}}}}}&lt;!--
--&gt;{{#arraymap:{{{standards}}}, {{{non-standards}}}|,|%spec%|&lt;nowiki/&gt;
{{!}} {{#ask: [[Implementation of::%spec%]] [[Implemented by::{{{implementation}}}]] | mainlabel=- | ?Implementation state= }}
| }}</text>
    </revision>
  </page>
  <page>
    <title>Website:Implementation template</title>
    <id>481</id>
    <revision>
      <id>2476</id>
      <timestamp>2010-03-19T09:03:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;nowiki/&gt;
== {{{2}}} ==
{{{3}}}
;Engine(s): {{{4}}}
;Author(s): {{#arraymap:{{{5}}}|,|!|[[!|{{author name|{{PAGENAME:!}}}}]]}}
;Implementations: {{#ask: [[Implementation of::+]] [[Implemented by::{{{1}}}]]
| mainlabel=-
| ?Implementation of=
| ?Implementation state=
| format=list
| link=none
}}
{{{6|}}}</text>
    </revision>
  </page>
  <page>
    <title>Form:Implementation</title>
    <id>482</id>
    <revision>
      <id>2475</id>
      <timestamp>2010-03-19T08:57:48Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;noinclude&gt;
This is the 'Implementation' form.
To add a page with this form, enter the page name below;
if a page with that name already exists, you will be sent to a form to edit that page.

{{#forminput:Implementation}}

&lt;/noinclude&gt;&lt;includeonly&gt;
{{{for template|Implementation}}}
{| class=&quot;formtable&quot;
! Name:
| {{{field|name|mandatory}}}
|-
! URL:
| {{{field|url}}}
|-
! Engine(s):
| {{{field|engines|list|autocomplete}}}
|-
! Author(s):&lt;br&gt;(Please use usernames only)
| {{{field|authors|list|autocomplete on namespace=User}}}
|-
! Description:
| {{{field|description|input type=textarea}}}
|}
{{{end template}}}

{{{standard input|summary}}}

{{{standard input|minor edit}}} {{{standard input|watch}}}

{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}}
&lt;/includeonly&gt;</text>
    </revision>
  </page>
  <page>
    <title>MediaWiki:Implementations</title>
    <id>483</id>
    <revision>
      <id>2478</id>
      <timestamp>2010-03-19T09:12:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with 'Implementations'</comment>
      <text xml:space="preserve">Implementations</text>
    </revision>
  </page>
  <page>
    <title>User:Wesgarland</title>
    <id>484</id>
    <revision>
      <id>2481</id>
      <timestamp>2010-03-19T11:58:23Z</timestamp>
      <contributor>
        <username>Wesgarland</username>
        <id>13</id>
      </contributor>
      <comment>Created page with '[[Real Name::Wes Garland]]'</comment>
      <text xml:space="preserve">[[Real Name::Wes Garland]]</text>
    </revision>
  </page>
  <page>
    <title>Console</title>
    <id>485</id>
    <revision>
      <id>2805</id>
      <timestamp>2010-05-27T09:29:57Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposed, discussed, some implementations
|implementations=Wakanda
}}
= console =

console is a well known logging facility to all the JS devs. By utilizing this standard interface which is almost identical across all major browsers, we will gain from familiarity from the developers. console is not a replacement for a `print` or any other full featured logging API, it may be an easily available default instance of a logger or a wrapper on `print`. Message representation and implementation is up to the platform provider.

== Prior Art ==

* [http://getfirebug.com/wiki/index.php/Console_API] Console API in FireBug
* [http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/Console_idl/Classes/Console/index.html]. Console API in Webkit inspector.

== Proposals ==

* [[console/A]] by Irakli Gozalishvili

All platforms must support a module, `console`, that MUST export following:

=== log(object[, object, ...]) ===
logs a message to with visual &quot;log&quot; representation allowing user to distinguish form other message types. You may pass as many arguments as you'd like, and they will be joined together in a space-delimited line. 

The first argument to &lt;code&gt;log&lt;/code&gt; may be a string containing printf-like string substitution patterns.  For example:
&lt;pre class=&quot;code&quot;&gt;require(&quot;console&quot;).log(&quot;The %s jumped over %d tall buildings&quot;, animal, count);&lt;/pre&gt;
The example above can be re-written without string substitution to achieve the same result:
&lt;pre class=&quot;code&quot;&gt;require(&quot;console&quot;).log(&quot;The&quot;, animal, &quot;jumped over&quot;, count, &quot;tall buildings&quot;);&lt;/pre&gt;
These two techniques can be combined.  If you use string substitution but provide more arguments than there are substitution patterns, the remaining arguments will be appended in a space-delimited line, like so:
&lt;pre class=&quot;code&quot;&gt;require(&quot;console&quot;).log(&quot;I am %s and I have:&quot;, myName, thing1, thing2, thing3);&lt;/pre&gt;
If objects are logged, platform provider may write the as static text, or a representation of an object, some platforms might dump interactive hyperlinks that can be inspected.

Here is the complete set of patterns that you may use for string substitution:
            &lt;table width=&quot;600&quot;&gt;
                &lt;tr&gt;&lt;td class=&quot;keyHead&quot; colspan=&quot;2&quot;&gt;String Substitution Patterns&lt;/td&gt;&lt;/tr&gt;
                &lt;tr&gt;&lt;td class=&quot;keyType&quot;&gt;%s&lt;/td&gt;&lt;td class=&quot;keyCode&quot;&gt;String&lt;/td&gt;&lt;/tr&gt;
                &lt;tr&gt;&lt;td class=&quot;keyType&quot;&gt;%d, %i&lt;/td&gt;&lt;td class=&quot;keyCode&quot;&gt;Integer (numeric formatting is not yet supported)&lt;/td&gt;&lt;/tr&gt;
                &lt;tr&gt;&lt;td class=&quot;keyType&quot;&gt;%f&lt;/td&gt;&lt;td class=&quot;keyCode&quot;&gt;Floating point number (numeric formatting is not yet supported)&lt;/td&gt;&lt;/tr&gt;
                &lt;tr&gt;&lt;td class=&quot;keyType&quot;&gt;%o&lt;/td&gt;&lt;td class=&quot;keyCode&quot;&gt;Object hyperlink&lt;/td&gt;&lt;/tr&gt;

            &lt;/table&gt;

=== debug(object[, object, ...]) ===

Logs a message, with a visual &quot;debug&quot; representation. Optionally includes an info of a caller (file, line where it was called from).

=== info(object[, object, ...]) ===

Logs a message with the visual &quot;info&quot; representation. Optionally includes an info of a caller (file, line where it was called from).

=== warn(object[, object, ...]) ===

Logs a message with the visual &quot;warning&quot; representation. Optionally includes an info of a caller (file, line where it was called from).

=== error(object[, object, ...]) ===

Logs a message with the visual &quot;error&quot; representation. Optionally includes an info of a caller (file, line where it was called from).

=== assert(expression[, object, ...]) ===

Tests that an expression is true.  If not, logs a message and throws an exception.

=== dir(object) ===

Logs a static / interactive listing of all properties of the object.

=== dirxml(node) ===

Logs the XML source tree of an HTML or XML element. Even though there is no CommonJS standards for XML, HTML yet most likely there will be one at some point. In order to keep compatibility with well known console from browsers, platform should implement this and may decide to default for a log or dir described above.   

=== trace() ===

Logs a static / interactive stack trace of JavaScript execution at the point where it is called. Details that platform is able to provide is most likely will be different there for it's up to platform, some may provide full stack trace like the functions on the stack, as well as the values that were passed as arguments to each function. While others may log just a module require graph. 

=== group(object[, object, ...]) ===

Logs a message to and opens a nested block to indent all future messages sent. Call &lt;code&gt;require(&quot;console&quot;).groupEnd()&lt;/code&gt; to close the block. Representation of block is up to the platform, it can be an interactive block or just a set of indented sub messages.

=== groupEnd() ===

Closes the most recently opened block created by a call to &lt;code&gt;require(&quot;console&quot;).group()&lt;/code&gt; or &lt;code&gt;require(&quot;console&quot;).groupCollapsed()&lt;/code&gt;

=== time(name) ===

Creates a new timer under the given name. Call &lt;code&gt;require(&quot;console&quot;).timeEnd(name)&lt;/code&gt; with the same name to stop the timer and log the time elapsed..

=== timeEnd(name) ===

Stops a timer created by a call to &lt;code&gt;require(&quot;console&quot;).time(name)&lt;/code&gt; and logs the time elapsed.

=== profile([title]) ===

Turns on profiler. The optional argument &lt;code&gt;title&lt;/code&gt; would contain the text to be logged in the header of the profile report. Data included in a report generated by a profiler is up to platform.  

=== profileEnd() ===

Turns off profiler and logs its report.

=== count([title]) ===

Writes the number of times that the line of code where &lt;code&gt;count&lt;/code&gt; was called was executed.  The optional argument &lt;code&gt;title&lt;/code&gt; will print a message in addition to the number of the count.


== Related Discussions ==
* [http://groups.google.com/group/commonjs/browse_thread/thread/160225ffabe4c2a4# console API]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Async/A</title>
    <id>486</id>
    <revision>
      <id>2719</id>
      <timestamp>2010-04-20T14:21:37Z</timestamp>
      <contributor>
        <username>Jbrantly</username>
        <id>109</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposal
|drafts=3
|drafts=2:2515
|drafts=1:2487
|implementations=Yabble
}}

This a proposal for the specification of the &quot;require.ensure&quot; method. (Formerly &quot;require.async&quot;.)

== Contract ==

# &quot;require.ensure&quot; accepts an array of module identifiers as first argument and a callback function as second argument.
# The callback function must be called as soon as all of the foreign modules, and their shallow and deep dependencies are available for synchronous require.
## The callback function must be passed the &quot;require&quot; function as its first argument.

=== Unspecified ===

This specification leaves the following important points of interoperability unspecified:
# the return value of &quot;require.ensure&quot; to allow for future modifications of the specification, notably the inclusion of promises,
# the means by which the foreign modules are loaded, and
# the presence of a timeout.

== Sample Code ==

;math.js:
&lt;source&gt;
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i &lt; l) {
        sum += args[i++];
    }
    return sum;
};
&lt;/source&gt;

;increment.js:
&lt;source&gt;
var add = require('math').add;
exports.inc = function(val) {
    return add(val, 1);
};
&lt;/source&gt;

;program.js:
&lt;source&gt;
require.ensure(['increment'], function(require) {
    var inc = require('increment').inc;
    var a = 1;
    inc(a); // 2
});
&lt;/source&gt;
&lt;noinclude&gt;

== Notes ==

* Given the semantic shift this method has taken thanks to Wes Garland's suggestions, the name &quot;require.async&quot; no longer seemed appropriate. We ended up agreeing on &quot;require.ensure&quot; instead.

== Related Discussion ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/3cab4886bb39c28e Updated Transport proposals]
* [http://chat.commonjs.org/mochabot/2010-03-25 IRC log]. Discussion starts at 00:34.</text>
    </revision>
  </page>
  <page>
    <title>Modules/require/async/A</title>
    <id>487</id>
    <revision>
      <id>2489</id>
      <timestamp>2010-03-22T19:40:19Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Modules/require/async/A]] to [[Modules/Async/A]]:&amp;#32;reorg</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/Async/A]]</text>
    </revision>
  </page>
  <page>
    <title>Modules/1.1.1</title>
    <id>488</id>
    <revision>
      <id>2799</id>
      <timestamp>2010-05-27T09:09:26Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=approved by discussion participants
|standard=yes
|implementations=Yabble, CouchDB, Narwhal=0.2, Wakanda
}}

'''Show of hands: Mikeal, Gozala, Zach Carter, Hannesw, Tobie, Ondřej Žára, Charles Jolley, KrisKowal, Chris Zumbrunn, Gmsox'''

This specification addresses how modules should be written in order to be interoperable among a class of module systems that can be both client and server side, secure or insecure, implemented today or supported by future systems with syntax extensions.  These modules are offered privacy of their top scope, facility for importing singleton objects from other modules, and exporting their own API.  By implication, this specification defines the minimum features that a module system must provide in order to support interoperable modules.

== Contract ==

=== Require ===

# require is a Function
## The &quot;require&quot; function accepts a module identifier.
## &quot;require&quot; returns the exported API of the foreign module.
## If there is a dependency cycle, the foreign module may not have finished executing at the time it is required by one of its transitive dependencies; in this case, the object returned by &quot;require&quot; must contain at least the exports that the foreign module has prepared before the call to require that led to the current module's execution.
## If the requested module cannot be returned, &quot;require&quot; must throw an error.
## The &quot;require&quot; function may have a &quot;main&quot; property.
### This attribute, when feasible, should be read-only, don't delete. 
### The &quot;main&quot; property must either be undefined or be identical to the &quot;module&quot; object in the context of one loaded module.
## The &quot;require&quot; function may have a &quot;paths&quot; attribute, that is a prioritized Array of path Strings, from high to low, of paths to top-level module directories.
### The &quot;paths&quot; property must not exist in &quot;sandbox&quot; (a secured module system).
### The &quot;paths&quot; attribute must be referentially identical in all modules.
### Replacing the &quot;paths&quot; object with an alternate object may have no effect.
### If the &quot;paths&quot; attribute exists, in-place modification of the contents of &quot;paths&quot; must be reflected by corresponding module search behavior.
### If the &quot;paths&quot; attribute exists, it may not be an exhaustive list of search paths, as the loader may internally look in other locations before or after the mentioned paths.
### If the &quot;paths&quot; attribute exists, it is the loader's prorogative to resolve, normalize, or canonicalize the paths provided.

=== Module Context ===

# In a module, there is a free variable &quot;require&quot;, which conforms to the above definiton.
# In a module, there is a free variable called &quot;exports&quot;, that is an object that the module may add its API to as it executes.
## modules must use the &quot;exports&quot; object as the only means of exporting.
# In a module, there must be a free variable &quot;module&quot;, that is an Object.
## The &quot;module&quot; object must have a &quot;id&quot; property that is the top-level &quot;id&quot; of the module.  The &quot;id&quot; property must be such that &lt;tt&gt;require(module.id)&lt;/tt&gt; will return the exports object from which the &lt;tt&gt;module.id&lt;/tt&gt; originated. (That is to say module.id can be passed to another module, and requiring that must return the original module). When feasible this property should be read-only, don't delete.
## The &quot;module&quot; object may have a &quot;uri&quot; String that is the fully-qualified URI to the resource from which the module was created.  The &quot;uri&quot; property must not exist in a sandbox.

=== Module Identifiers ===

# A module identifier is a String of &quot;terms&quot; delimited by forward slashes.
# A term must be a camelCase identifier, &quot;.&quot;, or &quot;..&quot;.
# Module identifiers may not have file-name extensions like &quot;.js&quot;.
# Module identifiers may be &quot;relative&quot; or &quot;top-level&quot;.  A module identifier is &quot;relative&quot; if the first term is &quot;.&quot; or &quot;..&quot;.
# Top-level identifiers are resolved off the conceptual module name space root.
# Relative identifiers are resolved relative to the identifier of the module in which &quot;require&quot; is written and called.

=== Unspecified ===

This specification leaves the following important points of interoperability unspecified:

# Whether modules are stored with a database, file system, or factory functions, or are interchangeable with link libraries.
# Whether a PATH is supported by the module loader for resolving module identifiers.

== Unit Tests ==

* [http://github.com/commonjs/commonjs/tree/master/tests/modules Unit tests on CommonJS Github Repository]

== Sample Code ==

;math.js:
&lt;source&gt;
exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i &lt; l) {
        sum += args[i++];
    }
    return sum;
};
&lt;/source&gt;

;increment.js:
&lt;source&gt;
var add = require('math').add;
exports.increment = function(val) {
    return add(val, 1);
};
&lt;/source&gt;

;program.js:
&lt;source&gt;
var inc = require('increment').increment;
var a = 1;
inc(a); // 2

module.id == &quot;program&quot;;
&lt;/source&gt;

== Notes ==

* [[Modules/Secure|Secure Modules]]
* [[Modules/Natives|How Modules relate to global natives like String]]
* [[Modules/Natives|How do you extend native prototypes from a Module?]]
* [[Modules/CompiledModules|Notes on compiling modules for browsers]]
* [[Modules/ScriptModules|On writing modules that also work as &lt;script&gt;s]]

== Related Documents ==

* Proposal to ECMA TC39: [http://docs.google.com/Doc?id=dfgxb7gk_34gpk37z9v&amp;hl=en Module System for ES-Harmony]
* Presentation to ECMA TC39: [http://docs.google.com/Presentation?docid=dcd8d5dk_0cs639jg8&amp;hl=en Modules]

== Related Discussion ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/6ad5c2c3b005cb3b/5a0f17e43d347673 RFC require.paths behaviour]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c3682135d72b1f8 Module meta data Proposal.] (resurrection of this discussion)
* [http://groups.google.com/group/commonjs/browse_thread/thread/6e6eeb9b3d2990f1 require.main === undefined Options]
* [http://groups.google.com/group/commonjs/browse_thread/thread/0f9e8fc585211f6a Modules 1.1 Comments]
* [http://groups.google.com/group/commonjs/browse_thread/thread/2f6c87b65e30fb71 Modules/1.1.1 Show of Hands]</text>
    </revision>
  </page>
  <page>
    <title>Packages/1.1</title>
    <id>489</id>
    <revision>
      <id>2847</id>
      <timestamp>2010-07-10T18:23:35Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Expliciated that the &quot;lib&quot; property is a subproperty of the &quot;directories&quot; mapping.</comment>
      <text xml:space="preserve">{{Spec
|status=draft
}}

== Packages ==

This specification describes the CommonJS package format for distributing CommonJS programs and libraries. A CommonJS package is a cohesive wrapping of a collection of modules, code and other assets into a single form. It provides the basis for convenient delivery, installation and management of CommonJS components.

This specifies the CommonJS package descriptor file and package file format. It does not specify a package catalogue file or format; this is an exercise for future specifications.
The package descriptor file is a statement of known fact at the time the package is published and may not be modified without publishing a new release.

== Package Descriptor File ==

Each package must provide a top-level package descriptor file called &quot;package.json&quot;. This file is a JSON format file. Each package must provide all the following fields in its package descriptor file.

* name - the name of the package. This must be a unique, lowercase alpha-numeric name without spaces. It may include &quot;.&quot; or &quot;_&quot; or &quot;-&quot; characters. It is otherwise opaque.
* version - a version string conforming to the Semantic Versioning requirements (http://semver.org/).

One of the following must also be in the package description file in order for it to be valid.

* main - module that must be loaded when require(name) is called. Definition must be relative to the package description file.
* directories.lib - directory of modules to be loaded under the packages namespace. require(name/subfilename) must return modules from this directory. Definition must be relative to the package description file.

Optional Keywords
* maintainers - Array of maintainers of the package. Each maintainer is a hash which must have a &quot;name&quot; property and may optionally provide &quot;email&quot; and &quot;web&quot; properties. For example:  
 &quot;maintainers&quot;:[ {
    &quot;name&quot;: &quot;Bill Bloggs&quot;,
    &quot;email&quot;: &quot;billblogs@bblogmedia.com&quot;,
   &quot; web&quot;: &quot;http://www.bblogmedia.com&quot;,
 }]
* description - a brief description of the package. By convention, the first sentence (up to the first &quot;. &quot;) should be usable as a package title in listings.
* licenses - array of licenses under which the package is provided. '''This property is not legally binding and does not necessarily mean your package is licensed under the terms you define in this property.''' Each license is a hash with a &quot;type&quot; property specifying the type of license and a url property linking to the actual text. If the license is one of the [http://www.opensource.org/licenses/alphabetical official open source licenses] the official license name or its abbreviation may be explicated with the &quot;type&quot; property.  If an abbreviation is provided (in parentheses), the abbreviation must be used.
 &quot;licenses&quot;: [
    {
        &quot;type&quot;: &quot;GPLv2&quot;,
        &quot;url&quot;: &quot;http://www.example.com/licenses/gpl.html&quot;,
    }
 ]

* &quot;bugs&quot; - URL for submitting bugs. Can be mailto or http.
* &quot;keywords&quot; - an Array of string keywords to assist users searching for the package in catalogs.
* &quot;repositories&quot; - Array of repositories where the package can be located. Each repository is a hash with properties for the &quot;type&quot; and &quot;url&quot; location of the repository to clone/checkout the package. A &quot;path&quot; property may also be specified to locate the package in the repository if it does not reside at the root. For example: 
 &quot;repositories&quot;: [
        {
             &quot;type&quot;: &quot;git&quot;, 
             &quot;url&quot;: &quot;http://github.com/example.git&quot;,
             &quot;path&quot;: &quot;packages/mypackage&quot;
        }
 ]
* &quot;contributors&quot; - an Array of hashes each containing the details of a contributor. Format is the same as for maintainer. By convention, the first contributor is the original author of the package.
* &quot;dependencies&quot; - Hash of prerequisite packages on which this package depends in order to install and run. Each dependency defines the lowest compatible MAJOR[.MINOR[.PATCH]] dependency versions (only one per MAJOR version) with which the package has been tested and is assured to work. The version may be a simple version string (see the version property for acceptable forms), or it may be a hash group of dependencies which define a set of options, any one of which satisfies the dependency. The ordering of the group is significant and earlier entries have higher priority. For example: 
 &quot;dependencies&quot;: {
        &quot;webkit&quot;: &quot;1.2&quot;,
        &quot;ssl&quot;: {
            &quot;gnutls&quot;: [&quot;1.0&quot;, &quot;2.0&quot;],
            &quot;openssl&quot;: &quot;0.9.8&quot;,
        },
 }
* &quot;homepage&quot; - URL string for the package web site
* &quot;os&quot; - Array of supported operating systems. If absent or set to the empty set, the package makes no platform assumptions. The set of valid os names includes: aix, freebsd, linux, macos,  solaris, vxworks, windows.
* &quot;cpu&quot; - Array of supported CPU architectures. If absent or set to the empty set, the package makes no platform assumptions. The set of valid cpu names includes: arm, mips, ppc, sparc, x86, x86_64.
* &quot;engine&quot; - Array of supported JavaScript engines. If absent or set to the empty set, the package makes no platform assumptions. The set of valid engine names includes: ejs, flusspferd, gpsee, jsc, spidermonkey, narwhal, node, rhino, v8.
* &quot;builtin&quot;- Boolean value indicating the package is built in as a standard component of the underlying platform
* directories - Object hash of package directories. Typical directories include &quot;lib&quot;, &quot;src&quot;, &quot;doc&quot;, &quot;jars&quot;, &quot;test&quot; and &quot;bin&quot;. Package manager tools must use these directory definitions to find various package components.
* implements - Array of relevant CommonJS specifications this package supports. A specification identifier is the WikiName of the specification prefixed by &quot;CommonJS/&quot;. Arbitrary URLs may also be specified to indicate support for externally published specifications.
   &quot;implements&quot;: [ &quot;CommonJS/Modules/1.0&quot;, &quot;CommonJS/JSGI/1.0&quot;]
* scripts - Object hash of scripts used in managing the package. A package manager tool may use these scripts to install, build, test or uninstall the package. For example:
    &quot;scripts&quot;: {
        &quot;install&quot;: &quot;install.js&quot;,
        &quot;uninstall&quot;: &quot;uninstall.js&quot;,
        &quot;build&quot;: &quot;build.js&quot;,
        &quot;doc&quot;: &quot;make-doc.js&quot;,
        &quot;test&quot;: &quot;test.js&quot;,
    }
* overlay - Object hash of identifiers for conditional replacements of top level properties. For example:
    &quot;overlay&quot;: {
        &quot;node&quot; : {&quot;dependencies&quot;:[...]},
        &quot;npm&quot;  : {&quot;scripts&quot;:{&quot;install&quot;:&quot;./npm-install.sh&quot;}
      }

Package managers and loaders should ignore unknown fields in the package descriptor file. 

== Reserved Properties ==

The following fields are reserved for future expansion: build, default, email, external, files, imports, maintainer, paths, platform, require, summary, test, using, downloads, uid.  Extensions to the package descriptor specification should strive to avoid collisions for future standard names by name spacing their properties with innocuous names that do not have meanings relevant to general package management.

The following fields are reserved for package registries to use at their discretion: id, type. 

All properties beginning with _ or $ are also reserved for package registries to use that their discretion.

== Catalog Properties ==

When a package.json is included in a catalog of packages, the following fields should be present for each package. 

* checksums - Hash of package checksums. This checksum is used by package manager tools to verify the integrity of a package. For example:
    checksums: {&quot;md5&quot;: &quot;841959b03e98c92d938cdeade9e0784d&quot;}

== Package File Format ==

The package files shall be a simple archive of the package directory including the package.json file in a relative, ZIP archive format (Though this format may change in future revisions of this specification). The archive must have a single top level directory.

== Package Directory Layout == 

A CommonJS package will observe the following:
* A package.json file must be in the top level directory
* Binary files should be in the &quot;bin&quot; directory, 
* Javascript code should be under the &quot;lib&quot; directory
* Documentation should be under the &quot;doc&quot; directory
* Unit tests should be under the &quot;test&quot; directory

== Package Files ==

To install and uninstall a CommonJS package some local installation steps may be required. A package may specify various scripts to run via the &quot;scripts&quot; package.json field.

== Other Requirements ==

* All modules contained in packages must conform to the CommonJS Securable Modules specification.

== Minimal Example Package Descriptor File ==

 {
    &quot;name&quot; : &quot;mypackage&quot;,
    &quot;version&quot; : &quot;0.7.0&quot;,
    &quot;main&quot; : &quot;./lib/main&quot;,
 }


== Large Example Package Descriptor File ==

 {
    &quot;name&quot;: &quot;mypackage&quot;,
    &quot;version&quot;: &quot;0.7.0&quot;,
    &quot;description&quot;: &quot;Sample package for CommonJS. This package demonstrates the required elements of a CommonJS package.&quot;,
    &quot;keywords&quot;: [
        &quot;package&quot;,
        &quot;example&quot; 
    ],
    &quot;maintainers&quot;: [
        {
            &quot;name&quot;: &quot;Bill Smith&quot;,
            &quot;email&quot;: &quot;bills@example.com&quot;,
            &quot;web&quot;: &quot;http://www.example.com&quot; 
        } 
    ],
    &quot;contributors&quot;: [
        {
            &quot;name&quot;: &quot;Mary Brown&quot;,
            &quot;email&quot;: &quot;maryb@embedthis.com&quot;,
            &quot;web&quot;: &quot;http://www.embedthis.com&quot; 
        } 
    ],
    &quot;bugs&quot;: {
        &quot;mail&quot;: &quot;dev@example.com&quot;,
        &quot;web&quot;: &quot;http://www.example.com/bugs&quot; 
    },
    &quot;licenses&quot;: [
        {
            &quot;type&quot;: &quot;GPLv2&quot;,
            &quot;url&quot;: &quot;http://www.example.org/licenses/gpl.html&quot; 
        } 
    ],
    &quot;repositories&quot;: [
        {
            &quot;type&quot;: &quot;git&quot;,
            &quot;url&quot;: &quot;http://hg.example.com/mypackage.git&quot; 
        } 
    ],
    &quot;dependencies&quot;: {
        &quot;webkit&quot;: &quot;1.2&quot;,
        &quot;ssl&quot;: {
            &quot;gnutls&quot;: [&quot;1.0&quot;, &quot;2.0&quot;],
            &quot;openssl&quot;: &quot;0.9.8&quot; 
        } 
    },
    &quot;implements&quot;: [&quot;cjs-module-0.3&quot;, &quot;cjs-jsgi-0.1&quot;],
    &quot;os&quot;: [&quot;linux&quot;, &quot;macos&quot;, &quot;win&quot;],
    &quot;cpu&quot;: [&quot;x86&quot;, &quot;ppc&quot;, &quot;x86_64&quot;],
    &quot;engines&quot;: [&quot;v8&quot;, &quot;ejs&quot;, &quot;node&quot;, &quot;rhino&quot;],
    &quot;scripts&quot;: {
        &quot;install&quot;: &quot;install.js&quot;,
        &quot;uninstall&quot;: &quot;uninstall.js&quot;,
        &quot;build&quot;: &quot;build.js&quot;,
        &quot;test&quot;: &quot;test.js&quot; 
    },
    &quot;directories&quot;: {
        &quot;lib&quot;: &quot;src/lib&quot;,
        &quot;bin&quot;: &quot;local/binaries&quot;,
        &quot;jars&quot;: &quot;java&quot; 
    } 
 }

== Editor Macros/Scripts ==

Remembering the format and typing the common bits can be boring.  So listed below are know editor scripts to make this easier:

* [http://gist.github.com/311512 commonjs-package-json.vim] written by Ashb.

== Background ==
* [[Packages-Background]] (discussion)
* [http://groups.google.com/group/commonjs/browse_thread/thread/9f73afe65dc33df7 modules packaging]
* [http://semver.org/ Semantic Versioning]
* [http://github.com/280north/narwhal/blob/master/docs/packages-howto.md How to make packages in Narwhal]

== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/a1abe3ffb7203ef4 Packages 1.1 version range definitions]
* [http://groups.google.com/group/commonjs/browse_thread/thread/9d714a00f5591efb Packages 1.1 Draft]
* [http://groups.google.com/group/commonjs/browse_thread/thread/ca0e9da69a33b519 Transport &amp; Packages]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c70af7ad188d6082 Packages 1.0 Comments]</text>
    </revision>
  </page>
  <page>
    <title>Modules/1.2</title>
    <id>490</id>
    <revision>
      <id>2510</id>
      <timestamp>2010-03-24T22:06:19Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>moved [[Modules/1.2]] to [[Modules/1.1.1]]</comment>
      <text xml:space="preserve">#REDIRECT [[Modules/1.1.1]]</text>
    </revision>
  </page>
  <page>
    <title>Implementations/CouchDB</title>
    <id>491</id>
    <revision>
      <id>2550</id>
      <timestamp>2010-04-01T20:49:13Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>*sigh* This needs a language.</comment>
      <text xml:space="preserve">{{Implementation
|name=CouchDB
|url=http://couchdb.apache.org/
|engines=SpiderMonkey
|authors=Mikeal
}}</text>
    </revision>
  </page>
  <page>
    <title>Promises/B</title>
    <id>492</id>
    <revision>
      <id>2780</id>
      <timestamp>2010-05-23T23:38:24Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposal
|standard=no
|implementations=Narwhal=0.5
}}

== Specification ==

# A promise is an opaque object:
## How to send messages to a promise object is beyond the scope of this specification.
## How to detect whether a value is a promise object is beyond the scope of this specification.
## These behaviors are an exercise left to implementors.
## Users of promises must not depend on any particular implementation's behavior.

The &quot;promise&quot; (provisionally &quot;promise-b&quot;) module exports the following API:

; when(object, callback, errback_opt)
# Arranges for callback to be called:
## with the fully resolved value of the given object
## in a future turn of the event loop
## if and when the object is or becomes a fully resolved value accessible to the caller.
# Arranges for errback to be called:
## with a value representing the reason why the object will never be fully resolved
## in a future turn of the event loop
## if the object is a promise and
## if that promise is resolved with a rejection (&quot;reject&quot;).
# Returns a promise that may be eventually resolved with the value returned by either the callback or the errback.
# The object may be any value.
# If the object is a promise, sends a &quot;when&quot; message to that promise with a callback and an errback that intercept the resolution of that promise and resolve the promise returned by &quot;when&quot;:
## with the value received by the callback
## or with a rejection (&quot;reject&quot;) with the reason given to the errback.
# Callback must not be called before when returns.
# Errback must not be called before when returns.
# Callback must only be called once.
# Errback must only be called once.
# If callback is called, errback must never be called.
# If errback is called, callback must never be called.
# &quot;when&quot; does not guarantee that callback or errback will ever be called.
; asap(object, callback, errback_opt)
# Arranges for callback to be called with the fully resolved value of the given object when the object is or becomes a fully resolved value accessible to the caller.
# The object may be any value.
# If the object is a promise, &quot;asap&quot; sends a &quot;when&quot; message to that promise with a callback and an errback that intercept the resolution of that promise and resolve the promise returned by &quot;asap&quot;:
## with the value given to the callback
## or with a rejection (&quot;reject&quot;) with the reason given to the errback.
# If the object is not a promise, &quot;asap&quot; must call the callback immediately.
## If the callback does not return a promise, &quot;asap&quot; returns the value returned by &quot;callback&quot;.
## If the callback returns a promise, &quot;asap&quot; sends a a &quot;when&quot; message to that promise with a callback and errback that intercept the resolution of that promise and resolve the promise returned by &quot;asap&quot;:
### with the value given to the callback
### or with a rejection (&quot;reject&quot;) with the reason given to the errback.
# &quot;asap&quot; does not guarantee that callback or errback will ever be called.
# Callback must only be called once.
# Errback must only be called once.
# If callback is called, errback must never be called.
# If errback is called, callback must never be called.
# Callback and errback may never be called.
; enqueue(task Function)
# causes a function to be called as soon as possible in a future turn.

; get(object, name)
# Returns a promise for a property of the given object.
; post(object, name, args)
# Returns a promise for the return value of calling a member function of the given object with the given arguments.
# &lt;code&gt;args&lt;/code&gt; are not variadic.
; put(object, name, value)
# returns a promise to set the value of a named property of the object and to forward the value when that has been completed.
; del(object, name)
# Returns a promise to delete the named property of the object and to forward &lt;code&gt;undefined&lt;/code&gt; when that has been completed.

; Promise(descriptor Object, fallback Function)
# Returns a Promise object
# Must be callable as a function
# May be instantiable as a constructor
# Accepts a descriptor Object that maps message names to handler functions, particularly:
## when(errback)
## get(name)
## put(name, value)
## post(name, args)
## del(name)
# Each of the above handler functions must &lt;em&gt;return&lt;/em&gt; a more resolved object or promise.
# Accepts a fallback(message, ...args) function that receives all messages that are not handled by the promise descriptor.
# Returns a promise object.
; defer()
# Returns an Object with a &quot;resolve(object)&quot; property function, and a &quot;promise&quot; object.
# The first time that &quot;resolve(object)&quot; is called, the state of the &quot;promise&quot; advances to &quot;resolved&quot; and all previous and future promises observing the &quot;promise&quot; are resolved.
## If the &quot;object&quot; is not a promise, the resolved value of the &quot;promise&quot; becomes a reference (&quot;ref&quot;) to the given object.
# All subsequent calls to resolve must be silently ignored.
; reject(reason String)
# Returns a rejected promise with the given reason.
# A rejected promise handles the &quot;when(errback)&quot; message in one of two ways:
## If an errback is provided, the errback is called with the reason as its argument, and the &quot;when&quot; message handler must return the value returned by the errback.
## If no errback is provided, the &quot;when&quot; message handler must return a new rejection (&quot;reject&quot;) with the same reason.
# Rejects all other messages.
; ref(object)
# If object is a promise, returns that promise.
# If the object is not a promise, returns a resolved promise that handles the following messages:
## when(errback) ignores the errback and forwards the resolved object.
## get(name) forwards the named property of the resolved object.
## put(name, value) sets the named property to the given value of the resolved object and forwards the value.
## del(name) deletes the named property of the resolved object and forwards &lt;code&gt;undefined&lt;/code&gt;
## post(name, args) calls the named method of the object and forwards the returned value.
## all other messages forward a rejection (&quot;reject&quot;) with the reason &quot;Promise does not handle NAME&quot; where NAME is the name of the message.

; isPromise(object) Boolean
: returns whether the given object is a promise.

; method(name String)
# returns a function like &quot;get&quot;, &quot;put&quot;, &quot;del&quot;, and &quot;post&quot; except with the given name that must forward a message to a promise in a future turn.

; defined(object)
# Returns a promise that the given object, when resolved, will not be &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.</text>
    </revision>
  </page>
  <page>
    <title>Promises/C</title>
    <id>493</id>
    <revision>
      <id>2724</id>
      <timestamp>2010-04-22T00:41:22Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Replaced content with '*redacted*'</comment>
      <text xml:space="preserve">*redacted*</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Smart</title>
    <id>494</id>
    <revision>
      <id>2578</id>
      <timestamp>2010-04-07T06:44:14Z</timestamp>
      <contributor>
        <username>Konobi</username>
        <id>105</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=Smart Platform
|url=http://github.com/joyent/smart-platform/
|engines=SpiderMonkey/C
|authors=Konobi, Joyent
}}</text>
    </revision>
  </page>
  <page>
    <title>HTTP Client/B</title>
    <id>495</id>
    <revision>
      <id>2810</id>
      <timestamp>2010-05-27T12:01:21Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <comment>/* Constructor: XMLHttpRequest(settings) */</comment>
      <text xml:space="preserve">{{Spec
|status=discussed, some implementations
|implementations=Wakanda
}}

Proposal B, Draft 1

'''Status: Proposal'''

An HTTP Client module which might be called &quot;xhr&quot; exposes an XMLHttpRequest constructor that creates an xhr object.

It is designed to be useable with Object.create()


== Introduction ==

The purpose to this proposal is to provide an interface which would be:

* compatible with lot of existing JavaScript libraries and scripts 
* very easy to learn because :
** mostly already known
** already described in lot of JavaScript, Ajax, and Web books and Web sites
** already documented as W3C recommendations ([http://www.w3.org/TR/XMLHttpRequest/ XMLHttpRequest] &amp; [http://www.w3.org/TR/XMLHttpRequest2/ XMLHttpRequest Level 2])


&quot;XML&quot; in &quot;XMLHttpRequest&quot; is only used for historical compatibility. An alias could be &quot;HttpRequest&quot;. The main difference between XMLHttpRequest and HttpRequest would then be the value returned by the toString() method.

For better user experience while using this API, It would be recommended:
* to be abble to set default values of the open() method as settings 
* to let the constructor return an instance without the &quot;new&quot; operator
* to allow chaining


Example of intuitive use:
&lt;pre&gt;
var HttpRequest = require(&quot;xhr&quot;).XMLHttpRequest;
var settings = HttpRequest.defaultSettings;
var cookies = {};

// these are some proposed setting properties
settings.async = false;
settings.cookies = cookies;
settings.host = &quot;http://www.foo.com/&quot;;

var client = HttpRequest();

// as these requests are synchronous, open() doesn't abort previous send()
var txt = client.open(&quot;GET&quot;, &quot;license.txt&quot;).send().responseText;
var obj = client.open(&quot;GET&quot;, &quot;data.json&quot;).send().responseObject;
var doc = client.open(&quot;GET&quot;, &quot;doc.html&quot;).send().responseXML;
var img = client.open(&quot;GET&quot;, &quot;img.jpg&quot;).send().responseBody;
...
// be aware that obj and doc may be set to null if the requests failed
&lt;/pre&gt;

NOTE: the upload property and the XMLHttpRequestUpload, as primarly used for DOM elements, are not defined in this proposal. It may be defined if an implementation wants to set upload progress properties to a server component (like a folder).

== Constructor: XMLHttpRequest(settings) ==

If called as a simple function, then return a new XMLHttpRequest(settings).

The settings parameter can be an object or undefined

* The settings parameter can have a &quot;custom&quot; property which is an object.
** Each implementor may define its own plate-form dependent object to carry its own specific settings
* Some standard setting properties may be defined later once a consensus is done regarding settings defined in plate-form dependent objects 


Some suggested setting properties are:

* &lt;code&gt;acceptType&lt;/code&gt;: String. Default: &quot;*/*&quot;
* &lt;code&gt;async&lt;/code&gt;: Boolean. Default: true
* &lt;code&gt;authType&lt;/code&gt;: String. Default: &quot;Basic&quot;
* &lt;code&gt;body&lt;/code&gt;: String, ByteArray, Document, Object, or null. Default: null
* &lt;code&gt;contentCharset&lt;/code&gt;: String or null. Default: null
* &lt;code&gt;contentType&lt;/code&gt;: String or null. Default: null
* &lt;code&gt;cookies&lt;/code&gt;
* &lt;code&gt;dom&lt;/code&gt;: Object or null. Provide the Document and/or HTMLDocument constructors in an object if available
* &lt;code&gt;headers&lt;/code&gt;: String or null
* &lt;code&gt;host&lt;/code&gt;: String or null. Would be used as the base URL
* &lt;code&gt;jsonHandler&lt;/code&gt;: Function or null. Used by JSON.parse for responseObject
* &lt;code&gt;keepAlive&lt;/code&gt;: String or null. Default: &quot;115&quot;
* &lt;code&gt;maxRedirects&lt;/code&gt;: Number or null
* &lt;code&gt;proxy&lt;/code&gt;: String, Location, or null.
* &lt;code&gt;timeout&lt;/code&gt;: Number.
* &lt;code&gt;user&lt;/code&gt;: String or null
* &lt;code&gt;password&lt;/code&gt;: String or null

These ones would break the standard minimal open() signature:

* &lt;code&gt;method&lt;/code&gt;: String or null.
* &lt;code&gt;url&lt;/code&gt;
* &lt;code&gt;location&lt;/code&gt;: a BOM like Location object


Another constructor named HttpRequest, with the same properties and behaviors could also be available.

== Constructor properties ==

=== prototype ===

The constructor has a prototype property described as bellow


== Prototype Read Only properties ==


=== UNSENT ===

Read-Only. 

Its value is the number 0. 

This represent the original value of the &lt;code&gt;[[#readyState]]&lt;/code&gt; property of &lt;code&gt;XMLHttpRequest&lt;/code&gt; instances.

=== OPENED ===

Read-Only. 

Its value is the number 1. 

This represent the value of the &lt;code&gt;[[#readyState]]&lt;/code&gt; property of &lt;code&gt;XMLHttpRequest&lt;/code&gt; instances once its &lt;code&gt;[[#open()]]&lt;/code&gt; method has been successfully invoked.

When an instance is in this state, the &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; method can be used to fix HTTP header field values.

=== HEADERS_RECEIVED ===

Read-Only. 

Its value is the number 2. 

This represent the value of the &lt;code&gt;[[#readyState]]&lt;/code&gt; property of &lt;code&gt;XMLHttpRequest&lt;/code&gt; instances once all HTTP headers have been received.

When an instance is in this state, the informations returned by these properties and methods are reliable:

Properties
* &lt;code&gt;[[#status]]&lt;/code&gt;
* &lt;code&gt;[[#statusText]]&lt;/code&gt;
Methods
* &lt;code&gt;[[#getResponseHeader()]]&lt;/code&gt;
* &lt;code&gt;[[#getAllResponseHeaders()]]&lt;/code&gt;


Some scripts may wait this state when an &lt;code&gt;Expect: 101-continue&lt;/code&gt; header were set in the request to send big content or chuncked data.

=== LOADING ===

Read-Only. 

Its value is the number 3. 

This represent the value of the &lt;code&gt;[[#readyState]]&lt;/code&gt; property of &lt;code&gt;XMLHttpRequest&lt;/code&gt; instances once the HTTP body started to be received.

This state is interesting to read a response while it is being received. It would be useful but requires the support of &lt;code&gt;[[#responseStream]]&lt;/code&gt; and/or &lt;code&gt;[[#responseTextStream]]&lt;/code&gt; properties

=== DONE ===

Read-Only. 

Its value is the number 4. 

This represent the value of the &lt;code&gt;[[#readyState]]&lt;/code&gt; property of &lt;code&gt;XMLHttpRequest&lt;/code&gt; instances once the HTTP body is fully received.

=== defaultSettings ===

The constructor MAY have a defaultSettings object property which properties would be Read-Write and accept the same settings as the ones defined for the constructor.
Any setting fixed in this constructor property is used by all future instances if not overridden by a different value fixed in the constructor parameter.


== Prototype Event Handler properties ==

Quite all Client-Side JavaScript libraries are based on asynchronous requests.

When implementing XMLHttpRequest on server-side, the implementor can either:

* support asynchronous execution
* simulated asynchronous execution, blocking the execution and calling the handlers each time the state of the request change


=== onreadystatechange ===

A &lt;code&gt;onreadystatechange&lt;/code&gt; event handler attribute handling the &lt;code&gt;readystatechange&lt;/code&gt; event MUST be supported. The handler is called each time the value of the [[#readyState]] constructor property change.


== Prototype properties ==

=== constructor ===

Read-Only. 

The &lt;code&gt;[[#prototype]]&lt;/code&gt; property SHOULD have a &lt;code&gt;constructor&lt;/code&gt; property which default value is the &lt;code&gt;XMLHttpRequest&lt;/code&gt; constructor.

If an &lt;code&gt;HttpRequest&lt;/code&gt; constructor is provided as well, its prototype should have a constructor set to &lt;code&gt;HttpRequest&lt;/code&gt;.

=== timeout ===

Read-Write. 

The amount of milliseconds a request can take before being terminated. By default this is 0 and has no observable effect. 

On setting the &lt;code&gt;timeout&lt;/code&gt; property these steps must be run:
# If the state is not [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;code&gt;send()&lt;/code&gt; flag is true raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# Set &lt;var&gt;request timeout&lt;/var&gt; to the given value. 

On getting, the &lt;code&gt;timeout&lt;/code&gt; property must return the value of the &lt;var&gt;request timeout&lt;/var&gt;.

([http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-timeout-attribute from XMLHttpRequest Level 2 W3C Editor's Working Draft])


=== readyState ===

Read-Only. 

Its default value is 0 ([[#UNSENT]]). 

This instance property value is changed automatically to 1 ([[#OPENED]]), 2 ([[#HEADERS_RECEIVED]]), 3 ([[#LOADING]]), and 4 ([[#DONE]]).

These changes can be handled by function set to the [[#onreadystatechange]] property.


=== withCredentials ===

Read-Write. 

Boolean. The default value is false. 

The &lt;code&gt;withCredentials&lt;/code&gt; property controls the &lt;var&gt;credentials&lt;/var&gt; flag which indicates whether a cross-origin request will include cookie and HTTP authentication data and whether cookies can be set.

It should be supported/simulated for compatibility with client libraries

On getting, the &lt;code&gt;withCredentials&lt;/code&gt; attribute must return the value of the &lt;var&gt;credentials&lt;/var&gt; flag.

This property can be set once &lt;code&gt;[[#open()]]&lt;/code&gt; has been called, until &lt;code&gt;[[#send()]]&lt;/code&gt; is called.

When the &lt;code&gt;withCredentials&lt;/code&gt; property is set, the implementation MUST run these steps:

# If the state is not [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;send()&lt;/var&gt; flag is true raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the given value is true, set the &lt;var&gt;credentials&lt;/var&gt; flag to true. For any other value, set the &lt;var&gt;credentials&lt;/var&gt; flag to false.

=== status ===

Read-Only. 

Number.

The &lt;code&gt;status&lt;/code&gt; property must return the result of running these steps:

# If the state is [[#UNSENT]] or [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;error&lt;/var&gt; flag is true return 0 and terminate these steps.
# Return the HTTP status code.


=== statusText ===

Read-Only. 

String.

The &lt;code&gt;statusText&lt;/code&gt; property must return the result of running these steps:

# If the state is [[#UNSENT]] or [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;error&lt;/var&gt; flag is true return the empty string and terminate these steps.
# Return the HTTP status text.


=== responseBody ===

Read-Only. 

ByteArray | null.

The &lt;code&gt;responseBody&lt;/code&gt; property, on getting, must return the result of running the following steps:

# If the state is not [[#LOADING]] or [[#DONE]] return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# Return a &lt;code&gt;ByteArray&lt;/code&gt; object representing the response entity body or return &lt;code&gt;null&lt;/code&gt; if the response entity body is null.


=== responseText ===

Read-Only. 

String. It's default value is the empty string.

The &lt;code&gt;responseText&lt;/code&gt; property, on getting, must return the result of running the following steps:

# If the state is not [[#LOADING]] or [[#DONE]], return the empty string and terminate these steps.
# Return the text response entity body.

=== responseXML ===

Read-Only. 

Document | null. It's default value is null.

The &lt;code&gt;responseXML&lt;/code&gt; property has XML in its name for historical reasons. It also returns documents created using an HTML parser.

The &lt;code&gt;responseXML&lt;/code&gt; property, on getting, must return the result of running the following steps:

# '''If DOM is not implemented and no Document nor HTMLDocument constructors have been provided, return &lt;code&gt;null&lt;/code&gt; and terminate these steps.'''
# If the state is not [[#DONE]], return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# If the response entity body is null, return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# If final MIME type is not null, &lt;code&gt;text/html&lt;/code&gt;, &lt;code&gt;text/xml&lt;/code&gt;, &lt;code&gt;application/xml&lt;/code&gt;, and does not end in &lt;code&gt;+xml&lt;/code&gt;, return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# If final MIME type is &lt;code&gt;text/html&lt;/code&gt; or &lt;code&gt;application/xhtml+xml&lt;/code&gt;, let &lt;var&gt;document&lt;/var&gt; be an object implementing the &lt;code&gt;HTMLDocument&lt;/code&gt; interface that represents the response entity body parsed following the rules set forth in the HTML specification for an HTML parser with scripting disabled and then terminate this algorithm.
# Otherwise, let &lt;var&gt;document&lt;/var&gt; be an object implementing the &lt;code&gt;Document&lt;/code&gt; interface that represents the result of parsing the response entity body into a document tree following the rules from the XML specifications. If this fails (unsupported character encoding, namespace well-formedness error et cetera), return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# Return &lt;var&gt;document&lt;/var&gt;. 


=== responseObject ===

Read-Only. 

Object | null. It's default value is null.

The &lt;code&gt;responseObject&lt;/code&gt; property, on getting, must return the result of running the following steps:

# If the state is not [[#DONE]], return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# If the response entity body is null, return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# If final MIME type is not null, &lt;code&gt;text/json&lt;/code&gt;, &lt;code&gt;application/json&lt;/code&gt;, &lt;code&gt;application/json-rpc&lt;/code&gt;, &lt;code&gt;application/jsonrequest&lt;/code&gt; and does not end in &lt;code&gt;+json&lt;/code&gt;, return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# Otherwise, let &lt;var&gt;object&lt;/var&gt; be the result of a JSON parse on the response entity body following the rules from the JSON specification. If this fails, return &lt;code&gt;null&lt;/code&gt; and terminate these steps.
# Return the resulting Object. 


=== responseStream ===

Read-Only.

Reserved for a binary Stream object


=== responseTextStream ===

Read-Only.

Reserved for a text Stream object


=== upload ===

Read-Only

This property should return null if &lt;code&gt;XMLHttpRequestUpload&lt;/code&gt; is not supported

== Prototype methods ==


=== open() ===

&lt;code&gt;open(method:String, url:String[, async:Boolean[, user:String[, password:String]]])&lt;/code&gt;

Parameters description:

* &lt;var&gt;method&lt;/var&gt;: The method used in the request (ex: &quot;POST&quot;, &quot;GET&quot;, &quot;PUT&quot;, ...)
* &lt;var&gt;url&lt;/var&gt;: The URL used in the request (ex: &quot;http://wiki.commonjs.org/&quot;)
* &lt;var&gt;async&lt;/var&gt;: A flag that is either true or false that indicates whether the request is done asynchronously (default: true)
* &lt;var&gt;user&lt;/var&gt;: The username used in the request (default: null)
* &lt;var&gt;password&lt;/var&gt;: The password used in the request (default: null)



When the open(method, url, async, user, password) method is invoked, the implementation must run these steps (unless otherwise indicated):

# If method is not a valid token as defined in RFC 2616 section 5.1.1, raise a [[#SYNTAX_ERR]] exception and terminate these steps.
# If method is an ASCII case-insensitive match for &lt;code&gt;CONNECT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;OPTIONS&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;TRACE&lt;/code&gt;, or  &lt;code&gt;TRACK&lt;/code&gt;, convert &lt;var&gt;method&lt;/var&gt; to ASCII uppercase. &lt;div&gt;&lt;em&gt;If it does not match any of the above, it is passed through literally, including in the final request.&lt;/em&gt;&lt;/div&gt;
# Let &lt;var&gt;url&lt;/var&gt; be a URL and its character encoding be UTF-8.
# If the implementation is an HTTP server, it MAY resolve relative URLs to its host (or virtual host) hostname setting. &lt;div&gt;&lt;em&gt;If the algorithm returns an error, raise a [[#SYNTAX_ERR]] exception and terminate these steps.&lt;/em&gt;&lt;/div&gt;
# Drop &lt;fragment&gt; from &lt;var&gt;url&lt;/var&gt; (servers don't expect to receive a fragment like &quot;#here&quot; in URLs)
# If &lt;var&gt;url&lt;/var&gt; contains an unsupported &lt;scheme&gt; (like &quot;ftp://&quot;) raise a [[#NOT_SUPPORTED_ERR]] and terminate these steps.
# If the &quot;user:password&quot; format is not supported for the relevant scheme and url contains this format raise a [[#SYNTAX_ERR]] and terminate these steps.
# If &lt;var&gt;url&lt;/var&gt; contains the &quot;user:password&quot; format let &lt;var&gt;temp user&lt;/var&gt; be the user part and &lt;var&gt;temp password&lt;/var&gt; be the password part.
# If &lt;var&gt;url&lt;/var&gt; just contains the &quot;user&quot; format let temp user be the user part.
# Let &lt;var&gt;async&lt;/var&gt; be the value of the &lt;var&gt;async&lt;/var&gt; argument
# If the &lt;var&gt;user&lt;/var&gt; argument was not omitted follow these sub steps: &lt;div&gt;&lt;em&gt;These steps override anything that may have been set by the &lt;var&gt;url&lt;/var&gt; argument (&lt;var&gt;user&lt;/var&gt; parameter of the &lt;code&gt;[[#open()]]&lt;/code&gt; method override the potential one defined in the URL)&lt;/em&gt;&lt;/div&gt;
## If the syntax of &lt;var&gt;user&lt;/var&gt; does not match the syntax specified by the relevant authentication scheme, raise a [[#SYNTAX_ERR]] exception and terminate the overall set of steps.
## If &lt;var&gt;user&lt;/var&gt; is null let &lt;var&gt;temp user&lt;/var&gt; be null.
## Otherwise let &lt;var&gt;temp user&lt;/var&gt; be &lt;var&gt;user&lt;/var&gt;. 
# If the &lt;var&gt;password&lt;/var&gt; argument was not omitted follow these sub steps:&lt;div&gt;&lt;em&gt;These steps override anything that may have been set by the &lt;var&gt;url&lt;/var&gt; argument (&lt;var&gt;password&lt;/var&gt; parameter of the &lt;code&gt;[[#open()]]&lt;/code&gt; method override the potential one defined in the URL) &lt;/em&gt;&lt;/div&gt;
## If the syntax of &lt;var&gt;password&lt;/var&gt; does not match the syntax specified by the relevant authentication scheme, raise a [[#SYNTAX_ERR]] exception and terminate the overall set of steps.
## If &lt;var&gt;password&lt;/var&gt; is null let &lt;var&gt;temp password&lt;/var&gt; be null.
## Otherwise let &lt;var&gt;temp password&lt;/var&gt; be &lt;var&gt;password&lt;/var&gt;. 
# Abort the &lt;code&gt;[[#send()]]&lt;/code&gt; algorithm (if &lt;code&gt;[[#send()]]&lt;/code&gt; was called before this &lt;code&gt;[[#open()]]&lt;/code&gt; invocation)
# The implementation should cancel any network activity for which the object is responsible.
# Set variables associated with the object as follows:
## Set the &lt;var&gt;send()&lt;/var&gt; flag to false.
## Set &lt;var&gt;response entity body&lt;/var&gt; to null.
## Empty the list of author request headers.
## Set the &lt;var&gt;request method&lt;/var&gt; to &lt;var&gt;method&lt;/var&gt;.
## Set the &lt;var&gt;request URL&lt;/var&gt; to &lt;var&gt;url&lt;/var&gt;.
## Set the &lt;var&gt;request username&lt;/var&gt; to &lt;var&gt;temp user&lt;/var&gt;.
## Set the &lt;var&gt;request password&lt;/var&gt; to &lt;var&gt;temp password&lt;/var&gt;.
## Set the &lt;var&gt;asynchronous&lt;/var&gt; flag to true if &lt;var&gt;async&lt;/var&gt; is true. Otherwise set it to false. 
# Switch the the state to [[#OPENED]]
# Dispatch a &lt;code&gt;readystatechange&lt;/code&gt; event

=== setRequestHeader() ===

&lt;code&gt;setRequestHeader(header:String, value:String)&lt;/code&gt;

As indicated in the algorithm below certain headers cannot be set and are left up to the implementation. In addition there are certain other headers the implementation will take control of if they are not set by the author as indicated at the end of the &lt;code&gt;[[#send()]]&lt;/code&gt; method section.

The &lt;code&gt;setRequestHeader()&lt;/code&gt; method appends a value if the HTTP header given as argument is already part of the author request headers list.

When the &lt;code&gt;setRequestHeader(header, value)&lt;/code&gt; method is invoked, the implementation must run these steps (unless otherwise indicated):

# If the state is not [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;send()&lt;/var&gt; flag is true raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;header&lt;/var&gt; argument does not match a valid field-name syntax (section 4.2 of RFC 2616) raise a [[#SYNTAX_ERR]] exception and terminate these steps.
# If the &lt;var&gt;value&lt;/var&gt; argument does not match a valid field-value syntax (section 4.2 of RFC 2616) raise a [[#SYNTAX_ERR]] exception and terminate these steps. (The empty string is legal and represents the empty header value)
# The following headers are not allowed to be set as they are better controlled by the implementation as it knows best what value they should have. Header names starting with &lt;code&gt;Sec-&lt;/code&gt; are not allowed to be set to allow new headers to be minted in the future that are guaranteed not to come from &lt;code&gt;XMLHttpRequest&lt;/code&gt;. If &lt;var&gt;header&lt;/var&gt; is an ASCII case-insensitive match for one of the following headers, or if the start of &lt;var&gt;header&lt;/var&gt; is an ASCII case-insensitive match for &lt;code&gt;Sec-&lt;/code&gt; (including when &lt;var&gt;header&lt;/var&gt; is just &lt;code&gt;Sec-&lt;/code&gt;), raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
## &lt;code&gt;Accept-Encoding&lt;/code&gt; (it is implementation specific)
## &lt;code&gt;Connection&lt;/code&gt; (it is generated by the &lt;code&gt;[[#send()]]&lt;/code&gt; method, should be customizable via a keepAlive setting)
## &lt;code&gt;Content-Length&lt;/code&gt; (it is fixed by from the length of the data parameter of the &lt;code&gt;[[#send()]]&lt;/code&gt; method)
## &lt;code&gt;Content-Transfer-Encoding&lt;/code&gt; (it is generated by the &lt;code&gt;[[#send()]]&lt;/code&gt; method)
## &lt;code&gt;Host&lt;/code&gt; (it is fixed by from URL parameter of the &lt;code&gt;[[#open()]]&lt;/code&gt; method)
## &lt;code&gt;Keep-Alive&lt;/code&gt; (it is generated by the &lt;code&gt;[[#send()]]&lt;/code&gt; method, should be customizable via a keepAlive setting)
## &lt;code&gt;TE&lt;/code&gt; (it is generated by the &lt;code&gt;[[#send()]]&lt;/code&gt; method)
## &lt;code&gt;Transfer-Encoding&lt;/code&gt; (it is generated by the &lt;code&gt;[[#send()]]&lt;/code&gt; method)
## &lt;code&gt;Upgrade&lt;/code&gt;
# If &lt;var&gt;header&lt;/var&gt; is not in the author request headers list append &lt;var&gt;header&lt;/var&gt; with its associated &lt;var&gt;value&lt;/var&gt; to the list and return the XMLHttpRequest instance.
# If &lt;var&gt;header&lt;/var&gt; is in the author request headers list either use multiple headers, combine the values or use a combination of those (section 4.2, RFC 2616)
# Return the XMLHttpRequest instance to provide chaining

See also the &lt;code&gt;[[#send()]]&lt;/code&gt; method regarding implementation header handling for caching, authentication, proxies, and cookies.

The following script:
&lt;pre&gt;
var client = new XMLHttpRequest();
client.open('GET', 'demo.cgi');
client.setRequestHeader('X-Test', 'one');
client.setRequestHeader('X-Test', 'two');
client.send();
&lt;/pre&gt;

Would result in the following header being sent:
&lt;pre&gt;
...
X-Test: one, two
...
&lt;/pre&gt;

=== send() ===

&lt;code&gt;send([data:(Document|String|ByteArray|Object)[, complete:Boolean]])&lt;/code&gt;

The send(data, complete) method initiates the request 

Arguments description:

* data: entity body for the request (default: null)
* complete: If false, the request's body is chunked and will be complete only once &lt;code&gt;[[#send()]]&lt;/code&gt; is called with complete set to true (default: true)


Authors are encouraged to ensure that they have specified the Content-Type header via &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; before invoking &lt;code&gt;[[#send()]]&lt;/code&gt; with a non-null data argument.

When invoked, the implementation must run these steps (unless otherwise noted). This algorithm might get aborted if the &lt;code&gt;[[#open()]]&lt;/code&gt; or &lt;code&gt;[[#abort()]]&lt;/code&gt; method is invoked. When the &lt;code&gt;[[#send()]]&lt;/code&gt; algorithm is aborted the user agent must terminate the algorithm after finishing the step it is on.

The &lt;code&gt;[[#send()]]&lt;/code&gt; algorithm can only be aborted when async is true (i.e., the request is done asynchronously) and only after the method call has returned.

# If the state is not [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;send()&lt;/var&gt; flag is true raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If stored method is &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, or &lt;code&gt;TRACE&lt;/code&gt;, act as if the &lt;var&gt;data&lt;/var&gt; argument is null. 
# If the &lt;var&gt;data&lt;/var&gt; argument has not been omitted and is not null use it for the entity body observing the following rules:
## &lt;var&gt;data&lt;/var&gt; is a &lt;code&gt;ByteArray&lt;/code&gt;: This will be done in terms of the File API in due course. Use data literally for transmission.
## &lt;var&gt;data&lt;/var&gt; is a String:
### if a &lt;var&gt;charset&lt;/var&gt; is defined in the &lt;code&gt;Content-Type&lt;/code&gt; header field: Encode &lt;var&gt;data&lt;/var&gt; using it for transmission, otherwise, encode data using UTF-8 for transmission.
## &lt;var&gt;data&lt;/var&gt; is a &lt;code&gt;Document&lt;/code&gt; (meaning DOM is supported):
### Let &lt;var&gt;tempdata&lt;/var&gt; be the result of getting the innerHTML attribute on the &lt;var&gt;data&lt;/var&gt; object and encode it using &lt;code&gt;data.inputEncoding&lt;/code&gt; or UTF-8 if &lt;code&gt;data.inputEncoding&lt;/code&gt; is null. Re-raise any exception this raises.
### If the document cannot be serialized an [[#INVALID_STATE_ERR]] exception is raised.
### Let &lt;var&gt;data&lt;/var&gt; be &lt;var&gt;tempdata&lt;/var&gt;.
### If no &lt;code&gt;Content-Type&lt;/code&gt; header has been set using &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; set a &lt;code&gt;Content-Type&lt;/code&gt; request header with a value of &lt;code&gt;application/xml;charset=charset&lt;/code&gt; where &lt;code&gt;charset&lt;/code&gt; is the encoding used to encode the document.
### Subsequent changes to the document have no effect on what is submitted.
## &lt;var&gt;data&lt;/var&gt; is an Object (neither &lt;code&gt;ByteArray&lt;/code&gt; or &lt;code&gt;Document&lt;/code&gt;):
### Let &lt;var&gt;tempdata&lt;/var&gt; be the result of computing a JSON stringify on the &lt;var&gt;data&lt;/var&gt; object and encode it with the charset defined in the &lt;code&gt;Content-Type&lt;/code&gt; or UTF-8 if not defined. Re-raise any exception this raises.
### If the object cannot be serialized an [[#INVALID_STATE_ERR]] exception is raised.
### Let &lt;var&gt;data&lt;/var&gt; be &lt;var&gt;tempdata&lt;/var&gt;.
### If no &lt;code&gt;Content-Type&lt;/code&gt; header has been set using &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; set a &lt;code&gt;Content-Type&lt;/code&gt; request header with a value of &lt;code&gt;application/json;charset=UTF-8&lt;/code&gt;
### Subsequent changes to the object have no effect on what is submitted.
## If the &lt;var&gt;data&lt;/var&gt; argument has been omitted, or is null, no entity body is used in the request.
# If the &lt;var&gt;asynchronous&lt;/var&gt; flag is false release the storage mutex.
# Set the &lt;var&gt;error&lt;/var&gt; flag to false.
# If the &lt;var&gt;asynchronous&lt;/var&gt; flag is true run these substeps:
## '''Set the &lt;var&gt;send()&lt;/var&gt; flag to true.'''
## Dispatch a &lt;code&gt;readystatechange&lt;/code&gt; event. (The state does not change. The event is dispatched for historical reasons.)
## Return the &lt;code&gt;[[#send()]]&lt;/code&gt; method call, but continue running the steps in this algorithm. 


If request timeout is not 0 and since the request started the amount of milliseconds specified by request timeout has passed before the response is fully received, raise a [[#TIMEOUT_ERR]] exception and terminate these steps.

If the implementation allows the end user to configure a proxy it should modify the request appropriately; i.e., connect to the proxy host instead of the origin server, modify the Request-Line and send &lt;code&gt;Proxy-Authorization&lt;/code&gt; headers as specified.


If the user agent supports HTTP Authentication and Authorization is not in the list of author request headers, it should consider requests originating from the XMLHttpRequest object to be part of the protection space that includes the accessed URIs and send Authorization headers and handle &lt;code&gt;401 Unauthorized&lt;/code&gt; response appropriately. If authentication fails the implementation must raise an [[#UNAUTHORIZED_ERR]] exception.


If the implementation supports HTTP State Management it should persist, discard and send cookies (as received in the &lt;code&gt;Set-Cookie&lt;/code&gt; and &lt;code&gt;Set-Cookie2&lt;/code&gt; response headers, and sent in the &lt;code&gt;Cookie&lt;/code&gt; header) as applicable. For compatibility with Client-side JavaScript libraries, it is recommended to provide a &lt;code&gt;document&lt;/code&gt; object with a &lt;code&gt;cookie&lt;/code&gt; property as available in browsers. 

If the implementation implements a HTTP client cache it should respect &lt;code&gt;Cache-Control&lt;/code&gt; request headers set by the &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; (e.g., &lt;code&gt;Cache-Control: no-cache&lt;/code&gt; bypasses the cache). It must not send &lt;code&gt;Cache-Control&lt;/code&gt; or &lt;code&gt;Pragma&lt;/code&gt; request headers automatically unless the end user explicitly requests such behavior.


For &lt;code&gt;304 Not Modified&lt;/code&gt; responses that are a result of an implementation generated conditional request the user agent must act as if the server gave a &lt;code&gt;200 OK&lt;/code&gt; response with the appropriate content. The implementation must allow &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; to override automatic cache validation by setting request headers (e.g.,&lt;code&gt;If-None-Match&lt;/code&gt;, &lt;code&gt;If-Modified-Since&lt;/code&gt;), in which case &lt;code&gt;304 Not Modified&lt;/code&gt; responses must be passed through. 


If the implementations support server-driven content-negotiation it should set &lt;code&gt;Accept-Encoding&lt;/code&gt; and &lt;code&gt;Accept-Charset&lt;/code&gt; headers as appropriate. Unless set through &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt; implementations should set the &lt;code&gt;Accept&lt;/code&gt; and &lt;code&gt;Accept-Language&lt;/code&gt; headers as well. Responses must have the content-encodings automatically decoded.


Besides the author request headers implementation should not include additional request headers other than those mentioned above or other than those authors are not allowed to set using &lt;code&gt;[[#setRequestHeader()]]&lt;/code&gt;. This ensures that authors have a reasonably predictable API.

=== abort() ===

When the &lt;code&gt;abort()&lt;/code&gt; method is invoked, the implementation must run these steps (unless otherwise noted):

# Abort the send() algorithm
# The implementation SHOULD cancel any network activity for which the object is responsible.
# Set the response entity body to null.
# Set the error flag to true.
# Empty the list of author request headers.
# If the state is [[#UNSENT]], [[#OPENED]] with the &lt;code&gt;send()&lt;/code&gt; flag being false, or [[#DONE]] go to the next step. Otherwise run these substeps:
## Switch the state to [[#DONE]].
## Set the &lt;var&gt;send()&lt;/var&gt; flag to false.
## Dispatch a &lt;code&gt;readystatechange&lt;/code&gt; event.
# Switch the state to [[#UNSENT]].

No &lt;code&gt;readystatechange&lt;/code&gt; event is dispatched.

=== getResponseHeader() ===

&lt;code&gt;getResponseHeader(header:String)&lt;/code&gt;

When the getResponseHeader(header)  is invoked, the implementation must run these steps:

# If the state is [[#UNSENT]] or [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;header&lt;/var&gt; argument does not match a valid field-name syntax (section 4.2 of RFC 2616), return null and terminate these steps.
# If the &lt;var&gt;error&lt;/var&gt; flag is true return null and terminate these steps.
# If &lt;var&gt;header&lt;/var&gt; is an ASCII case-insensitive match for multiple HTTP response headers, return the values of these headers as a single concatenated string separated from each other by a U+002C COMMA U+0020 SPACE character pair and terminate these steps.
# If &lt;var&gt;header&lt;/var&gt; is an ASCII case-insensitive match for a single HTTP response header, return the value of that header and terminate these steps.
# Return null. 

// The following script:
&lt;pre&gt;
var client = new XMLHttpRequest();
client.open(&quot;GET&quot;, &quot;test.txt&quot;, true);
client.send();
client.onreadystatechange = function() {
    if (this.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
        print(client.getResponseHeader(&quot;Content-Type&quot;));
    }
}
&lt;/pre&gt;
// ...should output something similar to the following text:
&lt;pre&gt;
Content-Type: text/plain; charset=utf-8
&lt;/pre&gt;

=== getAllResponseHeaders() ===

When the &lt;code&gt;getAllResponseHeaders()&lt;/code&gt;  method is invoked, the implementation must run the following steps:

# If the state is [[#UNSENT]] or [[#OPENED]] raise an [[#INVALID_STATE_ERR]] exception and terminate these steps.
# If the &lt;var&gt;error&lt;/var&gt; flag is true return the empty string and terminate these steps.
# Return all the HTTP headers as a single string, with each header line separated by a U+000D CR U+000A LF pair, and with each header name and header value separated by a U+003A COLON U+0020 SPACE pair. 


// The following script:
&lt;pre&gt;
var client = new XMLHttpRequest();
client.open(&quot;GET&quot;, &quot;test.txt&quot;, true);
client.send();
client.onreadystatechange = function() {
 if(this.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
  print(this.getAllResponseHeaders());
 }
}
&lt;/pre&gt;
// ...should output something similar to the following text:
&lt;pre&gt;
Date: Sun, 24 Oct 2004 04:58:38 GMT
Server: Apache/1.3.31 (Unix)
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/plain; charset=utf-8
&lt;/pre&gt;

=== overrideMimeType() ===

&lt;code&gt;overrideMimeType(mime:String)&lt;/code&gt;

When the &lt;code&gt;overrideMimeType(mime)&lt;/code&gt;  method is invoked, the user implementation run the following steps:

# If parsing &lt;var&gt;mime&lt;/var&gt; analogously to the value of the &lt;code&gt;Content-Type&lt;/code&gt; headers fails raise a [[#SYNTAX_ERR]] exception and abort this algorithm.
# If a MIME type (without any parameters) is successfully parsed set override MIME type to that MIME type.
# If a &lt;var&gt;charset&lt;/var&gt; parameter is successfully parsed set override &lt;var&gt;charset&lt;/var&gt; to its value.

=== toString() ===

If the constructor is XMLHttpRequest, the returned value must be &quot;[object XMLHttpRequest]&quot;.

If the constructor is HttpRequest, the returned value must be &quot;[object HttpRequest]&quot;.


== Exceptions ==

This API requires to send Exceptions which error code can be defined in DOM. Here are the description of these required Exceptions and their error code value:

[http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-17189187 Exceptions of DOM Level 2 Core]

This API requires new Exceptions defined in the W3C Editor's Draft of XMLHttpRequest Level 2

[http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#exceptions Exceptions of the W3C Editor's Draft of XMLHttpRequest Level 2]

=== NOT_SUPPORTED_ERR ===

Code value: 9

This is a DOM level 1 error meaning:

&quot;The implementation does not support the requested type of object or operation.&quot;

=== INVALID_STATE_ERR ===

Code value: 11

This is a DOM level 2 error meaning:

&quot;An attempt is made to use an object that is not, or is no longer, usable.&quot;

=== SYNTAX_ERR ===

Code value: 12

This is a DOM level 2 error meaning:

&quot;An invalid or illegal string is specified.&quot;

=== TIMEOUT_ERR ===

Code value: 23

This is a XMLHttpRequest Level 2 error meaning:

&quot;The author specified timeout has passed before the request could complete in synchronous requests.&quot;

This exception will be folded into an update of DOM Level 3 Core in due course, as they are appropriate for other API specifications as well.</text>
    </revision>
  </page>
  <page>
    <title>Encodings/B</title>
    <id>496</id>
    <revision>
      <id>2771</id>
      <timestamp>2010-05-12T13:13:40Z</timestamp>
      <contributor>
        <username>Hannesw</username>
        <id>10</id>
      </contributor>
      <text xml:space="preserve">''Draft 1''

This document describes an interface for converting streams of bytes to characters and vice versa. 

It pays special attention on the requirements of asynchronous streaming where no assumptions can be made about character alignment. 

The Decoder and Encoder classes also provide convenience methods to attach them to input or output streams for synchonous operation.

= Specification =

Platforms implementing this specifications provide an '''encoding''' module exporting the classes described below.

== Decoder ==

==== Constructor ====

;[new] Decoder(encoding string, [strict boolean], [capacity number]) Decoder
:Create a new Decoder instance that will decode bytes to characters using the given encoding. 

:A decoder encapsulates an character buffer for decoded output, and a binary input buffer for storing partial character input between invocations of decode(). The initial size of the output buffer is set to capacity or a default value if capacity is undefined. All buffers are growable and will be resized as required.

:If strict is true, the decoder will throw Errors on illegal input; otherwise, it will silently accept illegal input.

==== Instance Methods ====

;decode(buffer Binary, [start number], [end number]) Decoder
:Try to decode the content of buffer, appending the result to the internal character buffer. If start and end are defined and valid indices for buffer, only the region between start (inclusive) and end (exclusive) are decoded.

:If the Decoder was constructed with true as strict argument, this method throws an Error if the input is not valid for the decoder's encoding.

:The method returns this decoder for chainability.

;toString() string
:Return the content of the internal character buffer as string. This includes all content decoded since the Decoder was created or clear() was invoked on it.

;clear() Decoder
:Reset the output buffer, discarding all content decoded so far. This does not reset the input buffer, so any bytes representing a partial character are kept for later invocations of decode().

:The method returns this decoder for chainability.

;hasPendingInput() boolean
:Return true if there any bytes representing a partial character in the decoder's internal input buffer, false otherwise.

;close() Decoder
:Closes the decoder. The decoder must not be used after close() was invoked.

:If the Decoder was constructed in strict mode, this method throws an Error if there are any pending bytes in its input buffer.

:The method returns this decoder for chainability.

;readFrom(source Stream)
:If this method is invoked, input is read from source which must be a readable stream.

;readLine(includeNewline) string
:Return a string containing all decoded characters up to the first line break, or null if no line break was found in the current output buffer. A line break is either &quot;\n&quot;, &quot;\r&quot;, or &quot;\r\n&quot;. If Boolean(includeNewline) is true the line break is included with the return value. 

:If a source stream was defined using the readFrom method, more bytes are read form the source stream until a line break or EOF is encountered. 

==== Instance Properties ====

;length number
:Return the length of the decoded output in character units. This property is not writable.

== Encoder ==

==== Constructor ====

;[new] Encoder(encoding string, [strict boolean], [capacity number]) Encoder
:Create a new Encoder instance that will encode characters to bytes using the given encoding. 

:An encoder encapsulates an byte buffer for encoded output. The initial size of the size of the buffer is set to capacity or a default value if capacity is undefined, and will grow to accommodate encoded output as required.

:If strict is true, the decoder will throw Errors on illegal input; otherwise, it will silently accept illegal input.


==== Instance Methods ====

;encode(str string, [start number], [end number]) Encoder
:Try to encode the content of str, appending the result to the internal byte buffer. If start and end are defined and valid indices for str, only the region between start (inclusive) and end (exclusive) are decoded.

:If the Encoder was constructed with true as strict argument, this method throws an Error if the input is not valid for the decoder's encoding.

:The method returns this encoder for chainability.

;toBuffer|ByteArray|ByteString() Buffer|ByteArray|ByteString
:Return the content of the internal byte buffer as a binary buffer. This includes all content encoded since the Encoder was created or clear() was invoked on it.

;clear() Encoder
:Reset the output buffer, discarding all content encoder so far.

:The method returns this decoder for chainability.

;close() Encoder
:Closes the encoder. The encoder must not be used after close() was invoked.

:If the Decoder was constructed in strict mode, this method throws an Error if the encoder .

:The method returns this decoder for chainability.

;writeTo(sink Stream)
:If this method is invoked, all output is directly written to the sink which must be a writable stream instead of keeping it in the internal output buffer.

==== Instance Properties ====

;length number
:Return the length of the encoded output in bytes. This property is not writable.

= Implementations =

An implementation of this proposal is available and used for all text streams [http://github.com/hns/ringojs/blob/master/modules/ringo/encoding.js in RingoJS]</text>
    </revision>
  </page>
  <page>
    <title>Packages/Mappings/A</title>
    <id>497</id>
    <revision>
      <id>2892</id>
      <timestamp>2010-09-07T23:02:52Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <minor/>
      <comment>moved [[Packages/Mappings]] to [[Packages/Mappings/A]]:&amp;#32;This location needs to be an index since there are three other proposals.</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
}}

== Package Mappings ==

This specification describes an addition to the CommonJS package format for packages to define how they expect their module namespace to be mapped to referenced modules. This defines a new &quot;mappings&quot; property that how a set of module ids should be mapped to canonical URIs of target modules. This specification does not define how the URI target modules are installed or retrieved, and it does not define how any module ids are resolved outside of the mappings.

== Simple Example Package Descriptor File ==

 {
    &quot;name&quot;: &quot;mypackage&quot;,
    &quot;mappings&quot;: {
        &quot;other&quot;: &quot;jar:http://github.com/someone/other/zipball/master!/lib/&quot;
    },
    ...
 }
 

== Package Descriptor File Mappings Property==

The &quot;mappings&quot; property may be defined in a package's package.json file and defines the expected translation of module ids for all modules within the package. The &quot;mappings&quot; property value should be an object, where each property represents a mapping. The name of the property indicates the string to use to match module ids for the mapping. Module ids that begin with a &quot;.&quot; should never be translated by mappings. The mapping with the longest property in the mappings object that matches should be applied, and subsequent mapping objects may then be ignored. If no mappings are applicable for a module id, then the id should be looked up per the default id lookup scheme.

A require statement from a module in this package that uses an id that begins with the name of the property may be translated with this mapping if one of the following certain conditions:
* If the module id is identical to the property name and the &quot;to&quot; value (the mapping target) does not end with a slash, the module id should be translated to the resolved &quot;to&quot; value as the URI for the module.
* If the module ids starts with the property name followed by slash (/) and the &quot;to&quot; value does not end with a dot (.) followed exclusively by word characters ([a-zA-Z0-9]), then the module id should be translated. If the &quot;to&quot; value does not end with a slash, a slash should be appended. Then the remaining string after the property name and slash should be appended to the resolved &quot;to&quot; value (and slash if needed) as the URI for the module.

Finally, the extension (default of &quot;.js&quot;) should be appended to create the full URI for the module if the URI does not end with a dot (.) followed exclusively by word characters ([a-zA-Z0-9]).

The value of the property may be a string that defines the target of the mapping or may be a mapping object. The meaning of a string value is identical to the &quot;to&quot; property of a mapping object. If the value is an object (a mapping object), it must contain the following properties: 
* to - This indicates the target id of the translation. The remainder of the string after the part that matches the property name should be appended to the &quot;to&quot; value. The &quot;to&quot; value may be a relative URI, in which case it should be resolved against the location of this package.json file. 

The mapping object may contain the following optional properties, that are optionally supported by module loaders or package managers:
* verify - Provides hash-based verification of the contents of a target archive or file. The value of the &quot;verify&quot; property should be an object with two properties:
** signature - The signature or hash of the target file/archive.
** algorithm - The algorithm to use to compute the signature or hash of the target file/archive.

* mirrors - This denotes alternate URLs that can be used to access the target modules. It is recommended that files downloaded from a mirror only be used if the system ensures that all other packages that reference the target modules provide the same mirror URL in their list of mirrors or provide a secure hash that matches the contents of the files downloaded from mirror. This is to protect poisoning the cache for modules with a malicious files from a mirror.

* extension - This indicates the extension to append to module ids to create full URIs. This defaults to &quot;.js&quot;.

== Example Package Descriptor File ==

 {
    &quot;name&quot;: &quot;mypackage&quot;,
    &quot;mappings&quot;: {
    	&quot;other&quot;: &quot;jar:http://github.com/someone/other/zipball/master!/lib&quot;,
    	&quot;favorite&quot;: &quot;jar:http://github.com/someone/other/zipball/master!/lib/favorite.js&quot;,
        &quot;foo&quot;: {
            &quot;to&quot;: &quot;jar:http://downloads.sourceforge.net/project/foo/foo/rc1/foo-v1.zip!/lib/&quot;,
            &quot;mirrors&quot;: [
            	&quot;jar:http://another-download-site.com/foo-v1.zip!/lib/
            ],
            &quot;verify&quot;: {
                &quot;signature&quot;: &quot;c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87&quot;,
                &quot;algorithm&quot;: &quot;rsa-sha1&quot;
            }
        }
    },
    &quot;overlay&quot;: {
        &quot;rhino&quot;: {
            &quot;mappings&quot;: {
                 &quot;http-client&quot;: &quot;./engines/rhino/http-client&quot;
            }
        }
    },
    ...
 }
 

== Determining Package Information From URIs/modules ==

When a module's id is a URI, the loader should attempt to associate it with a package, if one exists for the module. The containing package and any directives (like mappings) from its package.json should be read and observed for the target modules. However, it is beyond the normative scope of this proposal to exhaustively define all the ways that a module loader may load or install packages, which may include package management tools, on-demand downloading, packages bundled in a distribution, etc. But, the following conventions should be observed:

* If a module's URL is within an archive (using the jar URI scheme), then the archive should be correspond to the package for the module (with package.json in the root folder).

* If a module includes a literal in a comment of the form:
package root: &lt;url&gt;
The URL indicates the URL of the root of the package:

* If a request is made to server for a module the response may includes a Link header that defines &quot;package&quot; relation to the package root.

* If a module's URL contains &quot;lib&quot; in one of the path identifiers, then the parent path should be considered to be the package root.

== Other Considerations ==

* It is recommended that when web servers and module loaders resolve and fulfill a URI request to a file system directory, that they look for an &quot;index.js&quot; in the directory to provide as the response for the module request. For example, a web server may look for a index.js in the &quot;my-modules&quot; directory to fulfill a URI request like &quot;http://somesite.com/my-modules/&quot;. However, dictating web server behavior like this in beyond the scope of this specification.

* If an &quot;overlay&quot; is used, the mappings from both the overlay and the base structure should be applied, with the overlay taking precedent.

* Implementations may treat some URIs with known server URIs structures as equivalent. For example, one can generally assume that the following URIs are the same (and prefer the use of the latter):

 http://github.com/{a}/{b}/raw/{c}/{d}
 jar:http://github.com/{a}/{b}/zipball/{c}!/{d}

Implementations may also utilize trusted mirrors or repositories for alternate equivalent URLs.

* This proposal does not dictate how module ids should be interpreted or mapped to packages outside of the mappings (with different mechanisms like package URI schema, two argument require, or other conventions). This proposal only provides a means for a package to declare how its modules expect an explicitly declared ranges of module ids to be mapped to URIs. These mappings only need to be applied to modules within the package.

* This proposal does not define how or when modules with URIs for different versions of the modules should be treated as a single module (to maintain a singleton even when different versions are requested). Normally modules with different URIs should be considered separate modules, but there may be situations where implementations provide a means for enforcing a single module for a range of URIs. This is outside the scope of the mappings property.

== Background ==
* [http://groups.google.com/group/commonjs/browse_thread/thread/3b6cf9d18df7379d package.json mappings]</text>
    </revision>
  </page>
  <page>
    <title>Modules/Metadata</title>
    <id>498</id>
    <revision>
      <id>2844</id>
      <timestamp>2010-07-09T00:06:18Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>Reverted edits by [[Special:Contributions/DeloresReese|DeloresReese]] ([[User talk:DeloresReese|Talk]]) to last revision by [[User:Jhuni|Jhuni]]</comment>
      <text xml:space="preserve">'''STATUS: PROPOSALS'''

== Overview ==

[[Packages/1.0]] specifies a JSON format for describing packages, this page proposes that we extend that benefit to modules, for the purposes and goals of this proposal see: [[Modules/Metadata/Purpose]].

== Format ==

Module metadata should be stored in JSON as package metadata is, since JSON is built right into JavaScript.

&lt;source&gt;
{

    // This manually specifies how this metadata will be handled.
    // See the &quot;handlers section&quot;
    &quot;handler&quot;: &quot;http://github.com/jhuni/Module-Metadata/blob/master/lib/META/Handlers/bundler.js&quot;,

    // Extends is basically a way of combining JSON files.
    &quot;extends&quot;: &quot;json-Modules-1.1.1-common&quot;,

    // This uses the format:
    // language, name, version, authority
    &quot;id&quot;: &quot;js-Utils.slurp-1.0-jsan+jhuni&quot;,

    // This makes the module return exports like in Modules/1.0.
    &quot;returns&quot;: &quot;exports&quot;,

    // This will pass the variables io and each to your module.
    &quot;use&quot;: {

        &quot;each&quot;: &quot;js-Utils.each-1.0-jsan+jhuni&quot;,

        // This is for rhino users:
        &quot;io.java&quot;: &quot;java-java.io-1.4-sun&quot;,
        
        // This is for parrot users:
        &quot;io.perl&quot;: &quot;perl-File::Slurp-1.2-cpan+DROLSKY&quot;

    },
    
    // This will make sure XMLHttpRequest works in IE.
    &quot;builtins&quot;: [
        &quot;XMLHttpRequest&quot;
    ],

    // This is to aid some implementations of require()
    &quot;requires&quot;: [
        &quot;js-Utils.more-1.2-jsan+jhuni&quot;
    ]

}
&lt;/source&gt;

== Examples ==

=== Sample Code ===

;math.js:
&lt;source&gt;
META({

    &quot;id&quot;: &quot;js-Utils.add-1.0-jsan+jhuni&quot;,

    &quot;builtins&quot;: [
        &quot;Array.prototype.reduce&quot;,
        &quot;Function.prototype.call&quot;
    ]

});

// Package
return function() {

    return( Array.prototype.reduce.call(arguments, function(a, b) {
        return a + b;
    }) );

};
&lt;/source&gt;

;increment.js:
&lt;source&gt;
META({

    &quot;id&quot;: &quot;js-Utils.inc-1.0-jsan+jhuni&quot;,

    &quot;use&quot;: {
        &quot;add&quot;: &quot;js-Utils.add-1.0-jsan+jhuni&quot;
    }

});

// Package:
return function(val) {

    return add(val, 1);

};
&lt;/source&gt;

;program.js:
&lt;source&gt;
META({ 

    &quot;id&quot;: &quot;js-Utils.program-1.0-jsan+jhuni&quot;,
    
    &quot;use&quot;: {
        &quot;inc&quot;: &quot;js-Utils.inc-1.0-jsan+jhuni&quot;
    }

});

// Package
var a = 1;
inc(a); // 2
&lt;/source&gt;

=== Modules/1.1.1 ===

&lt;source&gt;
META({

    // Specify what version of the CommonJS module system you are using
    &quot;extends&quot;: &quot;json-Modules-1.1.1-common&quot;,
    
    // Aid some static analysis tools by giving them shallow-deps
    &quot;requires&quot;: [
        &quot;inc&quot;
    ]

});

/* Modules/1.1.1 code */
&lt;/source&gt;

=== Loader ===

One of the advantages of this proposal is that even the loader script can have metadata, because usually loader scripts require lots of utilities, builtins, and other functionality. The yabble loader actually manually includes utilities similar to the ones below, furthermore the JSAN loader also requires lots of utilities.

This sort of practice will leave normalizing XMLHttpRequest, and other builtins to external scripts. For example there may be special normalizers for some server-side platforms which don't have XMLHttpRequest, and some old browsers such as Opera 7.0 have normalizers based upon java. [http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest]

;loader.js:
&lt;source&gt;
META({

    &quot;id&quot;: &quot;js-ensure-1.2-commonjs&quot;,
    
    &quot;returns&quot;: &quot;exports&quot;,
    
    &quot;builtins&quot;: [
        &quot;XMLHttpRequest&quot;, 
        &quot;Array.prototype.indexOf&quot;,
        &quot;Array.prototype.filter&quot;
    ],
    
    &quot;use&quot;: {
        &quot;loadModuleByScript&quot;: &quot;js-Get.script-1.0-jsan+jhuni&quot;
    }

});


exports.ensure = function(modules, callback) {
    /* ... */
};

&lt;/source&gt;

Most modules won't even need to have access to on-demand JavaScript, they just need the ability to handle dependencies, so you will rarely have to use such an ensure function.

&lt;source&gt;

META({

    &quot;use&quot;: {
        &quot;ensure&quot;: &quot;js-ensure-1.2-commonjs&quot;
    }

});

ensure(['Utils.inc', 'Utils.add'], callback);

&lt;/source&gt;

Furthermore, when you request the above script that requires Utils.add, and Utils.inc it will just combine the ensure like any other module, this is one case where this metadata proposal will boost the performance of client-side websites.

== Handlers ==

=== Overview ===

A handler is a function in which handles a metadata format, there may be multiple handlers which handle the same data differently, or handlers built to handle an entirely different metadata format.

=== Bundler ===

The bundler is a handler in which takes a module, removes its metadata and includes any of its dependencies to build a completely standalone file, for example the file Utils.program might look something like this if it was stand-alone:

&lt;source&gt;
(function() {

// From &quot;use&quot;: {&quot;add&quot;: js-Utils.add-1.0-jsan+jhuni&quot;}
var deps1 = (function() {

    return function() {

        return( Array.prototype.reduce.call(arguments, function(a, b) {
            return a + b;
        }) );

    };

})();

// From &quot;use&quot;: {&quot;inc&quot;: &quot;js-Utils.inc-1.0-jsan+jhuni&quot;}
var deps2 = (function(add) {

    return function(val) {
        return add(val, 1);
    };

})(deps1);

// This is the package itself:
var requestedModule = (function(inc) {
	
    var a = 1;
    inc(a); // 2
	
})(deps2);


// Now lets register the requested modules
// Using some register handler:

if (typeof Utils === 'undefined') {
    Utils = {};    
}

Utils.add     = deps1;
Utils.inc     = deps2;
Utils.program = requestedModule;

})();

&lt;/source&gt;

Implementation: http://github.com/jhuni/Module-Metadata/blob/master/lib/META/Handlers/bundler.js

=== Modules/Transport ===

Furthermore you can write META handlers to turn scripts into one of the [[Modules/Transport]] formats.

Transport D: http://github.com/jhuni/Module-Metadata/blob/master/lib/META/Handlers/transportD.js

== Usage ==

=== Local Scripts ===

On the server-side where you don't suffer from serious IO costs, you can just fetch all of a modules dependencies using asynchronous slurping and do the META handling locally.

Localized metadata system: http://github.com/jhuni/Module-Metadata/blob/master/lib/META.js

=== External Scripts ===

If you are getting a script from an external location then you should be able to delegate the META handling process to the server who is delivering the script.

&lt;source&gt;
// Possible Example:
script.src = &quot;http://openjsan.org/?v=Utils.program-1.0&amp;b=Firefox-3.5.9&quot;
&lt;/source&gt;

Then it that case the server in which contains that script will go through the META handling process for you and it will perform combo loading and packing to optimize performance.

=== Package Managers ===

Package managers may create separate JSON files for module metadata, for example for the module /Module/Stub.js the package manager may create /data/Module/Stub.json which stores the module's metadata.</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Yabble</title>
    <id>501</id>
    <revision>
      <id>2715</id>
      <timestamp>2010-04-20T13:57:54Z</timestamp>
      <contributor>
        <username>Jbrantly</username>
        <id>109</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=Yabble
|url=http://github.com/jbrantly/yabble
|engines=web browsers
|authors=jbrantly
}}</text>
    </revision>
  </page>
  <page>
    <title>Modules/Metadata/Purpose</title>
    <id>502</id>
    <revision>
      <id>2723</id>
      <timestamp>2010-04-21T11:43:06Z</timestamp>
      <contributor>
        <username>Jhuni</username>
        <id>106</id>
      </contributor>
      <text xml:space="preserve">== Goals ==

=== Performance ===

The Modules/Metadata proposal was developed with client-side performance in mind.

=== Extensibility ===

It is easy to extend the metadata format to add new features, such as ways of handling css, images, or other forms of external dependencies, furthermore the metadata can also be used by developers for all sorts of other purposes.

== Problems Solved ==

=== Synchronicity ===

The require statement of [[Modules/1.0]] is too tied to blocking IO and the server side. One of the principles of this proposal is that IO should be asynchronous and non-blocking on the server-side as well as the client-side.

&lt;source&gt;
// Block the UI and all processing until we load the add module
// Also if the add module happens to be online at the time, then everything might hang.
var add = require('math').add;
&lt;/source&gt;

'''Solution:''' This proposal solves this problem by using a source filter to build a function wrapper that is friendly to asynchronous loaders, or by wrapping a module in one of the [[Module/Transport]] schemes.

=== Dependency Resolution ===

[[Modules/1.1.1]] specifies that you should handle your dependencies by placing require statements around your module, perhaps this works on the server-side, however, on the client-side you need to get the dependencies pre-runtime, so in order to get the dependencies it is recommended that you use regular expressions such as this one:

&lt;source&gt;
// from: http://github.com/jbrantly/yabble/blob/master/yabbler.js
var requireRegex = /(?:^|[^\w\$_.])require\s*\(\s*(&quot;[^&quot;\\]*(?:\\.[^&quot;\\]*)*&quot;|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g;
&lt;/source&gt;

The dependencies are not that accessible if you have to use regular expressions to get them, and some specifications state that you have to use string literals in your require statements to aid such static analysis tools, this is confusing to JavaScript users who expect functions to behave as functions.

&lt;source&gt;
// Error: only use a string literal in your require statements:
require( moduleName );
require( isPositive ? &quot;Utils.inc&quot; : &quot;Utils.dec&quot; );
(require ? require : function() {})(&quot;Utils.inc&quot;);

eval( &quot;require('Utils.inc')&quot; );

var alternativeName = require;
alternativeName(&quot;Utils.inc&quot;);
&lt;/source&gt;

'''Solution:''' This proposal solves this problem by storing all metadata as JSON a format which is widely accepted and its parser is built right into JavaScript, that way if you want you can get the metadata without any regular expressions or string handling functions.

=== Keyword Dependency ===

Some users may be discouraged by the [[Modules/1.1.1]] dependency on introduced keywords such as exports, require, and module. This proposal gives you all the features of the Modules specification without depending on any keywords.

&lt;source&gt;
META({

    &quot;returns&quot;: &quot;exports&quot;,
    
    &quot;use&quot;: {
        // Specify that you want to use an old version of require()
        // that is to use the 1.0 version.
        &quot;require&quot;: &quot;js-require-1.0-commonjs&quot;
    }

});
&lt;/source&gt;

'''Solution''': this proposal solves this by assuming that you don't want any keywords unless you specify that you want them in your META header, however, if you completely omit your META header from your file then some implementations may assume that you are using a commonjs module.</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Ejscript</title>
    <id>503</id>
    <revision>
      <id>2743</id>
      <timestamp>2010-04-26T20:20:44Z</timestamp>
      <contributor>
        <username>Mob</username>
        <id>56</id>
      </contributor>
      <comment>Created page with '{{Implementation |name=Ejscript |url=http://github.com/embedthis/ejs-2 |engines=Ejscript |authors=mob }}'</comment>
      <text xml:space="preserve">{{Implementation
|name=Ejscript
|url=http://github.com/embedthis/ejs-2
|engines=Ejscript
|authors=mob
}}</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing/B</title>
    <id>504</id>
    <revision>
      <id>2748</id>
      <timestamp>2010-04-27T18:31:01Z</timestamp>
      <contributor>
        <username>Alexanderteinum</username>
        <id>112</id>
      </contributor>
      <comment>Change assert.ok() and assert.equal() to use strict equality by default, add assert.looseEqual() and notLooseEqual(), remove assert.strictEqual() and assert.notStrictEqual()</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
|specification=yes
|participants=
|discussion=
|implementations=
}}

= Specification =

Not yet versioned. Based on [[Unit_Testing/1.0|1.0]].

== Assert ==

1. The &lt;tt&gt;assert&lt;/tt&gt; module provides functions that throw &lt;tt&gt;AssertionError&lt;/tt&gt;'s when particular conditions are not met.  The &lt;tt&gt;assert&lt;/tt&gt; module must conform to the following interface.

&lt;source&gt;var assert = require(&quot;assert&quot;);&lt;/source&gt;

2. The AssertionError is defined in &lt;tt&gt;assert&lt;/tt&gt;.

&lt;source&gt;
new assert.AssertionError({message: message, actual: actual, expected: expected})
assert.AssertionError instanceof Error
&lt;/source&gt;

At present only the three keys mentioned above are used and understood by the spec. Implementations or sub modules can pass other keys to the AssertionError's constructor - they will  be ignored.

3. All of the following functions must throw an &lt;tt&gt;AssertionError&lt;/tt&gt; when a corresponding condition is not met, with a message that may be undefined if not provided.  All assertion methods provide both the actual and expected values to the assertion error for display purposes.

4. Pure assertion tests whether a value is &lt;code&gt;true&lt;/code&gt;, as determined by &lt;code&gt;guard === true&lt;/code&gt;.

&lt;source&gt;assert.ok(guard, message_opt);&lt;/source&gt;

This statement is equivalent to &lt;code&gt;assert.equal(guard, true, message_opt);&lt;/code&gt;.  To test loosely for the value &lt;code&gt;true&lt;/code&gt;, use &lt;code&gt;assert.looseEqual(guard, true, message_opt);&lt;/code&gt;.

5. The equality assertion tests shallow equality with &lt;code&gt;===&lt;/code&gt;.

&lt;source&gt;assert.equal(actual, expected, message_opt);&lt;/source&gt;

6. The non-equality assertion tests for whether two objects are not equal with &lt;code&gt;!==&lt;/code&gt;.

&lt;source&gt;assert.notEqual(actual, expected, message_opt);&lt;/source&gt;

7. The equivalence assertion tests a deep equality relation.  

* 7.1. All identical values are equivalent, as determined by &lt;tt&gt;===&lt;/tt&gt;.
* 7.2. If the expected value is a Date object, the actual value is equivalent if it is also a Date object that refers to the same time.
* 7.3. Other pairs that do not both pass &lt;tt&gt;typeof value == &quot;object&quot;&lt;/tt&gt;, equivalence is determined by &lt;tt&gt;==&lt;/tt&gt;.
* 7.4. For all other &lt;tt&gt;Object&lt;/tt&gt; pairs, including &lt;tt&gt;Array&lt;/tt&gt; objects, equivalence is determined by having the same number of owned properties (as verified with &lt;tt&gt;Object.prototype.hasOwnProperty.call&lt;/tt&gt;), the same set of keys (although not necessarily the same order), equivalent values for every corresponding key, and an identical &quot;prototype&quot; property.  Note: this accounts for both named and indexed properties on Arrays.

&lt;source&gt;assert.deepEqual(actual, expected, message_opt);&lt;/source&gt;

8. The non-equivalence assertion tests for any deep inequality.

&lt;source&gt;assert.notDeepEqual(actual, expected, message_opt);&lt;/source&gt;

9. The loose equality assertion tests loose equality, as determined by &lt;tt&gt;==&lt;/tt&gt;.

&lt;source&gt;assert.looseEqual(actual, expected, message_opt);&lt;/source&gt;

10. The loose non-equality assertion tests for loose inequality, as determined by &lt;tt&gt;!=&lt;/tt&gt;.

&lt;source&gt;assert.notLooseEqual(actual, expected, message_opt);&lt;/source&gt;

11. Expected to throw an error:

&lt;source&gt;assert.throws(block, Error_opt, message_opt);&lt;/source&gt;

== Test ==

12. The &quot;test&quot; module provides a &quot;run&quot; method that runs unit tests and catalogs their results.  The &quot;run&quot; method must return the total number of failures, suitable for use as a process exit status code.  The idiom for a self-running test module program would be:

&lt;source&gt;
if (module === require.main) 
    require(&quot;test&quot;).run(exports); 
&lt;/source&gt;

13. &lt;tt&gt;run&lt;/tt&gt; must accept any &lt;tt&gt;Object&lt;/tt&gt;, usually a unit test module's exports.  &quot;run&quot; will scan the object for all functions and object properties that have names that begin with but are not equal to &quot;test&quot;, and other properties for specific flags.  Sub-objects with names that start with but are not equal to &quot;test&quot; will be run as sub-tests.  

A future version of this specification may add a mechanism for changing the mode of test functions from fail-fast (where failed assertions throw) to fail-slow (where failed assertions just log/print) via a &lt;tt&gt;logger&lt;/tt&gt; argument or similar, but in the interim, this is implementation specific.

&lt;source&gt;
// ./sub-test
exports.testPatience = function () {
    require('os').sleep(1000);
};
&lt;/source&gt;

&lt;source&gt;
// ./test
exports.testSubTest = require(&quot;./sub-test&quot;);
&lt;/source&gt;

14. Test names may be any String that begins with &quot;test&quot;, not necessarily respecting a case convention.

&lt;source&gt;
[
    [{&quot;a&quot;: 10}, {&quot;a&quot;: 10}],
    [[1, 2, 3], [1, 2, 3]]
].forEach(function (pair) {
     exports['test ' + pair[0].toSource()] = function () {
         assert.equal.apply(assert, pair);
     };
});

exports[&quot;test behaviour X&quot;] = function() {
    behaviour.X()
}
&lt;/source&gt;

= Notes =

== Custom Assert Modules ==

The assertions defined above will not be to everyone's taste style wise (or infact behaviour wise.) Authors are free to define their own assertion methods in new modules as desired. To make it possible to combine assertions from different modules in one test suite, all assert methods must throw a &lt;tt&gt;AssertionError&lt;/tt&gt; (or something that is an &lt;tt&gt;instanceof AssertionError&lt;/tt&gt;).

Below is an example of how a custom assert module could be defined:

&lt;source&gt;
// file: my-check.js
exports.check = function(actual) {
    return {
        is: function(expect, message) {
            if (actual != expect)
                throw new AssertionError({actual: actual, expected: expected, message: message});
        },
    }
}
&lt;/source&gt;

&lt;source&gt;
// This would be used as follows:
var check = require(&quot;my-check&quot;).check;
exports.testSomething = function() {
    var sq = Math.pow(3, 2);
    check(sq).is(9, &quot;3 squared is 9&quot;);
}
&lt;/source&gt;

If future versions of this spec add a logger mechanism (with the intent of making it so that a failed assertion doesn't abort the above case) then the implementation above for &lt;tt&gt;check.is&lt;/tt&gt; will need to be updated.

== Implementations ==

None as yet.

== Unit Tests ==

# http://github.com/commonjs/commonjs/tree/master/tests/unit-testing/1.0/
# None yet for this version.

== Relevant Discussions ==

Up to [[Unit_Testing/1.0|1.0]]:

* [http://groups.google.com/group/commonjs/browse_thread/thread/2952de9982fc2b55 Unit Testing 1.0 Candidate]
* [http://groups.google.com/group/commonjs/browse_thread/thread/77abf61133d26c22 Recount on Unit Testing API (was: Vote: use QUnit API or Unit Testing/A)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/236024c7269bc9ec Vote: use QUnit API or Unit Testing/A]
* [http://groups.google.com/group/commonjs/browse_thread/thread/bf1e7ce55320f0b8 Revisiting &quot;include&quot; (was: QUnit and CommonJS)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/269253f5b713c5c5 QUnit and CommonJS]
* [http://groups.google.com/group/commonjs/browse_thread/thread/daee7099261d8d9a Unit Testing A Show of Hands III]
* [http://groups.google.com/group/commonjs/browse_thread/thread/77ca421f63017b3f Unit Testing Show of Hands II]
* [http://groups.google.com/group/commonjs/browse_thread/thread/a0db8fb0a815a6fe Unit Testing, Testing for Missing &quot;var&quot;s.]
* [http://groups.google.com/group/commonjs/browse_thread/thread/07c69484abc8a560 Unit Testing Show of Hands]</text>
    </revision>
  </page>
  <page>
    <title>Encodings/C</title>
    <id>505</id>
    <revision>
      <id>2755</id>
      <timestamp>2010-04-29T19:10:59Z</timestamp>
      <contributor>
        <username>Aristid</username>
        <id>46</id>
      </contributor>
      <comment>/* Stateful encodings */</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
|implementations=
}}

'''Derived from [[Encodings/A]] to support [[Binary/F]]. Some convenience has been removed to allow this.'''

For Streams, we need encodings support. There also should be a low-level API available for this. It should support asynchronicity.

= Specification =

== Encoding Names ==

The encoding names should be among those supported by ICONV, which seem to be a superset of http://www.iana.org/assignments/character-sets.

The following encodings are required:
* US-ASCII
* UTF-8
* UTF-16
* ISO-8859-1

Encoding names &lt;b&gt;must&lt;/b&gt; be case &lt;b&gt;insensitive&lt;/b&gt;

== API ==

OK, so probably this should be a module:

&lt;source&gt;
var enc = require('encodings')
&lt;/source&gt;

=== Simple methods ===

For convenience, there should be these easy methods for converting between encodings:

; string = enc.convertToString(sourceEncoding, buffer)
: Converts a Buffer to a Javascript string.
; buffer = enc.convertFromString(targetEncoding, string)
: Converts a Javascript string to a Buffer.
; out_buffer = enc.convert(sourceEncoding, targetEncoding, in_buffer)
: Converts a Buffer to a Buffer.

=== Checking for available encodings ===

; enc.supports(encodingName)
: Checks if encodingName is supported and return true if so, false otherwise.
;  enc.listEncodings([encodingCheckerFunction or regex])
: encodingCheckerFunction takes the encoding name as a parameter and returns true-ish if the encoding should be listed. Regexes should also be supported. If the parameter is missing, returns all supported encodings.

=== Class: Transcoder ===

There also should be a class enc.Transcoder for general transcoding conversion (between ByteStrings or ByteArrays).

; [Constructor] Transcoder(from, to)
: Where from and to are the encoding names.
; [Constant] sourceCharset
: String containing the (possibly normalised) source charset name.
; [Constant] destinationCharset
: String containing the (possibly normalised) destination charset name.
; [Method] push(buffer)
: Convert input from a Buffer. Those parts of buffer that could not be converted (for multi-byte encodings) are stored in a buffer. 
: Returns the converted bytes as a Buffer.
; [Method] close()
: Close the stream. Throws an exception if there was a conversion error (specifically, a partial multibyte character).
: Writes the remaining output bytes into a Buffer and returns that Buffer.
: &lt;i&gt;Also adds initial shift state sequences if required by the encoding.&lt;/i&gt;

'''TODO''': Which exception to throw on error?

= Usage examples =

Example:

&lt;source&gt;
Transcoder = require('encodings').Transcoder
transcoder = new Transcoder('iso-8859-1', 'utf-32')
output = []
output[0] = transcoder.push(input) // input is a Buffer
output[1] = transcoder.close() // and output is an array of Buffers
&lt;/source&gt;

Another example:

&lt;source&gt;
transcoder = new Transcoder('utf-32', 'utf-8')
output = []
while (input = readSomeByteFromSomewhere()) {
        buf = transcoder.push(input, output)
        output.push(buf)
}
output.push(transcoder.close())
output = Buffer.CONCATENATE_MANY(output)
// output is the complete conversion of all the input chunks concatenated now
&lt;/source&gt;

== Stateful encodings ==

Some encodings can carry state across many characters - state which has to be reset at the end of a conversion. This creates the need to ''always'' call transcoder.close() after converting. The simple methods take care of that already. An example of such an encoding would be [http://en.wikipedia.org/wiki/ISO/IEC_2022 ISO-2022-JP], a Japanese encoding. This encoding is compatible with ASCII as long as it is in the initial state. But there is an escape sequence (actually more than one: &lt;tt&gt;ESC ( J&lt;/tt&gt;, &lt;tt&gt;ESC $ @&lt;/tt&gt; and &lt;tt&gt;ESC $ B&lt;/tt&gt;) to get into Kana/Kanji mode, and another escape sequence to get back into ASCII mode: &lt;tt&gt;ESC ( B&lt;/tt&gt;. So a reader of ISO-2022-JP content assumes that, initially, the encoding is in ASCII mode, and as soon as it sees an escape sequence, switches into another mode. Therefore, in order to be able to concatenate files, ISO-2022-JP files should end with &lt;tt&gt;ESC ( B&lt;/tt&gt; if they are in non-ASCII mode at the end.

&lt;source&gt;
      // Te Su To - thanks to miwagawa
      katakana_string = &quot;\u30c6\u30b9\u30c8&quot;,
      katakana_shift_jis = binary.ByteString([
        0x83,0x65,
        0x83,0x58,
        0x83,0x67
      ]),
 
      // Shift to JIS X 0208-1983
      iso2022_FROM_ascii = [ 0x1b,0x24,0x42 ],
      // Shift to ASCII
      iso2022_TO_ascii   = [ 0x1b,0x28,0x42 ],
 
      katakana_iso2022 = binary.ByteString(
        iso2022_FROM_ascii.concat([
          0x25,0x46,
          0x25,0x39,
          0x25,0x48,
        ], iso2022_TO_ascii)
      );
&lt;/source&gt;

If you transcode as in the examples above, this should work.

Flusspferd has some tests for these things in http://github.com/ruediger/flusspferd/blob/master/test/js/encodings.t.js

= Implementation Recommendations =

First of all, it is recommended to implement convertToString, convertFromString and convert with Transcoder.

Secondly, you should make sure that initial shift state support is properly implemented. When you're using iconv, you need to call iconv(cd, 0, 0, &amp;ob, &amp;ol) in Transcoder.close(). An example of what an initial shift state is: In the Japanese ISO-2022-JP encoding, the default state are ASCII bytes. However, the state can be switched to Japanese with an escape sequence. To make sure that at the end of the text, the state is ASCII again, iconv will emit another escape sequence to switch back again. This is important if you want to concatenate ISO-2022-JP texts, and an implementation of Transcoder that doesn't properly emit these sequences is &lt;b&gt;broken&lt;/b&gt;.

= Relevant Discussions =

* [http://groups.google.com/group/commonjs/browse_thread/thread/6365b2a54615a134 Proposal: Encodings API (independent from Streams)]
* [http://groups.google.com/group/commonjs/browse_thread/thread/3faf4a067973a71a How to make Encodings]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f9fcf27e1dd4a8b1 Who's implementing the Encodings API?]

= Other =

[http://flusspferd.org Flusspferd]'s implementation is documented [http://flusspferd.org/docs/js/commonjs%20core/encodings.html here] and [http://flusspferd.org/docs/js/commonjs%20core/encodings/transcoder.html here].</text>
    </revision>
  </page>
  <page>
    <title>Events</title>
    <id>506</id>
    <revision>
      <id>2760</id>
      <timestamp>2010-05-02T02:10:23Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>related discussions</comment>
      <text xml:space="preserve">= Proposals =

* [[Events/A]] NameEmitter, Emitter, Event
* [[Events/B]] Emitter, Signal
* [[Events/C]] Emitter, NameEmitter
* [[Events/D]] strict subset of w3c events


== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/9bd7b457d0bdc85f/bfccd9961dea4335 Events A]
* [http://groups.google.com/group/commonjs/browse_thread/thread/70c0d276dc5fa267/6118058542d95d78 Events A Continued]
* [http://groups.google.com/group/commonjs/browse_thread/thread/36b5533cb6faf77c/a2053581a99aa21b Proposal: Timer]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c6e414e296d3a69a Event API Proposals]</text>
    </revision>
  </page>
  <page>
    <title>Cheap NFL Jerseys</title>
    <id>507</id>
    <revision>
      <id>2777</id>
      <timestamp>2010-05-20T06:54:51Z</timestamp>
      <contributor>
        <username>Gentleman Flying</username>
        <id>117</id>
      </contributor>
      <comment>Created page with 'Every NFL fan has a admired player. Someone that they admire, attending up to, and ambition they could alike be. Well, while your affairs of actuality your admired football amate…'</comment>
      <text xml:space="preserve">Every NFL fan has a admired player. Someone that they admire, attending up to, and ambition they could alike be. Well, while your affairs of actuality your admired football amateur may be continued gone, that doesn't beggarly that you can't dress like them and represent them everywhere you go. That is absolutely why bargain NFL jerseys are absolute for the NFL football fan whether adolescence or adult. Nothing says fan like cutting somebody's clothing, apperceive what I mean? So if you are attractive for abatement accoutrement and uniforms for your admired amateur or team, you accept appear to the appropriate place.&lt;br&gt;&lt;br&gt;
Let's booty a attending at some of the best accepted official bargain nfl jerseys for auction at absolutely absurd prices.&lt;br&gt;&lt;br&gt;
The Adrian Peterson jersey of the Minnesota Vikings is one of the best accepted uniforms there are. This is a replica adolescence jersey that appearance the logo and colors or the Vikings forth with Adrian's cardinal and name. Or you can accept this compatible alone and customized with your own cardinal and name printed on it if you would like.&lt;br&gt;&lt;br&gt;
This replica compatible is fabricated of able polyester cobweb that can be apparatus done with no problem. Its bolt is fabricated to abide tearing, ripping, and staining. It additionally has a able close to abate stretching. As we know, football admirers tend to comedy football, and they appetite to do it in their admired player's apparel, so this accouterment is fabricated to ensure a lot of stress. Of course, this bargain NFL jersey is clearly accountant by the NFL. By the way, barter who bought this NFL accouterment were blessed with the chump account and quick delivery. And they said the uniforms attending 100% authentic.&lt;br&gt;&lt;br&gt;
One of the best accepted bargain NFL jerseys and [http://www.jordanshoesebay.com cheap jordans] anytime is the Peyton Manning compatible and the Indianapolis Colts. This is a dejected replica Reebok jersey with the #18 and the Manning name on the back. This accoutrement is additionally fabricated of able polyester to bear the asperous apartment of the youths and adults that abrasion it. It has a able v-beck with the NFL football adumbration at the basal of V. The breach bead appendage replicates the authentic, official NFL jersey perfectly. The Reebock logo is printed on anniversary sleeve to add to the actuality of this clothing. Of course, this compatible is official and accountant by the National Football League.&lt;br&gt;&lt;br&gt;
You can acquirement this compatible anywhere from $70 - $80. Everyone that has bought and advised this jersey gave it a 5-star review. They say that jersey looked aloof like it did on the Internet, and that the aggregation was a amusement to accord with. This is a absolute allowance for anyone adolescent or old, adolescence or adult.&lt;br&gt;&lt;br&gt;
For alone $55, you can own of the best accepted football uniforms on the bazaar today. That is the jersey of Ben Roethlisberger of the Pittsburgh Steelers. The polyester cobweb of this compatible forth with the abundant stitch assignment makes it assume like this is abundant added than a replica jersey - it seems like it is absolutely authentic.&lt;br&gt;&lt;br&gt;
You can get this Steelers accoutrement alone and customized with your own name and cardinal if you would like, or you can leave it with Roethlisberger's name and cardinal on it. Either way, you won't be aghast as this is one of the best bargain NFL jerseys and bargain jordans available. Oh yeah, it is apparatus washable as able-bodied which agency that you can accumulate it apple-pie and attractive brand-spanking new.&lt;br&gt;&lt;br&gt;
Want to go old academy and but some bequest NFL uniforms? No botheration - we accept aggregate you charge including accurate jerseys appropriate here. Bequest legends such as Walter Payton, Lawrence Taylor, John Elway, Joe Montana, Walter Payton - you can get all of these bequest uniforms and added alignment from $60 - $150. Of course, you are activity to get the abstract NFL shield, the bequest attractive jerseys with the player's name and cardinal on it, and these are all clearly accountant by the NFL.&lt;br&gt;&lt;br&gt;
Sizes of these throwbacks uniforms will alpha at baby and go to 5X large. With 8 altered sizes, you won't accept any botheration at all award absolutely what you are attractive for. These jerseys are absolutely alleged replithentic jerseys. Of course, it is replica accouterment for adolescence and adults to enjoy, but they assume so absolute and official that you would affirm they were all 100% accurate apparel. Best of these bequest uniforms cannot be alone and customized with your name.&lt;br&gt;&lt;br&gt;
And don't anticipate this is all of your choices for bargain NFL jerseys. There are a ton added players [http://www.jordanshoesebay.com jordan shoes sale] you can buy. With abounding of them, you accept the advantage of accepting your player's name and cardinal on them, or you can personalize and adapt them with you own name and number. We are talking players like Tony Romo, Brett Favre, Drew Brees, Braylon Edwards, Ricky Williams, Joe Flacco, and Tom Brady aloof to name a few.&lt;br&gt;&lt;br&gt;
Most of these bargain NFL jerseys are fabricated by Reebok, one of the best trusted makers of football apparel. Reebok was absolutely amorphous in 1890 in England by a man who added spikes to shoes so athletes could run faster and quicker. Athletes such as Allen Iverson, Peyton Manning, Yao Ming, and Josh Beckett currently abrasion Reebok accoutrement and shoes.</text>
    </revision>
  </page>
  <page>
    <title>Implementations/NarwhalRhino</title>
    <id>508</id>
    <revision>
      <id>2784</id>
      <timestamp>2010-05-23T23:54:10Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Created page with '{{Implementation |name=Narwhal on Rhino |url=http://github.com/tlrobinson/narwhal |engines=Rhino |authors=Tlrobinson, KrisKowal }}'</comment>
      <text xml:space="preserve">{{Implementation
|name=Narwhal on Rhino
|url=http://github.com/tlrobinson/narwhal
|engines=Rhino
|authors=Tlrobinson, KrisKowal
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/NarwhalJSC</title>
    <id>509</id>
    <revision>
      <id>2785</id>
      <timestamp>2010-05-23T23:54:58Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Created page with '{{Implementation |name=Narwhal on JSC |url=http://github.com/280north/narwhal-jsc |engines=JSC |authors=Tlrobinson }}  Adapters for JavaScriptCore'</comment>
      <text xml:space="preserve">{{Implementation
|name=Narwhal on JSC
|url=http://github.com/280north/narwhal-jsc
|engines=JSC
|authors=Tlrobinson
}}

Adapters for JavaScriptCore</text>
    </revision>
  </page>
  <page>
    <title>Implementations/NarwhalNode</title>
    <id>510</id>
    <revision>
      <id>2786</id>
      <timestamp>2010-05-23T23:55:50Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Created page with '{{Implementation |name=Narwhal on Node |url=http://github.com/kriskowal/narwhal-node |engines=v8 |authors=KrisKowal, Paul Baumgart }}  Adapters for running Narwhal on Node on v8.'</comment>
      <text xml:space="preserve">{{Implementation
|name=Narwhal on Node
|url=http://github.com/kriskowal/narwhal-node
|engines=v8
|authors=KrisKowal, Paul Baumgart
}}

Adapters for running Narwhal on Node on v8.</text>
    </revision>
  </page>
  <page>
    <title>How to Choose Among Cheap NFL Jerseys</title>
    <id>511</id>
    <revision>
      <id>2792</id>
      <timestamp>2010-05-26T06:57:25Z</timestamp>
      <contributor deleted="deleted" />
      <comment>Created page with 'The National Football League season matches occur once every year. Beginning the weekend after Labor Day, the football madness rages for full seventeen weeks, but when it all end…'</comment>
      <text xml:space="preserve">The National Football League season matches occur once every year. Beginning the weekend after Labor Day, the football madness rages for full seventeen weeks, but when it all ends the fans will have to make do with memories until next year. For some being able to achieve what their heroes are doing is a life time dream. Even though you can only imagine being them, you can buy [http://www.godiscount.us nfl jerseys] jerseys that are replicas of your favorite footballer's jerseys. If you want to find out some tips, read the rest of this article.&lt;br&gt;&lt;br&gt;
The first thing to do when you decide to buy one is to get on a computer and search for the different options available. By comparing the different options available online you may even be able to land a bargain. It also makes sense to buy in bulk with a few of your friends. Some sellers will give free shipping as well as lower costs if you buy in bulk.&lt;br&gt;&lt;br&gt;
But before you can make your buying decision you have to decide which player's name you want on your jersey. Better still you can even have your own name printed on the shirt with your favorite player's number on it.&lt;br&gt;&lt;br&gt;
Some sellers will also offer you the option of customizing your jerseys even as far as club colors go. So you can get your name, with your lucky number and your preferred clubs colors. It is also possible to order jerseys for you and your friends with your very own colors. The internet opens a whole new way of buying products; it can help you get exactly what you want if you have the money to afford it.&lt;br&gt;&lt;br&gt;
When spending on jerseys try to avoid the temptation to just buy the cheapest ones. Good quality jerseys are made from polyester and can be used to play in actual games as well. The best part is that if you can get autographs of a star player on one of the jerseys, several years down the road it could become a collector's item.&lt;br&gt;&lt;br&gt;
The value of a collector's jersey at that time will also be based on the quality of the Jersey. Not only that, Even though they may cost a few extra bucks to get good quality jerseys are durable and very comfortable to wear.&lt;br&gt;&lt;br&gt;
Replicas that are available are priced based on the closeness of details to the original. So a Jersey that looks exactly like the original ones worn by the player will cost a lot. But it's always a good idea to buy as close to original as possible. It's worth it when you and your buddies show up to the games wearing these - you never know they might even mistake you for the stars themselves.&lt;br&gt;&lt;br&gt;
The effort that you have spent in searching for this page and reading it till now shows exactly how interested in getting the best for yourself. And to be very frank with you, [http://www.veryverycheap.us cheap nfl] Jerseys are the easiest way to step into the shoes of your favorite player.</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Wakanda</title>
    <id>512</id>
    <revision>
      <id>2809</id>
      <timestamp>2010-05-27T11:51:40Z</timestamp>
      <contributor>
        <username>Alexandre.Morgaut</username>
        <id>33</id>
      </contributor>
      <text xml:space="preserve">{{Implementation
|name=Wakanda
|url=http://www.wakandasoft.com
|engines=JavaScriptCore/C++
|authors=Alexandre.Morgaut
}}


The '''Wakanda project''' include a '''Server''' with a '''NoSQL data store''', a '''Studio''', and an '''Ajax Framework'''.

It is a [http://www.4D.com 4D] project created by '''Laurent Ribardiere'''



It was presented at:
# the Ajax Experience 2009
# the JSConf.eu 2009

(JSConf.us 2010 was missed because of the volcano...)

[http://www.slideshare.net/alexandre_morgaut/wakanda-js-conf-eu-09-slideshare Slide's of the JSConf presentation]



Twitter contacts:
# [http://twitter.com/wakandasoft @wakandasoft]
# [http://twitter.com/amorgaut @amorgaut]</text>
    </revision>
  </page>
  <page>
    <title>Packages/Mappings/B</title>
    <id>513</id>
    <revision>
      <id>2828</id>
      <timestamp>2010-06-15T23:23:07Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Charles shows his hand</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
}}

'''-1: Ash Berlin, Isaac Schlueter, Charles Jolley'''

'''+1: Kris Zyp, ChristophDorn, Irakli Gozalishvili, Kris Kowal'''

== Package Mappings ==

This specification describes an addition to the CommonJS package format for packages to define how they expect their module namespace to be mapped into the module name spaces of referenced packages.  This specification introduces a &quot;mappings&quot; property that describes special behavior of the &quot;require&quot; function that is scoped to all modules in the given package, such that top level identifiers starting with particular values for their first slash-delimited term correspond to top-level modules in the respectively mapped package. This specification does not define how the modules of referenced packages are installed or retrieved, and it does not define how any module identifiers are resolved apart from those that are mapped.

Example:

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: &quot;http://github.com/them/theirpackage/zipball/master&quot;
     }
 }


== Specification ==

The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,  &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.

=== Packages ===

# The &lt;code&gt;package.json&lt;/code&gt; at the root of a package directory  tree or archive MAY have a &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; property.
# The &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; property maps single-term top-level module identifiers to external package references.
# A single-term top-level module identifier MUST consist of only lower-case letters, digits, underscore, and hyphen.  ''Note: It MUST not include a slash (&lt;code&gt;&quot;/&quot;&lt;/code&gt;) or dot (&lt;code&gt;&quot;.&quot;&lt;/code&gt;).''
# If an external package reference is a string, it is equivalent to an object with that string as its &lt;code&gt;&quot;location&quot;&lt;/code&gt; property.
# An external package reference MUST have a &lt;code&gt;&quot;location&quot;&lt;/code&gt; property.
## The &lt;code&gt;&quot;location&quot;&lt;/code&gt; MUST be an HTTP URL String.
## If the &lt;code&gt;&quot;location&quot;&lt;/code&gt; ends with a slash (&lt;code&gt;&quot;/&quot;&lt;/code&gt;), it MUST refer to the root of a directory tree conforming to the content of a package as described by [[Packages]] and where every contained file is retrievable with an HTTP GET request for a path resolved based on the given location.
## If the &lt;code&gt;&quot;location&quot;&lt;/code&gt; does not end with a slash (&lt;code&gt;&quot;/&quot;&lt;/code&gt;), it MUST refer to an archive as described by [[Packages]] and retrievable with a single HTTP GET request.
# An external package reference MAY have a &lt;code&gt;&quot;descriptor&quot;&lt;/code&gt; property that is a limited package descriptor object, a strict subset of the &lt;code&gt;package.json&lt;/code&gt; schema as described in [[Packages]].
## A package descriptor MAY have a &lt;code&gt;&quot;index&quot;&lt;/code&gt; property &lt;code&gt;String&lt;/code&gt; that is a path relative to the root of the package URL or archive.
## A package descriptor MAY have a &lt;code&gt;&quot;directories&quot;&lt;/code&gt; property.
### The &lt;code&gt;&quot;directories&quot;&lt;/code&gt; Object MAY have a &lt;code&gt;&quot;lib&quot;&lt;/code&gt; property, which MUST be a &lt;code&gt;String&lt;/code&gt; describing a relative path, resolved from the root of a package or archive.
# If &lt;code&gt;package.json&lt;/code&gt; contains an &lt;code&gt;&quot;overlay&quot;&lt;/code&gt; property, and any of the applicable values of the overlay property (as defined by [[Packages]]) contain a &quot;mappings&quot; property, the (key, value) pairs of the main &quot;mappings&quot; property MUST be updated with each applicable overlaid mappings property, overriding existing (key, value) pairs.
# If the &lt;code&gt;&quot;location&quot;&lt;/code&gt; of the package refers to a retrievable archive, an external package reference MAY have a &lt;code&gt;&quot;verify&quot;&lt;/code&gt; property that is an &lt;code&gt;Object&lt;/code&gt;.
## The &lt;code&gt;&quot;verify&quot;&lt;/code&gt; object MUST have a &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; property that refers to the algorithm with which the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; was generated.
## The &lt;code&gt;&quot;verify&quot;&lt;/code&gt; object MUST have a &lt;code&gt;&quot;signature&quot;&lt;/code&gt; property that is a signature or hash of the referenced archive.
## The &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be a lower-case base-16 value represented as a string of colon-delimited bytes.
## The &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; MAY be &lt;code&gt;&quot;md5&quot;&lt;/code&gt;, in which case the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be a MD5 digest of the package archive file, computed as described in RFC 1321.
## The &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; MAY be &lt;code&gt;&quot;sha1&quot;&lt;/code&gt;, in which case the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be an SHA-1 digest of the package archive file, computed as described in RFC 3174.

''Note: this specification does not define the behavior of any other verification algorithms.  These may be amended in a future revision.''

''Note: this specification does not define any archival formats apart from zip since this is the only standard format described in [[Packages]], and may be amended in a future revision of that specification, in which case corresponding verbiage must be added to this specification to indicate the archival format of the an external package.''

=== Modules ===

Within a package, the semantics of the &lt;code&gt;require&lt;/code&gt; function are augmented as follows:

# If the required module identifier is not relative, it is a candidate for referencing a module in an external package.
## If the identifier has only one term (''That is, contains no slashes (&lt;code&gt;&quot;/&quot;&lt;/code&gt;'')), it is a candidate for referencing the index module of an external package.
### If this package is external to another package, and the parent package has an &lt;code&gt;&quot;index&quot;&lt;/code&gt; property in its mapping for this package, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the specified index module of the external package.
### Otherwise, if the external package does have an &lt;code&gt;&quot;index&quot;&lt;/code&gt; property in its &lt;code&gt;package.json&lt;/code&gt; file, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the index module of the external package.
### Otherwise, &lt;code&gt;require&lt;/code&gt; MUST throw an &lt;code&gt;Error&lt;/code&gt;.
## If the identifier has multiple terms delimited by slashes, it is a candidate for referencing a module in the library directory of an external package.
### If the first term of the module identifier as delimited by slashes is not a property of the &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; object in the current package's &lt;code&gt;package.json&lt;/code&gt;, the behavior of &lt;code&gt;require&lt;/code&gt; is beyond the scope of this specification and follows through with the behavior defined in [[Packages]] in the context of the current package.
### If the first term of the module identifier as delimited by slashes is a property of the &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; object in the current package's &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the module with the top-level identifier composed of all subsequent slash-delimited terms in the required module identifier in the context of the referenced external package as defined in [[Packages]].
#### If the external package reference contains a &lt;code&gt;descriptor.directories.lib&lt;/code&gt; property, the modules from the external package MUST be found in the named lib directory, resolved relative to the root of the external package.

=== The Index Module ===

# In the evaluation context of an index module, the value of the &lt;code&gt;module&lt;/code&gt; free variable does not have an &lt;code&gt;&quot;id&quot;&lt;/code&gt; property.

== Examples ==

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: &quot;http://github.com/them/theirpackage/zipball/master&quot;
     }
 }

This example is equivalent to the above example, by virtue of rotating the package location into an external package reference object.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;location&quot;: &quot;http://github.com/them/theirpackage/zipball/master&quot;
         }
     }
 }

This example includes an annotation on where to find the index module of a legacy Narwhal external package, and an annotation describing the SHA-1 hash of the package archive for verification purposes.

 {
     &quot;name&quot;: &quot;jill&quot;,
     &quot;mappings&quot;: {
         &quot;jack&quot;: {
             &quot;location&quot;: &quot;http://github.com/280north/jack/zipball/master&quot;,
             &quot;descriptor&quot;:
                 &quot;index&quot;: &quot;lib/jack.js&quot;,
                 &quot;directories&quot;: {
                     &quot;lib&quot;: &quot;lib/jack&quot;
                 }
             },
             &quot;verify&quot;: {
                 &quot;signature&quot;: &quot;c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87&quot;,
                 &quot;algorithm&quot;: &quot;sha1&quot;
             }
         }
     }
 }

The following example indicates how you might externally reference a package that was not designed for CommonJS:

 {
    &quot;name&quot;: &quot;mypackage&quot;,
    &quot;mappings&quot;: {
        &quot;dojox&quot;: {
            &quot;location&quot;: &quot;http://download.dojotoolkit.org/release-1.4.3/dojo-release-1.4.3.zip&quot;,
            &quot;descriptor&quot;: {
                &quot;directories&quot;: {
                    &quot;lib&quot;: &quot;dojox&quot;
                }
            }
        }
    }
 }

== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/3b6cf9d18df7379d package.json mappings]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c3aaaa406d794b79 packages]</text>
    </revision>
  </page>
  <page>
    <title>Packages/Mappings/C</title>
    <id>514</id>
    <revision>
      <id>2874</id>
      <timestamp>2010-08-04T02:38:45Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <comment>Define behavior for string values in mappings for relative and absolute URLs</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
}}

== Package Mappings ==

This specification describes an addition to the CommonJS package format for packages to define how they expect their module namespace to be mapped into the module name spaces of referenced packages.  This specification introduces a &quot;mappings&quot; property that describes special behavior of the &quot;require&quot; function that is scoped to all modules in the given package, such that top level identifiers starting with particular values for their first slash-delimited term correspond to top-level modules in the respectively mapped package. This specification does not define how the modules of referenced packages are installed or retrieved, and it does not define how any module identifiers are resolved apart from those that are mapped.

== Examples ==

A package that provides the URL of an archive that is known to work as a subpackage.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
            &quot;archive&quot;: &quot;http://github.com/them/theirpackage/zipball/master&quot;
         }
     }
 }

This can be written more tersely:

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: &quot;http://github.com/them/theirpackage/zipball/master&quot;
     }
 }

A package that provides the exact version number of a subpackage that is known to work.  A version number implies that this package is a member of some registry or catalog with consistently named and versioned packages.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;version&quot;: &quot;0.0.1&quot;
         }
     }
 }

The URL of the registry or catalog may be provided for informational purposes, but this specification does not impose any restrictions on the format or content of the registry.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;version&quot;: &quot;0.0.1&quot;
         }
     },
     &quot;catalog&quot;: &quot;http://example.com/packages-catalog.json&quot;
 }

If a package uses sub-packages from a variety of catalogs, the informational catalog URL may be provided for specific mappings.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;version&quot;: &quot;0.0.1&quot;
         },
         &quot;otherpackage&quot;: {
             &quot;version&quot;: &quot;0.0.1&quot;,
             &quot;catalog&quot;: &quot;http://example.org/some/other/catalog.json&quot;
         }
     },
     &quot;catalog&quot;: &quot;http://example.com/packages-catalog.json&quot;
 }

The key of the mapping indicates how the package will be known in modules.  In these examples, the &quot;main&quot; module of &quot;theirpackage&quot; would be imported as &quot;theirpackage&quot;.

 require(&quot;theirpackage&quot;);

If the package comes from a registry of coordinated package names, the name of the package in the repository is assumed to be the same as the key of the mapping.  However, it may be overridden.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;version&quot;: &quot;0.0.1&quot;,
             &quot;name&quot;: &quot;theirpackagename&quot;
         }
     },
     &quot;catalog&quot;: &quot;http://example.com/packages-catalog.json&quot;
 }

Some package managers can fetch individual files from an unpacked package, provided over HTTP at a particular location.  The &lt;code&gt;&quot;location&quot;&lt;/code&gt; key indicates the URL of an unpacked package that is known to work as a subpackage.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;location&quot;: &quot;http://example.com/packages/theirpackage/&quot;
         }
     }
 }

To be compatible with a wide variety of package managers, packages should include a variety of metadata, and may provide all of the defined attributes.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;mappings&quot;: {
         &quot;theirpackage&quot;: {
             &quot;name&quot;: &quot;theirpackagename&quot;,
             &quot;version&quot;: &quot;0.0.1&quot;,
             &quot;archive&quot;: &quot;http://example.com/packages/theirpackage.zip&quot;,
             &quot;location&quot;: &quot;http://example.com/packages/theirpackage/&quot;
         }
     },
     &quot;catalog&quot;: &quot;http://example.com/packages-catalog.json&quot;
 }

# To be compliant with this specification, a package manager must be able to handle any package that provides all of the recommended metadata.
# To be usable by any package manager, a package must provide all of the recommended metadata.

== Specification ==

The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,  &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in RFC 2119.

=== Packages ===

# The &lt;code&gt;package.json&lt;/code&gt; at the root of a package directory  tree or archive MAY have a &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; property.
# &lt;code&gt;package.json&lt;/code&gt;'s &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; property maps single-term top-level module identifiers to external package references.
# A single-term top-level module identifier MUST consist of only lower-case letters, digits, underscore, and hyphen.  ''Note: It MUST not include a slash (&lt;code&gt;&quot;/&quot;&lt;/code&gt;) or dot (&lt;code&gt;&quot;.&quot;&lt;/code&gt;).''
# If an external package reference is a string and the string is an absolute URL, it is equivalent to an object with that string as its &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property.
# If an external package reference is a string and the string is a relative URL, it is equivalent to an object with that string as its &lt;code&gt;&quot;location&quot;&lt;/code&gt; property.
# An external package reference SHOULD have an &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property.  Package managers MAY depend on the provision of this property.
## The &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property MUST be an URL String from which an archive as described by [[Packages]] can be downloaded with an HTTP GET request.
# An external package reference SHOULD have a &lt;code&gt;&quot;location&quot;&lt;/code&gt; property.  Package managers MAY depend on the provision of this property.
## The &lt;code&gt;&quot;location&quot;&lt;/code&gt; property MUST refer to the root of a directory tree conforming to the content of a package as described by [[Packages]] and where every contained file is retrievable by the URL resolved based on the given location. If the &lt;code&gt;&quot;location&quot;&lt;/code&gt; property is a relative URL, it MUST be resolved relative to the package root of the parent package that is being described and contains the mappings (i.e. relative to this package.json file). If the package has been expanded from an archive, the relative URLs MAY point to another directory within the archive.
# An external package reference MAY have a &lt;code&gt;&quot;version&quot;&lt;/code&gt; property.  Package managers MAY depend on the provision of this property.
## If &lt;code&gt;&quot;version&quot;&lt;/code&gt; exists, an external package reference MAY contain a &lt;code&gt;&quot;name&quot;&lt;/code&gt; property that indicates the name of the package in a coordinated registry of packages.  If omitted, this property defaults to the key of the mapping.
# An external package reference MAY have a &lt;code&gt;&quot;descriptor&quot;&lt;/code&gt; property that is a package descriptor object, conforming to the &lt;code&gt;package.json&lt;/code&gt; schema as described in [[Packages]].
# An external package reference MAY have a &lt;code&gt;&quot;catalog&quot;&lt;/code&gt; property that notes the URL of the catalog or registry with which a package manager is expected to associate this external package reference with additional or missing details.
# &lt;code&gt;package.json&lt;/code&gt; may have a &quot;catalog&quot; property that notes the URL of the catalog or registry with which to associate package names and versions with further corresponding external package reference details.
# If the external package reference has a &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property, an external package reference MAY have a &lt;code&gt;&quot;verify&quot;&lt;/code&gt; property that is an &lt;code&gt;Object&lt;/code&gt;.
## The &lt;code&gt;&quot;verify&quot;&lt;/code&gt; object MUST have a &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; property that refers to the algorithm with which the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; was generated.
## The &lt;code&gt;&quot;verify&quot;&lt;/code&gt; object MUST have a &lt;code&gt;&quot;signature&quot;&lt;/code&gt; property that is a signature or hash of the referenced archive.
## The &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be a lower-case base-16 value represented as a string of colon-delimited bytes.
## The &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; MAY be &lt;code&gt;&quot;md5&quot;&lt;/code&gt;, in which case the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be a MD5 digest of the package archive file, computed as described in RFC 1321.
## The &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; MAY be &lt;code&gt;&quot;sha1&quot;&lt;/code&gt;, in which case the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be an SHA-1 digest of the package archive file, computed as described in RFC 3174.

''Note: this specification does not define the behavior of any other verification algorithms.  These may be amended in a future revision.''

''Note: this specification does not define any archival formats apart from zip since this is the only standard format described in [[Packages]], and may be amended in a future revision of that specification, in which case corresponding verbiage must be added to this specification to indicate the archival format of the an external package.''

''Note: This specification does not impose any restrictions on the format of the catalog file, nor even whether it is retrievable.  Package registries or catalogs may opt to disqualify a package based on whether it supports a particular catalog URL, the format of the catalog, or for not providing a catalog URL.''

''Note: An external package reference may contain further properties.  This specification recommends that these properties be prefixed with an implementation name to avoid collisions with properties of other implementations and future versions of this specification.''

=== Modules ===

Within a package, the semantics of the &lt;code&gt;require&lt;/code&gt; function are augmented as follows:

# If the required module identifier is not relative, it is a candidate for referencing a module in an external package.
## If the identifier has only one term (''That is, contains no slashes (&lt;code&gt;&quot;/&quot;&lt;/code&gt;'')), it is a candidate for referencing the main module of an external package.
### If this package is external to another package, and the parent package has an &lt;code&gt;&quot;main&quot;&lt;/code&gt; property in its mapping for this package, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the specified main module of the external package.
### Otherwise, if the external package does have an &lt;code&gt;&quot;main&quot;&lt;/code&gt; property in its &lt;code&gt;package.json&lt;/code&gt; file, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the main module of the external package.
### Otherwise, &lt;code&gt;require&lt;/code&gt; MUST throw an &lt;code&gt;Error&lt;/code&gt;.
## If the identifier has multiple terms delimited by slashes, it is a candidate for referencing a module in the library directory of an external package.
### If the first term of the module identifier as delimited by slashes is not a property of the &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; object in the current package's &lt;code&gt;package.json&lt;/code&gt;, the behavior of &lt;code&gt;require&lt;/code&gt; is beyond the scope of this specification and follows through with the behavior defined in [[Packages]] in the context of the current package.
### If the first term of the module identifier as delimited by slashes is a property of the &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; object in the current package's &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the module with the top-level identifier composed of all subsequent slash-delimited terms in the required module identifier in the context of the referenced external package as defined in [[Packages]].
#### If the external package reference contains a &lt;code&gt;descriptor.directories.lib&lt;/code&gt; property, the modules from the external package MUST be found in the named lib directory, resolved relative to the root of the external package.

== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/3b6cf9d18df7379d package.json mappings]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c3aaaa406d794b79 packages]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f58a017810ffdb78 Towards a Simplified Packages Spec]
* [http://groups.google.com/group/commonjs/browse_thread/thread/d523333df583d11b Packages/1.1 tire kick]
* [http://groups.google.com/group/commonjs/browse_thread/thread/cb8db969eb2dcf7e Semi-related packages question]</text>
    </revision>
  </page>
  <page>
    <title>User:Fgm</title>
    <id>517</id>
    <revision>
      <id>2840</id>
      <timestamp>2010-06-29T08:24:00Z</timestamp>
      <contributor>
        <username>Fgm</username>
        <id>53</id>
      </contributor>
      <comment>Created page with 'Following CommonJS dev but not coding for it (yet ?)'</comment>
      <text xml:space="preserve">Following CommonJS dev but not coding for it (yet ?)</text>
    </revision>
  </page>
  <page>
    <title>Talk:Packages/1.0</title>
    <id>518</id>
    <revision>
      <id>2889</id>
      <timestamp>2010-09-06T17:10:58Z</timestamp>
      <contributor>
        <username>Zimbatm</username>
        <id>72</id>
      </contributor>
      <comment>/* Engines */</comment>
      <text xml:space="preserve">Hi, the following has sprung to my eyes:
* Keyword ''engine'', but the example says ''engines'', which sounds more reasonable due to the array value
* Keyword ''contributors'' mentions ''author''; did you mean ''maintainers''?
* ''&quot; web&quot;'' in the ''maintainers'' example contains a spurious whitespace character
--[[User:Astro|Astro]] 03:27, 14 July 2010 (UTC)

== Engines ==

* What is the engine name for browsers ?  --[[User:Zimbatm|Zimbatm]] 17:10, 6 September 2010 (UTC)</text>
    </revision>
  </page>
  <page>
    <title>User:Astro</title>
    <id>519</id>
    <revision>
      <id>2849</id>
      <timestamp>2010-07-14T03:27:25Z</timestamp>
      <contributor>
        <username>Astro</username>
        <id>125</id>
      </contributor>
      <comment>Created page with 'Mail &amp; XMPP: astro@spaceboyz.net'</comment>
      <text xml:space="preserve">Mail &amp; XMPP: astro@spaceboyz.net</text>
    </revision>
  </page>
  <page>
    <title>Talk:Packages/1.1</title>
    <id>520</id>
    <revision>
      <id>2850</id>
      <timestamp>2010-07-14T03:41:51Z</timestamp>
      <contributor>
        <username>Astro</username>
        <id>125</id>
      </contributor>
      <comment>errata?</comment>
      <text xml:space="preserve">Oops, I accidently read &amp; commented on Packages/1.0. Why do you link to old versions? 2/3 questions remain though:
* Is ''&quot; web&quot;'' a typo?
* Is it ''&quot;engine&quot;'' or ''&quot;engines&quot;''?
--[[User:Astro|Astro]] 03:41, 14 July 2010 (UTC)</text>
    </revision>
  </page>
  <page>
    <title>Packages/Mappings/D</title>
    <id>521</id>
    <revision>
      <id>2858</id>
      <timestamp>2010-07-15T11:45:37Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Undo revision 2855 by [[Special:Contributions/Gozala|Gozala]] ([[User talk:Gozala|Talk]]); If you intend for the removal of a page please tag it for deletion.</comment>
      <text xml:space="preserve">{{Spec
|status=proposal
}}

== Package Mappings / Dependencies ==

This specification extends CommonJS package format for packages to define how
they expect their dependencies to be mapped into the module name spaces. This
specification extends &quot;dependencies&quot; property in package descriptor and
expects that implementers will organize dependencies in way that all modules
from the &quot;dependencies&quot; can be required by a top level identifiers, whose
first slash-delimited term correspond to a key in the &quot;dependencies&quot; map.
This specification does not define how the modules of referenced packages are
installed or retrieved.

== Examples ==

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;dependencies&quot;: {
         &quot;theirpackage&quot;: &quot;http://github.com/Gozala/github/blob/gh-pages/&quot;
     }
 }

Values in the &quot;dependencies&quot; map MUST represent URI's and have to refer
to the root of a dependent package. There for appending 'package.json' to the
dependency URI should give URI to a package descriptor.

Appending 'manifest.json' to a dependency URI MUST give URI to a package
manifest, that is a JSON containing list of modules that package contains.

 [
 	&quot;index&quot;,
 	&quot;foo/bar&quot;,
 	&quot;foo/main&quot;
 ]

Way of expressing version or other information about dependency is by
intension left to a package registries / managers and expected to be embedded
into URI itself.

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;dependencies&quot;: {
         &quot;theirpackage&quot;: &quot;http://npm.com/foo@1.2.3/&quot;
     }
 }

 {
     &quot;name&quot;: &quot;mypackage&quot;,
     &quot;dependencies&quot;: {
         &quot;theirpackage&quot;: &quot;http://mozillalabs.com/jetpack/libs/bar/1.2.3/&quot;
     }
 }

The key for this proposal is to provide a form of requiring modules form a
dependency, regardless of the package manager and registry they come from.

 require(&quot;theirpackage/theirmodule&quot;);

How does package managers register or install individual packages / modules is
out of the scope of this proposal.

# To be compliant with this specification, package manager must be able to
handle any package that provides all of the recommended metadata.
# To be usable by any package manager, a package must provide all of the
recommended metadata.

== Specification ==

The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;,
&quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,  &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be
interpreted as described in RFC 2119.

=== Packages ===

# The &lt;code&gt;package.json&lt;/code&gt; at the root of a package directory tree or
archive MAY have a &lt;code&gt;&quot;dependencies&quot;&lt;/code&gt; property.
# &lt;code&gt;package.json&lt;/code&gt;'s &lt;code&gt;&quot;dependencies&quot;&lt;/code&gt; property maps
single-term top-level module identifiers to external package references.
# A single-term top-level module identifier MUST consist of only lower-case
letters, digits, underscore, and hyphen.  ''Note: It MUST not include a slash
(&lt;code&gt;&quot;/&quot;&lt;/code&gt;) or dot (&lt;code&gt;&quot;.&quot;&lt;/code&gt;).''
# An external package reference SHOULD have an &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property.  Package managers MAY depend on the provision of this property.
## The &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property MUST be an URL String from which an archive as described by [[Packages]] can be downloaded with an HTTP GET request.
# An external package reference SHOULD have a &lt;code&gt;&quot;location&quot;&lt;/code&gt; property.  Package managers MAY depend on the provision of this property.
## The &lt;code&gt;&quot;location&quot;&lt;/code&gt; property MUST refer to the root of a directory tree conforming to the content of a package as described by [[Packages]] and where every contained file is retrievable with an HTTP GET request for a path resolved based on the given location.
# An external package reference MAY have a &lt;code&gt;&quot;version&quot;&lt;/code&gt; property.  Package managers MAY depend on the provision of this property.
## If &lt;code&gt;&quot;version&quot;&lt;/code&gt; exists, an external package reference MAY contain a &lt;code&gt;&quot;name&quot;&lt;/code&gt; property that indicates the name of the package in a coordinated registry of packages.  If omitted, this property defaults to the key of the mapping.
# An external package reference MAY have a &lt;code&gt;&quot;descriptor&quot;&lt;/code&gt; property that is a package descriptor object, conforming to the &lt;code&gt;package.json&lt;/code&gt; schema as described in [[Packages]].
# An external package reference MAY have a &lt;code&gt;&quot;catalog&quot;&lt;/code&gt; property that notes the URL of the catalog or registry with which a package manager is expected to associate this external package reference with additional or missing details.
# &lt;code&gt;package.json&lt;/code&gt; may have a &quot;catalog&quot; property that notes the URL of the catalog or registry with which to associate package names and versions with further corresponding external package reference details.
# If the external package reference has a &lt;code&gt;&quot;archive&quot;&lt;/code&gt; property, an external package reference MAY have a &lt;code&gt;&quot;verify&quot;&lt;/code&gt; property that is an &lt;code&gt;Object&lt;/code&gt;.
## The &lt;code&gt;&quot;verify&quot;&lt;/code&gt; object MUST have a &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; property that refers to the algorithm with which the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; was generated.
## The &lt;code&gt;&quot;verify&quot;&lt;/code&gt; object MUST have a &lt;code&gt;&quot;signature&quot;&lt;/code&gt; property that is a signature or hash of the referenced archive.
## The &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be a lower-case base-16 value represented as a string of colon-delimited bytes.
## The &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; MAY be &lt;code&gt;&quot;md5&quot;&lt;/code&gt;, in which case the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be a MD5 digest of the package archive file, computed as described in RFC 1321.
## The &lt;code&gt;&quot;algorithm&quot;&lt;/code&gt; MAY be &lt;code&gt;&quot;sha1&quot;&lt;/code&gt;, in which case the &lt;code&gt;&quot;signature&quot;&lt;/code&gt; MUST be an SHA-1 digest of the package archive file, computed as described in RFC 3174.

''Note: this specification does not define the behavior of any other verification algorithms.  These may be amended in a future revision.''

''Note: this specification does not define any archival formats apart from zip since this is the only standard format described in [[Packages]], and may be amended in a future revision of that specification, in which case corresponding verbiage must be added to this specification to indicate the archival format of the an external package.''

''Note: This specification does not impose any restrictions on the format of the catalog file, nor even whether it is retrievable.  Package registries or catalogs may opt to disqualify a package based on whether it supports a particular catalog URL, the format of the catalog, or for not providing a catalog URL.''

''Note: An external package reference may contain further properties.  This specification recommends that these properties be prefixed with an implementation name to avoid collisions with properties of other implementations and future versions of this specification.''

=== Modules ===

Within a package, the semantics of the &lt;code&gt;require&lt;/code&gt; function are augmented as follows:

# If the required module identifier is not relative, it is a candidate for referencing a module in an external package.
## If the identifier has only one term (''That is, contains no slashes (&lt;code&gt;&quot;/&quot;&lt;/code&gt;'')), it is a candidate for referencing the main module of an external package.
### If this package is external to another package, and the parent package has an &lt;code&gt;&quot;main&quot;&lt;/code&gt; property in its mapping for this package, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the specified main module of the external package.
### Otherwise, if the external package does have an &lt;code&gt;&quot;main&quot;&lt;/code&gt; property in its &lt;code&gt;package.json&lt;/code&gt; file, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the main module of the external package.
### Otherwise, &lt;code&gt;require&lt;/code&gt; MUST throw an &lt;code&gt;Error&lt;/code&gt;.
## If the identifier has multiple terms delimited by slashes, it is a candidate for referencing a module in the library directory of an external package.
### If the first term of the module identifier as delimited by slashes is not a property of the &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; object in the current package's &lt;code&gt;package.json&lt;/code&gt;, the behavior of &lt;code&gt;require&lt;/code&gt; is beyond the scope of this specification and follows through with the behavior defined in [[Packages]] in the context of the current package.
### If the first term of the module identifier as delimited by slashes is a property of the &lt;code&gt;&quot;mappings&quot;&lt;/code&gt; object in the current package's &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;require&lt;/code&gt; MUST return the exports of the module with the top-level identifier composed of all subsequent slash-delimited terms in the required module identifier in the context of the referenced external package as defined in [[Packages]].
#### If the external package reference contains a &lt;code&gt;descriptor.directories.lib&lt;/code&gt; property, the modules from the external package MUST be found in the named lib directory, resolved relative to the root of the external package.

== Related Discussions ==

* [http://groups.google.com/group/commonjs/browse_thread/thread/3b6cf9d18df7379d package.json mappings]
* [http://groups.google.com/group/commonjs/browse_thread/thread/c3aaaa406d794b79 packages]
* [http://groups.google.com/group/commonjs/browse_thread/thread/f58a017810ffdb78 Towards a Simplified Packages Spec]
* [http://groups.google.com/group/commonjs/browse_thread/thread/d523333df583d11b Packages/1.1 tire kick]
* [http://groups.google.com/group/commonjs/browse_thread/thread/cb8db969eb2dcf7e Semi-related packages question]</text>
    </revision>
  </page>
  <page>
    <title>HTTP-Gateway</title>
    <id>522</id>
    <revision>
      <id>2865</id>
      <timestamp>2010-07-16T07:41:18Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <minor/>
      <comment>6 revisions:&amp;#32;Import my HTTP-Gateway proposal, decommissioning the accessjs wiki</comment>
      <text xml:space="preserve">This is an interface used by any http gateway handler. A handler's job is to talk
with a webserver (or act as one) in some way (mod_ handler, CGI handler, FastCGI handler, built-in http server, Servlet handler, etc...)
and provide an api conforming to this spec which it makes a call to the gateway using app with to handle the http request and response.

The API used in this spec was designed arround an inverted XMLHttpRequest object, with some high-level things removed, static content properties and events converted to streaming, and some server functionality patterns from the JSGI/Rack/WSGI group of protocols. Middleware is NOT a target of this spec, middleware is a semi-high level funcationality, this spec's target is low-level functionality only. Middleware can be implemented inside of a gateway interface built on top of this gateway interface written in pure-js (ie: You can write JSGI entirely using this http-gateway, heck you could write a node compatible API port using this http-gateway).

This API is independent of sync or async code. It works purely on a streaming basis. The implementation is expected to:
# read the status line and the headers (or grab them from whatever api)
# look for a content-length header and use it to wrap the input stream (or make the input stream return EOF right away if no content-length is present)
# wrap the output stream in this api
# then pass it to the gateway app
Once the api leaves the gateway handler control over the response is completely up to the gateway app. It is the gateway app's responsibility to end the request by calling .close(); The function returning signifies nothing to the handler other than the gateway being ready to accept another request. So it doesn't matter to the handler whether the gateway app is streaming or doing some other action asynchronously.

== Quick Overview ==
&lt;source&gt;
exports.(app|gateway?) = function(r) {
	r.gateway.version = [1, 0];
	r.gateway.multithread;
	r.gateway.multiprocess;
	r.gateway.runonce;
	r.env; // An object containing various pieces of data from the server;
	       // Env variables for CGI, passed faux env for FastCGI, handler dependant on other types of handlers.
	r.connected; // boolean true, will change to boolean false if the client has disconnected
	
	// Request (all keys must be present and of the correct type)
	r.method === &quot;GET&quot;; // must be uppercase string
	r.scheme === &quot;http&quot;; // must be lowercase string
	r.serverName; // string; ip, static hostname, etc... (NOT the value of the Host: header)
	r.serverPort; // 80, etc...
	r.scriptName; // String coresponding to the application location. &quot;&quot; if at site root, string starting with / otherwise. (decoded)
	r.pathInfo; // ... (decoded)
	r.queryString; // string
	r.getRequestHeader('Content-Type');
	r.read(#);
	r.read();
	
	// Response
	r.status = 200;
	r.statusText = &quot;OK&quot;; // optional status text. Some handlers may ignore this,
	                     // handlers should understand the relation of basic http status codes
	                     // to their status text in some way (even if that is allowing apache or something else handle that)
	r.addResponseHeader('Content-Type', 'text/html'); // Should throw an error if .flush() has already been called.
	r.write(data); // First call implies a call to .flush()
	r.flush(); // Flushes buffered data if buffering is used and flushing is possible;
	           // First call sends status and headers through handler and signifies finalization of them, rejection of headers after that is enforced.
	r.close();
};
&lt;/source&gt;

== API ==
;connected: A boolean indicating if the client is still connected. Checking this periodically is useful to understand if you should abort what you are doing.

;method: The method of request used as an uppercase string.
;scheme: The protocol used in the request as a lowercase string. This is normally only ever &quot;http&quot; or &quot;https&quot;.
;serverName: 
;serverPort:
;scriptName: (decoded)
;pathInfo: (decoded)
;queryString: The query string from the response.
;getRequestHeader(headerName);
:
;read(max);
:

;status
:The numeric http status code to return. This is the only necessary interface for defining the return status. The handler must map the standard HTTP numeric status codes to their default status text.

;statusText
:An optional extra interface to the status text. You may set this to override the status text printed beside the status code. This interface is not necessary for use for the standard http headers, the handler must know how to map status codes to status text when overrides are not specified.
:Note that some handlers may ignore this property if the system they connect does not provide a way to set the status text.

;addResponseHeader(headerName, headerValue);
:Adds a response header to the headers in the response. Multiple headers of the same kind can be written with separate calls. New calls will not overwrite old headers.

;flush();
:Ensures current buffered data is flushed to the output stream.
:On first call this method forces the status line and headers to be sent, and terminates headers (the blank line indicating the start of the body). After this is called all calls to addResponseHeader will throw.

;write(data);
:Writes a chunk of data to the output stream.
:Data must be a object that returns a Blob on valueOf(&quot;blob&quot;);
:On first call this implies a call to .flush();

;close();
:This closes the connection with the browser ending the response.

== ToFix ==
* getRequestHeader is implemented for the most flexibility, however to implement JSGI's env/req object with HTTP-Gateway we'll need a method that allows the list of all sent headers to be obtained so that the .headers object can be created.
* Should we note that calls to addResponseHeader with newlines in the headerValue should write out the header in extended header format (ie: A single header where it is extended to multiple lines by prepending each line with leading whitespace):
&lt;pre&gt;X-Example: asdf
 asdf&lt;/pre&gt;</text>
    </revision>
  </page>
  <page>
    <title>AIO</title>
    <id>523</id>
    <revision>
      <id>2866</id>
      <timestamp>2010-07-16T09:11:28Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <comment>Created page with ''''AIO''' (Advanced IO) is an API idea based on Java's NIO as well as some high-level ideas. The intent is to provide a powerful api which is clean to use and can be optimized we…'</comment>
      <text xml:space="preserve">'''AIO''' (Advanced IO) is an API idea based on Java's NIO as well as some high-level ideas. The intent is to provide a powerful api which is clean to use and can be optimized well by the implementation.

* [[/ByteBuffer/]]
* [[/Stream/]]
* [[/Patterns and Examples/]]
* [[/Multi-Thread/]]</text>
    </revision>
  </page>
  <page>
    <title>AIO/ByteBuffer</title>
    <id>524</id>
    <revision>
      <id>2869</id>
      <timestamp>2010-07-16T09:19:22Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">Buffer; Abstract

ByteBuffer is an abstract, potentially virtual, optimized binary storage object.

We say a ByteBuffer can be &quot;virtual&quot; because a ByteBuffer does not care that it's
data be non-shared, be located in mem with the same capacity as the buffer says
it is, or even be aranged in memory in the way it looks. The only thing that matters
is that the API works as expected.

This is why we have duplicate methods like reset() and clear().
If a ByteBuffer had been optimizing in a special way to avoid the need to copy
data to the start of the buffer and was instead artificially shrinking the
capacity of the buffer and using an internal offset the act of calling reset()
on it which has an implied contract that the data will not be scrambled would
force the buffer to copy the data to the start of the buffer in order to avoid
scrambling the data unexpectedly. However the clear() operation behaves the same
as reset() except it does not have the contract of maintaining that data, the
ByteBuffer is free to do whatever it wants with the data. In this case because
the ByteBuffer does not have to worry about the data being scrambled instead of
copying the data to the start of the buffer in memory it could instead leave
the data where it is and reset the internal offset, this would have the effect
of making it look to a programa as if the start of the buffer was shifted forward
an arbatrary length, however it is a faster operation than reset() because it
doesn't need to copy the data to the start of the buffer to avoid creating that
false impression.

We also say that it can be &quot;virtual&quot; because it doesn't care that the data is
actually a managed buffer in memory mirroring the data. ByteBuffer works fine
with a section of memory that is actually mmaped, actually belongs to the os'
filesystem cache, etc... as long as the ByteBuffer behaves in the way it is
expected to. So it is possible to optimize it to shuffle data around while
avoiding various inefficient operations. It is also possible to use .range to
create a buffer which is actually backed by a portion of another ByteBuffer and
which will modify it's data.

;ByteBuffer.cast(data);
:Converts data into a ByteBuffer. If the data cannot be converted into a byte buffer a TypeError is thrown (a RangeError is thrown if a number not within 0-255 was passed or used in an array). Generally cast supports passing in a single number (turned into a cap=1 buffer with that 0-255 number as it's only byte)
:
;new ByteBuffer(capacity);
;new ByteBuffer(data);
:Create a new ByteBuffer, you can also omit the `new` keyword and get the same result. ByteBuffer's constructor accepts any data that .cast accepts however using a number creates a buffer with that capacity, not a single byte buffer with that number inside it. Please use ByteBuffer.cast instead of the ByteBuffer constructor if you are trying to take foreign data and cast it to a ByteBuffer to use. Please note that calling ByteBuffer's constructor with an instance of another byte buffer will not create a copy of that buffer, it will create a buffer instance which is backed by the other buffer. In other words operations on the new buffer will affect the content of the buffer that was passed to it.
;.position;
:The current position which relative operations will start at. Relative operations will throw an error when called if position is less than 0 or greater than limit.
;.limit;
:The position where relative operations will stop. Relative operations will throw an error when called if limit is less than 0 or greater than capacity.
;.capacity; read-only;
:The capacity this buffer has.
;.remaining; getter;
:The number of elements remaining between the position and the limit.

;.reset();
:resets the position to 0, the limit to the capacity, and discards the mark. Use of this method implies that the data inside the ByteBuffer will still be the same after calling the method. Use this operation if you want to make sure that after the reset the actual data inside the buffer is the same. If you don't care about the actual content of the buffer please use .clear() instead, in some cases clear() can be more efficient than using .reset() because without the requirement of maintaining the content of the buffer it is sometimes possible for the implementation to optimise by avoiding heavy operations required to maintain the data when resetting the position and limit at the cost of scrambling the data within the buffer causing it to appear to the app differently than it was before the use of clear()

;.clear();
:resets the position to 0, the limit to the capacity, and discards the mark. Use of this method does not require that the data inside the buffer be the same after the method is called, the implementation is free to scramble the content of the buffer to anything it wants if it will optimise the performance of the buffer. If you do not care about the content of the buffer, please use this method instead of using .reset() or manually resetting the position and limit yourself. .reset() should only be used instead of .clear() if you require that the buffer's content be the same after calling it.

;.clone();
:Creates a new ByteBuffer with the same content, capacity, position, limit, and mark values. The new ByteBuffer is not backed by the content of this buffer, it is independent (writing to either buffer will not modify the contents of the other buffer). Please note that use of this method is preferable to manually creating a buffer with the same content. Manually copying the data will likely require that the data is actually copied. However using .clone only mandates that it looks like the data has been copied. This means that if a half-decent Copy-On-Write setup is used, it is possible for the act of using .clone() on a buffer, and then reading data from it may actually never to an expensive memory copy if the original buffer is never modified during that time. If you want to create a copy of a buffer with the same content but using an initial set of cap, pos, limit, and mark values it is potentially more efficient to call .clone().reset() than it is to create a new buffer and copy the data from the buffer into the new one.

;.range();
;.range(start, stop);
:Returns a new Buffer of the same class backed by a portion of this buffer. The new buffer will have a capacity and limit set to the size of the data the buffer is backing, and position of 0, the mark will be unset. If start and stop are not specified the new buffer will back the portion of the buffer which is currently between .position and .limit and the new buffer's capacity and limit will be equivalent to what this buffer's .remaining was.</text>
    </revision>
  </page>
  <page>
    <title>AIO/Patterns and Examples</title>
    <id>525</id>
    <revision>
      <id>2871</id>
      <timestamp>2010-07-16T09:43:29Z</timestamp>
      <contributor>
        <username>Dantman</username>
        <id>1</id>
      </contributor>
      <text xml:space="preserve">&lt;source&gt;

// Starts piping from streamA into streamB in the background and returns a concurrent promise
streamA.pipeTo(streamB);

// Start up two processes
var cmdA = Process.start(&quot;cmdA&quot;);
var cmdB = Process.start(&quot;cmdB&quot;);

// Wrap some data in a ByteBufferStream and pipe it into the stdin of the first command
new ByteBufferStream(someData).pipeTo(cmdA.stdin);
// Pipe the first command's stdout into the second command's stdin
cmdA.stdout.pipeTo(cmdB.stdin);
// The stdout of the second command can be read
cmdB.stdout; // ...

// An example use... a poor man's gzip libraryless gzip
var gzip = Process.start(&quot;gzip&quot;);
new ByteBufferStream(someData).pipeTo(gzip.stdin);
gzip.stdout.pipeTo(...); // ... would be a stream such as the output stream for a http request

/** Transfering data from one stream to another **/
// High-Level //
// This starts the piping in the background in a separate thread, it returns a
// concurrent promise you can wait on or register an async callback
from.pipeTo(to);

// Mid-Level //
// This transfers data from one stream to another without using any js level buffer
// In some cases like in Java where one of the streams is backed by a file
// this can even try and avoid a deal of unnecessary copying.
while ( !from.eof )
	from.transferTo(to, 1024);

// Low-Level
var buf = new ByteBuffer(1024);
// ...
buf.clear();

while ( from.read(buf) &gt;= 0 || buf.position ) { // If we read some data, or still have unwritten data
  buf.???(); // java calls it flip; We ready the buffer for writing by setting the limit to the position and resetting the position to 0
  to.write(buf);
  buf.???();  // java calls it compact; The buffer is prepared in a way so that the next .read will put data into the unused portion of the buffer
}

&lt;/source&gt;</text>
    </revision>
  </page>
  <page>
    <title>User:Hdon</title>
    <id>526</id>
    <revision>
      <id>2872</id>
      <timestamp>2010-07-22T18:32:21Z</timestamp>
      <contributor>
        <username>Wesgarland</username>
        <id>13</id>
      </contributor>
      <comment>Created page with '[[Real Name::Donny Viszneki]]'</comment>
      <text xml:space="preserve">[[Real Name::Donny Viszneki]]</text>
    </revision>
  </page>
  <page>
    <title>Implementations/RequireJS</title>
    <id>528</id>
    <revision>
      <id>2880</id>
      <timestamp>2010-08-30T10:08:54Z</timestamp>
      <contributor>
        <username>Temsa</username>
        <id>132</id>
      </contributor>
      <comment>creation</comment>
      <text xml:space="preserve">{{Implementation
|name=RequireJS
|url=http://requirejs.org
|engines=web browsers, rhino
}}</text>
    </revision>
  </page>
  <page>
    <title>Packages/Registry</title>
    <id>529</id>
    <revision>
      <id>2887</id>
      <timestamp>2010-09-01T17:37:28Z</timestamp>
      <contributor>
        <username>IsaacSchlueter</username>
        <id>52</id>
      </contributor>
      <comment>tabs</comment>
      <text xml:space="preserve">&lt;h1 id=&quot;packages_registry&quot;&gt;Packages/Registry&lt;/h1&gt;

&lt;p&gt;This specification describes a method for identifying package descriptors by a combination of name, version, and registry base URL.&lt;/p&gt;

&lt;p&gt;A package registry is considered &amp;#8220;CommonJS Compliant package registry&amp;#8221; if it implements the API described in this specification.&lt;/p&gt;

&lt;p&gt;The &amp;#8220;client&amp;#8221; refers to a package.json-aware system that uses a CommonJS Compliant package registry to locate packages.&lt;/p&gt;

&lt;h2 id=&quot;scope&quot;&gt;Scope&lt;/h2&gt;

&lt;p&gt;This API &lt;em&gt;only&lt;/em&gt; describes identifying and locating packages.  It specifically does not describe the mechanisms by which packages are added &lt;em&gt;to&lt;/em&gt; the registry.  It is assumed that each registry may implement different mechanisms for user authentication, package acceptance, package removal, and so on.&lt;/p&gt;

&lt;p&gt;Furthermore, this specification &lt;em&gt;only&lt;/em&gt; dictates the behavior for the URLs it describes.  Any URL which is not a valid registry root url, package root url, or package version url, is not defined by this specification.&lt;/p&gt;

&lt;p&gt;This API does not assume any particular implementation technology.&lt;/p&gt;

&lt;h2 id=&quot;http_request_method_and_headers&quot;&gt;HTTP Request Method and Headers&lt;/h2&gt;

&lt;p&gt;HTTP GET is the only method required for consuming the data in a package registry.  Registries MAY use other methods for entering data into the registry, authenticating user accounts, and so on, but that is outside the scope of this specification.&lt;/p&gt;

&lt;p&gt;Clients SHOULD send an Accept header of &lt;code&gt;application/json&lt;/code&gt;.  Behavior of the registry in the presence of other Accept headers is undefined.  For instance, a Compliant registry MAY send an HTML document description of a package if given the Accept value of &lt;code&gt;text/html&lt;/code&gt;, or it MAY send JSON in all cases.&lt;/p&gt;

&lt;p&gt;Registries MUST send responses with an &lt;code&gt;application/json&lt;/code&gt; Content-Type if the client sends an Accept header value of &lt;code&gt;application/json&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;http_errors&quot;&gt;HTTP Errors&lt;/h2&gt;

&lt;p&gt;In the case of errors, registries SHOULD still send any response body in the form of valid JSON with an &lt;code&gt;error&lt;/code&gt; member, and optionally any other useful information.  For instance:&lt;/p&gt;

&lt;pre&gt;HTTP/1.1 404 Object Not Found
Content-Length: 52

{&quot;error&quot;:&quot;not found&quot;,&quot;reason&quot;:&quot;document not found&quot;}
&lt;/pre&gt;

&lt;p&gt;Registries MAY send back an empty response body, but any response body that is sent MUST be valid JSON.&lt;/p&gt;

&lt;h2 id=&quot;urls&quot;&gt;URLs&lt;/h2&gt;

&lt;p&gt;The following classes of urls are described:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;registry root url&lt;/li&gt;
&lt;li&gt;package root url&lt;/li&gt;
&lt;li&gt;package version url&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;registry_root_url&quot;&gt;registry root url&lt;/h3&gt;

&lt;p&gt;Examples: &lt;code&gt;http://registry.npmjs.org/&lt;/code&gt; &lt;code&gt;http://js.packag.es/registry/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The root URL is the base of the package registry.  Given this url, a name, and a version, a package can be uniquely identified, assuming it exists in the registry.&lt;/p&gt;

&lt;p&gt;When requested, the package root URL SHOULD return a list of packages in the registry in the form of a hash of package names to package root descriptors.&lt;/p&gt;

&lt;p&gt;The package root descriptor MUST be either: an Object that would be valid for the &amp;#8220;package root url&amp;#8221; contents for the named package, or a string URL that should be used as the &lt;code&gt;package root url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the case of a string URL, it MAY refer to a different registry.  In that case, a request for &lt;code&gt;{registry root url}/{package name}&lt;/code&gt; SHOULD be EITHER a 301 or 302 redirect to the same URL as named in the string value, OR a valid &amp;#8220;package root url&amp;#8221; response.&lt;/p&gt;

&lt;p&gt;The following would be a valid response for the package root url at &lt;code&gt;http://example.com/&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;{ &quot;foo&quot; : &quot;http://foo.com/package/versions/foo&quot;
, &quot;quux&quot; : &quot;http://example.com/quux&quot;
, &quot;asdf&quot; : &quot;http://example.com/-/third-party/asdf&quot;
, &quot;bar&quot; :
  { &quot;name&quot; : &quot;bar&quot;
  , &quot;maintainers&quot; : [ { &quot;name&quot; : &quot;isaacs&quot;, &quot;email&quot; : &quot;i@izs.me&quot; } ]
  , &quot;mtime&quot;: &quot;2010-08-29T23:10:47Z&quot;
  , &quot;versions&quot; : { &quot;1.0.0&quot; : &quot;http://example.com/bar/1.0.0&quot; }
  }
, &quot;baz&quot; :
  { &quot;name&quot; : &quot;baz&quot;
  , &quot;versions&quot; :
	{ &quot;1.0.0&quot; :
	  { &quot;name&quot; : &quot;baz&quot;
	  , &quot;version&quot; : &quot;1.0.0&quot;
	  , &quot;main&quot; : &quot;./lib/baz.js&quot;
	  , &quot;description&quot; : &quot;The bazziest!&quot;
	  , &quot;dist&quot; : { &quot;tarball&quot; : &quot;http://example.com/-/baz-1.0.0.tgz&quot; }
	  }
	}
  }
}
&lt;/pre&gt;

&lt;p&gt;The &amp;#8220;foo&amp;#8221; package is a redirect to another registry.  The &amp;#8220;quux&amp;#8221; package is served from the typical URL on this registry, but not listed in the registry root response.  The &amp;#8220;asdf&amp;#8221; package is served from this registry, but at a different URL.  The &amp;#8220;bar&amp;#8221; package lists top-level information but supplies a URL for specific versions.  The &amp;#8220;baz&amp;#8221; package lists top-level information as well as package descriptors for specific versions.&lt;/p&gt;

&lt;h3 id=&quot;package_root_url&quot;&gt;package root url&lt;/h3&gt;

&lt;p&gt;The package root url is the base URL where a client can get top-level information about a package and all of the versions known to the registry.&lt;/p&gt;

&lt;p&gt;A valid &amp;#8220;package root url&amp;#8221; response MUST be returned when the client requests &lt;code&gt;{registry root url}/{package name}&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;redirection&quot;&gt;Redirection&lt;/h4&gt;

&lt;p&gt;The package root URL SHOULD be found at &lt;code&gt;{registry root url}/{package name}&lt;/code&gt;.  If the registry would rather proxy to a different URL for a specific package, then it MUST respond with a 301 or 302 status code and a Location header to the desired address.  It MAY send a JSON response body with a &amp;#8220;location&amp;#8221; field containing the intended location.  For example, requesting &lt;code&gt;http://example.com/foo&lt;/code&gt; in the previous example might return this:&lt;/p&gt;

&lt;pre&gt;HTTP 1.1/302 Found
Location: http://foo.com/package/versions/foo
Content-Type: application/json
Content-Length: 54

{ &quot;location&quot; : &quot;http://foo.com/package/versions/foo&quot; }
&lt;/pre&gt;

&lt;p&gt;Redirection may also be used within the same host if the registry wishes to serve package root information from a different location than &lt;code&gt;{registry root url}/{package name}&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;package_root_object&quot;&gt;Package Root Object&lt;/h4&gt;

&lt;p&gt;The root object that describes all versions of a package MUST be a JSON object with the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name: The name of the package.  When both are decoded, this MUST match the &amp;#8220;package name&amp;#8221; portion of the URL.  That is, packages with irregular characters in their names would be URL-Encoded in the request, and JSON-encoded in the data.  So, a request to &lt;code&gt;/%C3%A7%C2%A5%C3%A5%C3%B1%C3%AE%E2%88%82%C3%A9&lt;/code&gt; would show a package root object with &amp;#8220;\u00e7\u00a5\u00e5\u00f1\u00ee\u2202\u00e9&amp;#8221; as the name, and would refer to the &amp;#8220;ç¥åñî∂é&amp;#8221; project.&lt;/li&gt;
&lt;li&gt;versions: An object hash of version identifiers to valid &amp;#8220;package version url&amp;#8221; responses: either URL strings or package descriptor objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following fields are optional, and thus MAY be present in the package root response.  If they are present, then they MUST have the meanings described:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mtime: The last modified time of the package root object, expressed as an ISO String.&lt;/li&gt;
&lt;li&gt;ctime: The creation time of the package root object, expressed as an ISO String.&lt;/li&gt;
&lt;li&gt;maintainers: An array of identifiers of package registry users who maintain the package described.&lt;/li&gt;
&lt;li&gt;repository: The repository where the project source is managed.  This SHOULD match the repository field on the most recently published version of the package.&lt;/li&gt;
&lt;li&gt;url: A URL where the package root object can be found.  (This is largely unnecessary in the case of requesting a package root object directly, but can be helpful with abbreviated package root objects are returned in the registry root response.)&lt;/li&gt;
&lt;li&gt;description: A description of the project.  This SHOULD match the description field on the most recently published version of the package.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;package_version_url&quot;&gt;package version url&lt;/h3&gt;

&lt;p&gt;The package version url is the base URL where a client can get package descriptor information about a specific version of a package.&lt;/p&gt;

&lt;p&gt;A valid &amp;#8220;package version url&amp;#8221; response MUST be returned when the client requests &lt;code&gt;{registry root url}/{package name}/{package version}&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;redirection&quot;&gt;Redirection&lt;/h4&gt;

&lt;p&gt;The package version URL SHOULD be found at &lt;code&gt;{registry root url}/{package name}/{package version}&lt;/code&gt;.  If the registry would rather proxy to a different URL for a specific package version, then it MUST respond with a 301 or 302 status code and a Location header to the desired address.  It MAY send a JSON response body with a &amp;#8220;location&amp;#8221; field containing the intended location.  For example, requesting &lt;code&gt;http://example.com/foo/1.0.0&lt;/code&gt; in the previous example might return this:&lt;/p&gt;

&lt;pre&gt;HTTP 1.1/302 Found
Location: http://foo.com/package/versions/foo/1.0.0
Content-Type: application/json
Content-Length: 60

{ &quot;location&quot; : &quot;http://foo.com/package/versions/foo/1.0.0&quot; }
&lt;/pre&gt;

&lt;p&gt;Redirection may also be used within the same host if the registry wishes to serve package root information from a different location than &lt;code&gt;{registry root url}/{package name}/{package version}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In this example, the &amp;#8220;foo&amp;#8221; package root was served on a different registry.  If that registry is also a CommonJS Compliant Package Registry, then tacking &lt;code&gt;/1.0.0&lt;/code&gt; onto the package root URL would be a valid package version url.&lt;/p&gt;

&lt;h4 id=&quot;package_version_object&quot;&gt;Package Version Object&lt;/h4&gt;

&lt;p&gt;The Package Version Object is almost identical to the Package Descriptor object described in the CommonJS Packages specification.  For the purposes of the package registry, the following fields are required.  Note that some of these do not exist in the Packages specification.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name: The package name.  This MUST match the &lt;code&gt;{package name}&lt;/code&gt; portion of the URL.&lt;/li&gt;
&lt;li&gt;version: The package version.  This MUST match the &lt;code&gt;{package version}&lt;/code&gt; portion of the URL.&lt;/li&gt;
&lt;li&gt;dist: An object hash with urls of where the package archive can be found.  The key is the type of archive.  At the moment the following archive types are supported, but more may be added in the future:
&lt;ul&gt;
&lt;li&gt;tarball: A url to a gzipped tar archive containing a single folder with the package contents (including the package.json file in the root of said folder)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;changes_to_packages_spec&quot;&gt;Changes to Packages Spec&lt;/h2&gt;

&lt;p&gt;Besides the addition of fields to the Package Version Object, this addition to the Packages spec imposes the following restrictions on the &amp;#8220;name&amp;#8221; and &amp;#8220;version&amp;#8221; fields:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MUST NOT start with &amp;#8220;-&amp;#8220;&lt;/li&gt;
&lt;li&gt;MUST NOT contain any &amp;#8220;/&amp;#8221; characters&lt;/li&gt;
&lt;li&gt;MUST NOT be &amp;#8220;.&amp;#8221; or &amp;#8220;..&amp;#8221;&lt;/li&gt;
&lt;li&gt;SHOULD contain only URL-safe characters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This makes it simpler for package names and versions to map to a URL scheme.  Since they may not start with &amp;#8220;-&amp;#8220;, this makes it possible for registry owners to &amp;#8220;escape&amp;#8221; from the package registry on the same hostname.&lt;/p&gt;

&lt;p&gt;For example, a package registry owner might wish to serve the tarball for &amp;#8220;foo&amp;#8221; version 1.0.0 from &lt;code&gt;http://example.com/foo/-/foo-1.0.0.tgz&lt;/code&gt;.  Since &lt;code&gt;-&lt;/code&gt; is never a valid version, this will not be interpreted as a request for package data.  (See &amp;#8220;Scope&amp;#8221; above.)&lt;/p&gt;

&lt;h3 id=&quot;changes_to_package_dependencies&quot;&gt;Changes to Package Dependencies&lt;/h3&gt;

&lt;p&gt;The package &lt;code&gt;dependencies&lt;/code&gt; hash may now be augmented with information about which registry is to be queried for matching dependencies.  A &lt;code&gt;registry&lt;/code&gt; field may be provided:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;at the top level of the package.json descriptor&lt;/li&gt;
&lt;li&gt;individually for each dependency.  In this case, the dependency name is the key, and the value is an object with &amp;#8220;version&amp;#8221; and &amp;#8220;registry&amp;#8221; strings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a registry is provided, then it MUST be the registry root url of a CommonJS Compliant Package Registry.  If provided, clients SHOULD query this registry for package data.  If not provided, then clients MAY default to any or no registry URL.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;pre&gt;{ &quot;name&quot; : &quot;foo&quot;
, &quot;registry&quot; : &quot;http://example.com/registry/&quot;
, &quot;dependencies&quot; :
  { &quot;bar&quot; : &quot;1.0.2&quot;
  , &quot;baz&quot; :
    { &quot;version&quot; : &quot;1.2.3&quot;
    , &quot;registry&quot; : &quot;http://baz.com/packages/&quot;
    }
  }
}
&lt;/pre&gt;

&lt;h2 id=&quot;prior_art&quot;&gt;Prior Art&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;npm Registry http://registry.npmjs.org/&lt;/li&gt;
&lt;/ul&gt;</text>
    </revision>
  </page>
  <page>
    <title>Packages/Transport</title>
    <id>530</id>
    <revision>
      <id>2891</id>
      <timestamp>2010-09-07T03:28:36Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposal
|standard=yes
}}

== Packages Transport ==

This specification describes how to transport contents of a CommonJS package from a server to an asynchronous browser-based client side loader. Given the URL of a package, regardless of the domain of the package (whether it be the same as the requested page or not) a client side loader should be able to load the metadata of the package and modules within that package based on a module id within the package.

== Specification ==

A package that is intended to be available for client side usage and complies with this specification SHOULD provide a &quot;package.js&quot; resource at the root URL of the package. This module SHOULD provide the client with package metadata by calling the require.package function. A package.js resource, as well as any other JavaScript resource in the package, may call require.def or require.define, as defined by the Modules Transport specification to register modules (package.js may include module definitions in order to avoid multiple requests). However, the require.package call SHOULD proceed any require.def calls.

== require.package ==

The require.package function must take a single argument that is a JavaScript object that corresponds to the package metadata. The properties of the package metadata object should follow the CommonJS package specification. For example, a package.js could include:

  require.package({
    name: &quot;foo&quot;,
    description: &quot;some package&quot;
  });

Any require.def calls that exist in the package.js after the require.package call MAY use relative module ids to identify themselves. The module id should be resolved relative to the lib root of the package.

== Background ==
* [http://groups.google.com/group/commonjs/browse_thread/thread/51e760229cd0d933 Cross-domain loading of package metadata]</text>
    </revision>
  </page>
  <page>
    <title>Packages/Mappings</title>
    <id>531</id>
    <revision>
      <id>2894</id>
      <timestamp>2010-09-07T23:07:51Z</timestamp>
      <contributor>
        <username>KrisKowal</username>
        <id>6</id>
      </contributor>
      <comment>Created an index for the mappings topic</comment>
      <text xml:space="preserve">
= Proposals =

* [[/A]] Kris Zyp
* [[/B]] Kris Kowal based on A
* [[/C]] Kris Kowal based on B
* [[/D]] Gozala based on C</text>
    </revision>
  </page>
  <page>
    <title>Modules/AsynchronousDefinition</title>
    <id>532</id>
    <revision>
      <id>2907</id>
      <timestamp>2010-09-28T01:29:40Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposal
|implementations=RequireJS, Nodules, Yabble
}}

The Asynchronous Module Definition API specifies a mechanism for defining modules such that the module and it's dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross-domain access problems. This specification used to be called Modules Transport/C, but this is specification is not primarily geared for transported existing CommonJS modules, but for defining modules (although it can be used as a transport).

== Specification ==

The specification defines a single function &quot;def&quot; that should be available on the &quot;require&quot; free variable. The signature of the function:

require.def(id?, dependencies?, factory);

The first argument, id, specifies the id of the module being defined. This argument is optional, and if it not present, the module id should default to the id of the module that the loader was requesting for the given response script. When present, the module id MUST be an absolute id (relative ids are not allowed.

The second argument, dependencies, is an array of the dependencies that are required by the module that is being defined. The dependencies must be resolved prior to execution of the module factory function, and the resolved values should be passed as arguments to the factory function with argument positions corresponding to index in the dependencies array. The dependencies ids may be relative ids, and should be resolved relative the module being defined. This specification defines three special dependency names that have a distinct resolution. If the value of &quot;require&quot;, &quot;exports&quot;, or &quot;module&quot; appear in the dependency list, the argument should be resolved to the corresponding free variable as defined by the CommonJS modules specification. This argument is optional. If omitted, it should default to [&quot;require&quot;, &quot;exports&quot;, &quot;module&quot;]. However, if the factory function's arity (length property) is less than 3, than the loader may choose to only call the factory with the number of arguments corresponding to the function's arity or length.

The third argument, factory, is a function that should be executed to instantiate the module or an object. If the factory is a function it should only be executed once. If the factory argument is an object, that object should be assigned as the exported value of the module.

If the factory function returns a value (an object, function, or any value that coerces to true), and then that value should be assigned as the exported value for the module.

If both the first argument (module id) and the second argument (dependencies) are omitted, the module loader MAY choose to scan the factory function for dependencies in the form of require statements (literally in the form of require(&quot;module-string&quot;)). The first argument must literally be named require for this to work. In some situations module loaders may choose not to scan for dependencies due to code size limitations or lack of toString support on functions (Opera Mobile is known to lack toString support for functions). If either the first or second argument is present, the module loader SHOULD NOT scan for dependencies within the factory function.


=== Transporting more than one module at a time ===

Multiple require.def calls can be made within a single script. The order of the require.def calls SHOULD NOT be significant. Earlier module definitions may specify dependencies that are defined later in the same script. It is the responsibility of the module loader to defer loading unresolved dependencies until the entire script is loaded to prevent unnecessary requests.

== Examples ==

=== Using require and exports ===

Sets up the module with ID of &quot;alpha&quot;, that uses require, exports and the module with ID of &quot;beta&quot;:

 require.def(&quot;alpha&quot;, [&quot;require&quot;, &quot;exports&quot;, &quot;beta&quot;], function (require, exports, beta) {
     exports.verb = function() {
         return beta.verb();
         //Or:
         return require(&quot;beta&quot;).verb();
     }
 });

=== Usage notes ===

It is recommended that require.def calls be in the literal form of 'require.def(...)' in order to work properly with static analysis tools (like build tools).</text>
    </revision>
  </page>
  <page>
    <title>Packages/AsynchronousDefinition</title>
    <id>533</id>
    <revision>
      <id>2899</id>
      <timestamp>2010-09-10T02:01:54Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <text xml:space="preserve">{{Spec
|status=proposal
|standard=yes
}}

== Asynchronous Package Definition ==

This specification describes how to define the contents of a CommonJS package with an asynchronous API, specifically to facilitate loading packages in a browser. Given the URL of a package, regardless of the domain of the package (whether it be the same as the requested page or not) a client side browser-based loader should be able to load the metadata of the package and modules within that package based on a module id within the package.

== Specification ==

A package that is intended to be available for client side usage and complies with this specification SHOULD provide a &quot;package.js&quot; resource at the root URL of the package. This module SHOULD provide the client with package metadata by calling the require.package function. A package.js resource, as well as any other JavaScript resource in the package, may call require.def or require.define, as defined by the Asynchronous Module Definition [http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition] specification or Modules Transport [http://wiki.commonjs.org/wiki/Modules/Transport/D] specification to register modules (package.js may include module definitions in order to avoid multiple requests). However, the require.package call SHOULD proceed any require.def calls.

== require.package ==

The require.package function must take a single argument that is a JavaScript object that corresponds to the package metadata. The properties of the package metadata object should follow the CommonJS package specification. 

== Example ==

A package.js could include:

  require.package({
    name: &quot;foo&quot;,
    description: &quot;some package&quot;
  });

Any require.def calls that exist in the package.js after the require.package must use provide module ids (they can not be anonymous, without their first parameter) to identify themselves.

== Background ==
* [http://groups.google.com/group/commonjs/browse_thread/thread/51e760229cd0d933 Cross-domain loading of package metadata]</text>
    </revision>
  </page>
  <page>
    <title>Unit Testing/1.1</title>
    <id>534</id>
    <revision>
      <id>2901</id>
      <timestamp>2010-09-21T14:26:27Z</timestamp>
      <contributor>
        <username>Gozala</username>
        <id>22</id>
      </contributor>
      <comment>Created page with '=Unit Testing/1.1=  ==STATUS: Draft==  ==Specification==  This specification adds following features no top of [http://wiki.commonjs.org/wiki/Unit\_Testing/1.0,Unit Testing/1.0]:…'</comment>
      <text xml:space="preserve">=Unit Testing/1.1=

==STATUS: Draft==

==Specification==

This specification adds following features no top of [http://wiki.commonjs.org/wiki/Unit\_Testing/1.0,Unit Testing/1.0]:

* Mechanism for running tests in &lt;strong&gt;fail-slow&lt;/strong&gt; mode (where
failed assertions just log) on the side to &lt;strong&gt;fail-fast&lt;/strong&gt; mode
(where failed assertions fails entire test).
* Mechanism for running tests in &lt;strong&gt;asynchronous&lt;/strong&gt; mode.


===&quot;Fail-slow&quot; Mode===

All the test functions that would like to run tests in &lt;strong&gt;fail-slow&lt;/strong&gt;
mode &lt;strong&gt;must&lt;/strong&gt; expect to be called by test runner with a first special argument (for simplicity we'll be referring to it as &lt;tt&gt;test&lt;/tt&gt; named argument):

* &lt;tt&gt;typeof&lt;/tt&gt; &lt;tt&gt;test&lt;/tt&gt; is &lt;tt&gt;&quot;function&quot;&lt;/tt&gt;. It &lt;strong&gt;may&lt;/strong&gt; be called with
an arguments: assertion function described by [http://wiki.commonjs.org/wiki/Unit\_Testing/1.0,Unit Testing/1.0] followed by any number of arguments.  
* &lt;tt&gt;test&lt;/tt&gt; function &lt;strong&gt;must&lt;/strong&gt; perform assertion by calling first
argument (assertion function) by passing through all the arguments
starting form second (including all the optional defaulting to
&lt;tt&gt;undefined&lt;/tt&gt; even if they where not passed to &lt;tt&gt;test&lt;/tt&gt;) plus &lt;tt&gt;test&lt;/tt&gt; as a last argument.
* &lt;tt&gt;test&lt;/tt&gt; function &lt;strong&gt;must&lt;/strong&gt; log results for the performed assertion
instead of failing a test.
* &lt;tt&gt;test&lt;/tt&gt; function &lt;strong&gt;must&lt;/strong&gt; log test failure if performed assertion
throws exception other then &lt;tt&gt;AssertionError&lt;/tt&gt;.
* &lt;tt&gt;test&lt;/tt&gt; named argument &lt;strong&gt;must&lt;/strong&gt; contain following own properties:
&lt;tt&gt;passes&lt;/tt&gt;, &lt;tt&gt;fails&lt;/tt&gt;, &lt;tt&gt;errors&lt;/tt&gt;. &lt;tt&gt;typeof&lt;/tt&gt; of all this properties must
be &lt;tt&gt;number&lt;/tt&gt; and they should represent number of assertions passed,
assertions failed, errors occurred.

&lt;source&gt;var assert = require(&quot;assert&quot;)
  , planned = require('test-addons').planned


exports.testSample = function(test) {
  test(assert.equal, actual, expected, message_opt)
  test(assert.notEqual, actual, expected)
  test(planned, actual, expected, message_opt)
}
&lt;/source&gt;


&lt;strong&gt;Notes:&lt;/strong&gt;

* Future versions of this spec &lt;strong&gt;may&lt;/strong&gt; add additional
properties to the first named argument &lt;tt&gt;test&lt;/tt&gt;.    
* Test functions are backwards compatible and &lt;strong&gt;must&lt;/strong&gt; allow
running tests in mixed (&lt;strong&gt;fail-slow&lt;/strong&gt;, &lt;strong&gt;fail-fast&lt;/strong&gt;) mode.


===Asynchronous Mode===

All the test functions that would like to run tests in
&lt;strong&gt;asynchronous&lt;/strong&gt; mode must expect second named argument. Such test
functions will have special behavior: 

* Asynchronous test functions &lt;strong&gt;must&lt;/strong&gt; be called with a second
argument (for simplicity we'll be referring to it as &lt;tt&gt;done&lt;/tt&gt; named
argument).
* &lt;tt&gt;typeof&lt;/tt&gt; &lt;tt&gt;done&lt;/tt&gt; named argument passed to the asynchronous test
functions must be &lt;tt&gt;&quot;function&quot;&lt;/tt&gt;.
* Test runner &lt;strong&gt;must&lt;/strong&gt; consider asynchronous test being finished
only after calling &lt;tt&gt;done&lt;/tt&gt; named argument.
* All the assertions performed for the test that is finished
(after it called &lt;tt&gt;done&lt;/tt&gt;) &lt;strong&gt;must&lt;/strong&gt; be logged as errors for that
test.
* All the calls to the &lt;tt&gt;done&lt;/tt&gt; function for the test that is
finished (after it called &lt;tt&gt;done&lt;/tt&gt;) &lt;strong&gt;must&lt;/strong&gt; be logged as an errors
for that test.

&lt;source&gt;var assert = require(&quot;assert&quot;)


exports.testAsync = function(test, done) {
  var xhr = new XMLHttpRequest()
  xhr.open('GET', 'http://foo.com/', true)
  xhr.onreadystatechange = function listener(e) {
    if (req.readyState == 4) {
      test(assert.equal, xhr.status, 200)
      test(assert.equal, xhr.responseText, 'bar')
    }
  }
  xhr.send(null)
  // verify results
  setTimeout(function timeout() {
    test(assert.equal, test.passes + test.fails, 2, 'two assertions expected')
    done()
  }, 3000)
}
&lt;/source&gt;</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Nodules</title>
    <id>535</id>
    <revision>
      <id>2906</id>
      <timestamp>2010-09-28T01:26:43Z</timestamp>
      <contributor>
        <username>Kriszyp</username>
        <id>39</id>
      </contributor>
      <comment>Created page with '{{Implementation |name=Nodules |url=http://github.com/kriszyp/nodules |engines=node, narwhal }}'</comment>
      <text xml:space="preserve">{{Implementation
|name=Nodules
|url=http://github.com/kriszyp/nodules
|engines=node, narwhal
}}</text>
    </revision>
  </page>
  <page>
    <title>Implementations/Dasquillette</title>
    <id>538</id>
    <revision>
      <id>2912</id>
      <timestamp>2010-09-30T22:00:38Z</timestamp>
      <contributor>
        <username>Hypernado</username>
        <id>135</id>
      </contributor>
      <comment>Work-in-progress JavaScript platform.</comment>
      <text xml:space="preserve">{{Implementation
|name=Dasquillette
|url=http://dasquillette.hypernado.com/
|engines=JSC
|authors=Hypernado
|description=Work-in-progress open-source, JavaScriptCore-based, CommonJS-complying JavaScript platform. Will eventually implement the entire CommonJS standard. Also will include a full JavaScriptCore Objective-C wrapper.
}}</text>
    </revision>
  </page>
</mediawiki>
