Refactors ezl to use CommonJS.
authordsc <david.schoonover@gmail.com>
Mon, 29 Nov 2010 04:12:48 +0000 (20:12 -0800)
committerdsc <david.schoonover@gmail.com>
Mon, 29 Nov 2010 04:12:48 +0000 (20:12 -0800)
60 files changed:
bin/cjs.py
doc/notes.md
index.php
lib/cjs/deps.js [new file with mode: 0644]
lib/cjs/dummy.js [new file with mode: 0644]
lib/cjs/module.js
lib/jquery.js [new symlink]
src/Y/class.cjs
src/Y/core.cjs
src/Y/index.cjs
src/Y/modules/old-y.event.js [moved from src/Y/modules/event.js with 100% similarity]
src/Y/modules/y.cookies.cjs [moved from src/Y/modules/y.cookies.js with 86% similarity]
src/Y/modules/y.event.cjs [moved from src/Y/modules/y.event.js with 94% similarity]
src/Y/modules/y.json.cjs [moved from src/Y/modules/y.json.js with 62% similarity]
src/Y/modules/y.kv.cjs [moved from src/Y/modules/y.kv.js with 88% similarity]
src/Y/op.cjs
src/Y/types/array.cjs
src/Y/types/collection.cjs
src/Y/types/function.cjs
src/Y/types/number.cjs
src/Y/types/object.cjs
src/Y/types/string.cjs
src/Y/utils.cjs [new file with mode: 0644]
src/Y/y.cjs
src/evt/evt.class.js
src/ezl/index.cjs [new file with mode: 0644]
src/ezl/layer.cjs [moved from src/ezl/layer.js with 96% similarity]
src/ezl/loc/boundingbox.cjs [new file with mode: 0644]
src/ezl/loc/index.cjs [new file with mode: 0644]
src/ezl/loc/loc.cjs [new file with mode: 0644]
src/ezl/loc/square.cjs [new file with mode: 0644]
src/ezl/loop/cooldown.cjs [moved from src/ezl/loop/cooldown.js with 92% similarity]
src/ezl/loop/eventloop.cjs [moved from src/ezl/loop/eventloop.js with 87% similarity]
src/ezl/loop/fps.cjs [moved from src/ezl/loop/fps.js with 92% similarity]
src/ezl/loop/index.cjs [new file with mode: 0644]
src/ezl/math/index.cjs [new file with mode: 0644]
src/ezl/math/line.cjs [moved from src/ezl/math/line.js with 70% similarity]
src/ezl/math/math.js [deleted file]
src/ezl/math/rect.cjs
src/ezl/math/vec.cjs [moved from src/ezl/math/vec.js with 78% similarity]
src/ezl/shape/circle.cjs [moved from src/ezl/shape/circle.js with 92% similarity]
src/ezl/shape/index.cjs [new file with mode: 0644]
src/ezl/shape/line.cjs [moved from src/ezl/shape/line.js with 98% similarity]
src/ezl/shape/polygon.cjs [moved from src/ezl/shape/polygon.js with 74% similarity]
src/ezl/shape/rect.cjs [moved from src/ezl/shape/rect.js with 74% similarity]
src/ezl/shape/shape.cjs [moved from src/ezl/shape/shape.js with 93% similarity]
src/ezl/util/astar.cjs [new file with mode: 0644]
src/ezl/util/astar.js [deleted file]
src/ezl/util/binaryheap.cjs [moved from src/ezl/util/binaryheap.js with 98% similarity]
src/ezl/util/graph.cjs [moved from src/ezl/util/graph.js with 76% similarity]
src/ezl/util/tree/pointquadtree.cjs [moved from src/ezl/util/tree/pointquadtree.js with 100% similarity]
src/ezl/util/tree/quadtree.cjs [moved from src/ezl/util/tree/quadtree.js with 97% similarity]
src/ezl/util/tree/rbtree.cjs [moved from src/ezl/util/tree/rbtree.js with 98% similarity]
src/tanks/map/level.cjs
src/tanks/map/loc/bbox.cjs [deleted file]
src/tanks/map/loc/index.cjs [deleted file]
src/tanks/map/loc/loc.cjs [deleted file]
src/tanks/map/loc/rect.cjs [deleted file]
src/tanks/ui/grid.cjs
tanks.php

index 250e42d..dbdbc72 100755 (executable)
@@ -7,7 +7,7 @@ __version__   = (0, 0, 1)
 __all__ = ('ResolutionError', 'Module', 'JSResolver',)
 
 
-import sys, re
+import sys, re, json
 from itertools import chain, repeat
 from collections import defaultdict
 from subprocess import Popen, check_output, STDOUT, PIPE
@@ -18,21 +18,30 @@ from path import path
 import pystache
 
 
+AT_REQUIRE_PAT   = re.compile(r'//@require\(\s*([\'"])(.*?)\1\s*\)')
 LINE_COMMENT_PAT = re.compile(r'(.*?)(//.*?)(?:\n|$)')
 PAIR_COMMENT_PAT = re.compile(r'(.*?)(/\*.*?\*/)')
 REQUIRE_PAT      = re.compile(r'\brequire\(\s*([\'"])(.*?)\1\s*\)')
+
 ROOT             = path(__file__).abspath().dirname().dirname()
 LIB              = ROOT/'lib/cjs'
 CWD              = path('.')
 BLANK            = path('')
+
 MODULE_TEMPLATE  = ''
+DUMMY_TEMPLATE   = ''
+DEPS_TEMPLATE    = ''
 
 try:
-    with (LIB/'module.js').open('rU') as f : 
+    with (LIB/'module.js').open('rU') as f:
         MODULE_TEMPLATE = f.read()
+    with (LIB/'dummy.js').open('rU') as f:
+        DUMMY_TEMPLATE = f.read()
+    with (LIB/'deps.js').open('rU') as f:
+        DEPS_TEMPLATE = f.read()
 except Exception as ex:
     print
-    print 'Error reading module template file!'
+    print 'Error reading template file!'
     print '  ROOT={ROOT}, LIB={LIB}, module.js={}'.format(LIB/'module.js', **locals())
     raise
 
@@ -86,55 +95,41 @@ def canonicalise(query, base=None):
     return str(id)
 
 
-class Repo(object):
-    def __init__(self, filepath, url):
-        self.path = filepath
-        self.url  = url
-    
-    def __repr__(self):
-        return 'Repo({}, url={})'.format(self.path, self.url)
-    
-    def __str__(self):
-        return repr(self)
-
-
 
 class Module(Bunch):
     DEFAULTS = {
-        'id'        : '',   # Canonical Module ID
-        'file'      : None, # path
-        'name'      : '',   # Module Name
-        'uri'       : '',   # Module URI (TODO)
-        'text'      : None, # Unmodified module text
-        'contents'  : None, # Compiled module text
-        '_requires' : None,
-        'outpath'   : None,
+        'id'           : '',   # Canonical Module ID
+        'file'         : None, # path
+        'name'         : '',   # Module Name
+        'uri'          : '',   # Module URI (TODO)
+        'text'         : None, # Unmodified module text
+        'contents'     : None, # Compiled module text
+        'outpath'      : None, # Build directory
+        '_requires'    : None,
+        '_at_requires' : None,
     }
     
     
-    def __init__(self, id, file, uri='', out=None, compile=True):
+    def __init__(self, id, file, uri=BLANK, out=None, compile=True):
         self.update(Module.DEFAULTS)
         
         self.id   = id
         self.file = path(file)
-        self.name = self.id.split('/').pop().capitalize()
+        self.name = re.subn(r'\W', '', self.id.split('/').pop().capitalize())[0]
         
         if out:
-            out = (path(out) / self.id) + '.js'
+            out = path(out)
+            outpath = (out / self.id) + '.js'
         else:
-            out = self.file.replace('.cjs', '.js')
-        self.outpath = path(out)
-        self.uri = uri
+            out = BLANK
+            outpath = self.file.replace('.cjs', '.js')
+        self.outpath = path(outpath)
+        self.uri = str(out/uri/self.id)+'.js'
         
-        if compile: self.compile()
+        self.compile()
         # print "new!", repr(self)
     
     def compile(self):
-        # if uri: self.uri = uri.format(**self) # TODO: calc uri
-        
-        if not self.file.endswith('.cjs'):
-            return self
-        
         outdir = self.outpath.dirname()
         if not outdir.exists():
             outdir.makedirs()
@@ -149,7 +144,8 @@ class Module(Bunch):
             with self.file.open('rU') as f:
                 txt = f.read()
             self['text'] = txt
-            self['contents'] = pystache.render(MODULE_TEMPLATE, self)
+            template = MODULE_TEMPLATE if self.file.endswith('.cjs') else DUMMY_TEMPLATE
+            self['contents'] = pystache.render(template,  self)
         return self[attr]
     
     @property
@@ -160,6 +156,10 @@ class Module(Bunch):
     def contents(self):
         return self.read('contents')
     
+    def findDirectives(self, text):
+        for areq in AT_REQUIRE_PAT.finditer(text):
+            yield canonicalise(areq.group(2), self)
+    
     def findRequires(self, text):
         text = LINE_COMMENT_PAT.subn(r'\1 ', text)[0]
         text = PAIR_COMMENT_PAT.subn(r'\1 ', text)[0]
@@ -167,11 +167,23 @@ class Module(Bunch):
         for mreq in REQUIRE_PAT.finditer(text):
             yield canonicalise(mreq.group(2), self)
     
+    def calcRequires(self, attr):
+        if self._requires is None or self._at_requires is None:
+            self._at_requires = list(self.findDirectives(self.text))
+            self._requires    = list(self.findRequires(self.text))
+        return getattr(self, attr)
+    
+    @property
+    def atRequires(self):
+        return self.calcRequires('_at_requires')
+    
+    @property
+    def nonAtRequires(self):
+        return self.calcRequires('_requires')
+    
     @property
     def requires(self):
-        if self._requires is None:
-            self._requires = list(self.findRequires(self.text))
-        return self._requires
+        return self.calcRequires('_at_requires') + self._requires
     
     def __hash__(self):
         return hash(self.id)
@@ -209,22 +221,30 @@ class CommonJS(object):
                 req = cjs.lookup(query, mod)
                 if req not in seen:
                     queue.append(req)
+        if cjs.deps_name:
+            cjs.genDepLoader()
         return cjs
     
     
     repos   = []
     modules = {} # id -> Module
-    _graph  = None # id -> set(dependants)
-    
-    
-    def __init__(self, repos, out='build', clean=True):
-        self.modules = {}
-        self.repos   = set( path(path(p).abspath()+'/') for p in repos)
-        self.out = None if out is '' else out
+    _graph    = None # id -> set(dependants)
+    _at_graph = None # id -> set(dependants)
+    
+    def __init__(self, repos, out='build', deps_name=None, clean=True, **options):
+        self.modules  = {}
+        self.options  = options
+        self.deps_name = deps_name
+        self.repos    = set( path(path(p).abspath()+'/') for p in repos)
+        self.out      = None if out is '' else out
         
         if self.out is not None and clean:
             out = path(self.out)
-            if out.exists(): out.rmtree()
+            for f in out.glob('*'):
+                if f.isdir():
+                    f.rmtree()
+                elif f.isfile():
+                    f.remove()
     
     def register(self, id, file):
         mod = self.modules[id] = Module(id=id, file=file, out=self.out)
@@ -254,32 +274,67 @@ class CommonJS(object):
         for k, mod in self.modules.iteritems():
             yield k, mod
     
-    @property
-    def graph(self):
+    def calcGraph(self, attr):
         if self._graph is None:
-            graph = self._graph = defaultdict(set)
+            graph   = self._graph    = defaultdict(set)
+            atgraph = self._at_graph = defaultdict(set)
             for mod in self.modules.values():
-                for req in mod.requires:
+                for req in mod.nonAtRequires:
                     graph[req].add(mod)
-        return self._graph
+                for req in mod.atRequires:
+                    atgraph[req].add(mod)
+        return getattr(self, attr)
     
     @property
-    def deplist(self):
-        return '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in self.graph.iteritems() for dep in deps )
+    def graph(self):
+        return self.calcGraph('_graph')
     
     @property
-    def dependencies(self):
+    def atGraph(self):
+        return self.calcGraph('_at_graph')
+    
+    def tsort(self, graph):
         p = Popen(['tsort'], stderr=STDOUT, stdin=PIPE, stdout=PIPE)
-        p.stdin.write( self.deplist )
+        deps = '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in graph.iteritems() for dep in deps )
+        p.stdin.write(deps)
         p.stdin.close()
         if p.wait() != 0:
             raise ResolutionError('Cannot resolve dependencies! Requirements must be acyclic!')
-        return p.stdout.read().strip().split('\n')
+        return p.stdout.read()
+    
+    @property
+    def dependencies(self):
+        deps = (self.tsort(self.atGraph)+self.tsort(self.graph)).strip().split('\n')
+        for i, dep in reversed(list(enumerate(deps[:]))):
+            try:
+                idx = deps.index(dep, 0, i-1)
+                if i != idx:
+                    del deps[idx]
+            except ValueError: pass
+        return deps
+    
+    def dumpDependencies(self):
+        column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
+        mods = self.modules.values()
+        for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
+            column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
+            # print '%s\t->\t%r' % (mod, sorted(mod.requires))
+        column.stdin.close()
+        if column.wait() != 0:
+            print >> sys.stderr, 'Some sort of error has occurred!'
+        return column.stdout.read()
     
-    def cat(self):
-        for dep in self.dependencies:
-            print self.modules[dep].contents
+    def genDepLoader(self):
+        with (path(self.out)/self.deps_name).open('w') as deps:
+            deps.write( pystache.render(DEPS_TEMPLATE, uris=json.dumps(self.uris)) )
     
+    @property
+    def uris(self):
+        return [ self.modules[d].uri for d in self.dependencies ]
+    
+    @property
+    def scriptTags(self):
+        return '\n'.join( '<script src="{}" type="text/javascript"></script>'.format(uri) for uri in self.uris )
 
 
 
@@ -292,15 +347,19 @@ def main():
         usage   = 'usage: %prog [options] file[...] [-- [repo_path[...]]]',
         description = 'Compiles CommonJS modules.',
         version = '%prog'+" %i.%i.%i" % __version__)
-    parser.add_option("-p", "--repo-paths", dest='repos', default='',
+    parser.add_option("-p", "--repo-paths", default='',
         help="Comma-seperated paths to search for unqualified modules. "
              "If a path contains :, the portion afterward will be taken as the repo URL. [default: .]")
     parser.add_option("-o", "--out", default='build',
         help="Root directory to write compiled JS files. Specify '' to write to module's dir. [default: build]")
     parser.add_option("-C", "--no-clean", dest='clean', default=True, action="store_false",
         help="Do not clean the out-dir of compiled files. [default: False if -o, True otherwise]")
-    parser.add_option("-d", "--print-deps", default=False, action="store_true", 
+    parser.add_option("--print-deps", default=False, action="store_true", 
         help="Prints module dependencies after compiling. [default: %default]")
+    parser.add_option("-g", "--gen-deps-script", dest='deps_name', default=None,
+        help="Generates a JS script with the given name which doc-writes tags for this set of modules.")
+    parser.add_option("-s", "--script-tags", default=False, action="store_true",
+        help="Emits script-tags for this set of modules in dependency order. [default: %default]")
     
     (options, args) = parser.parse_args()
     
@@ -310,21 +369,24 @@ def main():
     (files, sep, repos) = partition(sys.argv, '--')
     files = filter(lambda f: f in args, files)
     repos = filter(lambda f: f in args, repos)
-    repos.extend( filter(None, options.repos.split(',')) )
+    repos.extend( filter(None, options.repo_paths.split(',')) )
     
     # print 'files:', files, 'repos:', (repos or ['.'])
-    js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+    try:
+        js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+    except ResolutionError as ex:
+        print >> sys.stderr, str(ex)
+        return 1
+    
+    if options.script_tags:
+        print js.scriptTags
     
     if options.print_deps:
-        column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
-        mods = js.modules.values()
-        for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
-            column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
-            # print '%s\t->\t%r' % (mod, sorted(mod.requires))
-        
-        column.stdin.close()
-        if column.wait() != 0: print 'Some sort of error has occurred!'
-        print column.stdout.read()
+        print >> sys.stderr, 'All Dependencies:'
+        print >> sys.stderr, js.dumpDependencies()
+        print >> sys.stderr, ''
+        print >> sys.stderr, 'Resolution:'
+        print >> sys.stderr, '\n'.join(js.dependencies)
     
     return 0
 
index 3285ae5..38cd78e 100644 (file)
@@ -2,9 +2,8 @@
 - Tanks seem to get stuck on some corners
 
 # TODOs
-- How-to overlay
-- Restart level button
-- AI: Line-of-sight for dodging, firing
+- change @require to @ensure
+
 - AI: Don't shoot if it'll kill you or your friends
 - AI: Lead shots on moving targets
 - Config-driven unit-types (name, stats, properties; pointers to behavior scripts, assets)
index afcb361..3ac3f78 100644 (file)
--- a/index.php
+++ b/index.php
 </div></div>
 
 <div id="scripts">
-<?php require "tanks.php"; Tanks::writeTags( Tanks::ALL_SCRIPTS ); ?>
+<?php
+    /* require "tanks.php"; Tanks::writeTags( Tanks::ALL_SCRIPTS ); */
+    require "tanks.php"; Tanks::writeLoaders();
+?>
 </div>
 
 </body>
diff --git a/lib/cjs/deps.js b/lib/cjs/deps.js
new file mode 100644 (file)
index 0000000..3735e59
--- /dev/null
@@ -0,0 +1,3 @@
+{{{uris}}}.forEach(function(uri){
+    document.write('<scr'+'ipt src="'+uri+'" type="text/javascript"></scr'+'ipt>');
+});
diff --git a/lib/cjs/dummy.js b/lib/cjs/dummy.js
new file mode 100644 (file)
index 0000000..71c5a6b
--- /dev/null
@@ -0,0 +1,14 @@
+require.install(
+// Module ID
+'{{{id}}}',
+
+// Module metadata
+{
+    'name'  : '{{{name}}}',
+    'id'    : '{{{id}}}',
+    'uri'   : '{{{uri}}}'
+},
+// Dummy module: setup does nothing
+function setup{{{name}}}(require, exports, module){});
+
+{{{text}}}
index 7f225e1..167f51a 100644 (file)
@@ -1,17 +1,17 @@
 require.install(
 // Module ID
-'{{id}}',
+'{{{id}}}',
 
 // Module metadata
 {
-    'name'  : '{{name}}',
-    'id'    : '{{id}}',
-    'uri'   : '{{uri}}'
+    'name'  : '{{{name}}}',
+    'id'    : '{{{id}}}',
+    'uri'   : '{{{uri}}}'
 },
 
 // Module Setup function
-function setup{{name}}(require, exports, module){
+function setup{{{name}}}(require, exports, module){
 
-{{text}}
+{{{text}}}
 
 });
\ No newline at end of file
diff --git a/lib/jquery.js b/lib/jquery.js
new file mode 120000 (symlink)
index 0000000..0185856
--- /dev/null
@@ -0,0 +1 @@
+jquery-1.4.3.min.js
\ No newline at end of file
index 9ca59ab..dc1a4b5 100644 (file)
@@ -1,7 +1,10 @@
 // Inspired by John Resig's "Simple Class Inheritence" -- http://ejohn.org/blog/simple-javascript-inheritance/
 
-var Y = require('Y').Y
-,   type = require('Y/type')
+var type      = require('Y/type')
+,   YFunction = require('Y/types/function').YFunction
+,   core      = require('Y/core')
+,   slice     = core.slice
+
 ,   KNOWN_CLASSES = type.type.KNOWN_CLASSES
 ,   classToString = function toString(){ return this.className+"()"; }
 ;
@@ -113,7 +116,7 @@ function Class(className, Parent, members) {
             prototype[k] = members[k];
     }
     
-    if (prototype.init) NewClass.init = Y(prototype.init);
+    if (prototype.init) NewClass.init = YFunction(prototype.init);
     
     KNOWN_CLASSES[className] = NewClass;
     
@@ -171,59 +174,9 @@ var YBase = new Class("YBase", {
 
 
 
-
-/// Other Class Utilities ///
-
-function bindName(v, k){
-    if ( isFunction(v) )
-        this[k] = Y(v).bind(this);
-}
-// bindName = Y(bindName).curry();
-
-function bindAll(o, names){
-    var names = new Y(arguments, 1);
-    Y(names.size() ? names.generate(Y.op.get(o)) : o).forEach( bindName, o );
-    return o;
-}
-
-// Y.chainDelegates = chainDelegates;
-function chainDelegates(type, name){
-    var names = Y(arguments, 1),
-        proto = type.prototype;
-    names.forEach(function(name){
-        proto[name] = function(){
-            var o = this._o || this;
-            o[name].apply(o, Y(arguments));
-            return this;
-        };
-    });
-    return type;
-}
-
-// Y.mixinNames = mixinNames;
-function mixinNames(o, Donor, names, override, yWrap){
-    var target = ( isFunction(o)     ? o.prototype     : o)
-    ,   proto  = ( isFunction(Donor) ? Donor.prototype : Donor);
-    
-    // Need a closure to capture the name
-    names.forEach(function(name){
-        if ( isFunction(proto[name]) && (override || !target[name]) )
-            target[name] = function(){
-                var r = proto[name].apply(this._o || target, arguments);
-                return (yWrap ? Y(r) : r);
-            };
-    });
-    
-    return o;
-}
-
 exports['Class'] =
 exports['subclass']    = Class;
 exports['instantiate'] = Class.instantiate.bind(Class);
 exports['fabricate']   = Class.fabricate.bind(Class);
-
-exports['YBase']          = YBase;
-exports['bindAll']        = bindAll;
-exports['chainDelegates'] = chainDelegates;
-exports['mixinNames']     = mixinNames;
+exports['YBase']       = YBase;
 
index 83f1594..0725a30 100644 (file)
@@ -1,4 +1,15 @@
 // Generic Collection Functions
+var undefined
+,   globals   = (function(){ return this; })()
+,   _Function = globals.Function
+,   _Array    = globals.Array
+,   PT = "prototype"
+,   slice = _Array[PT].slice
+;
+
+// function slice(a){
+//     return _asl.apply(a, _asl.call(arguments, 1));
+// }
 
 function notWrapped(fn){
     var self = arguments.callee.caller;
@@ -9,7 +20,7 @@ function reduce(o, fn, acc){
     if ( !o )
         return acc;
     
-    fn = Function.toFunction(fn);
+    fn = _Function.toFunction(fn);
     var cxt = arguments[3] || o;
     if ( notWrapped(o.reduce) )
         return o.reduce.apply(o, [fn, acc, cxt]);
@@ -24,7 +35,7 @@ function map(o, fn){
     if ( !o )
         return o;
     
-    fn = Function.toFunction(fn);
+    fn = _Function.toFunction(fn);
     var acc = {}, cxt = arguments[2] || o;
     if ( notWrapped(o.map) )
         return o.map.apply(o, [fn, cxt]);
@@ -44,7 +55,7 @@ function filter(o, fn){
     if ( !o )
         return o;
     
-    fn = Function.toFunction(fn);
+    fn = _Function.toFunction(fn);
     var acc = {}, cxt = arguments[2] || o;
     if ( notWrapped(o.filter) )
         return o.filter.apply(o, [fn, cxt]);
@@ -116,3 +127,4 @@ exports['extend']  = extend;
 exports['dset']    = dset;
 exports['dattr']   = dattr;
 exports['dextend'] = dextend;
+exports['slice']   = slice;
\ No newline at end of file
index bc8097e..cdfd44e 100644 (file)
@@ -1,7 +1,8 @@
+//  -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
 
 /// Import our external deps first ///
-// require('lessly/future');
-// require('functional/to-function');
+//@require('lessly/future');
+//@require('functional/to-function');
 
 /// Set up core and utilities ///
 var core = require('Y/core')
@@ -17,6 +18,7 @@ core.extend(type.type, type);
 
 // Attach core & type to Y
 core.extend(Y, core, type);
+delete Y.slice; // grr
 
 // Make top-level setters refer to the delegating versions
 Y['core']   = core;
@@ -41,7 +43,7 @@ addNames('curry methodize genericize compose chain memoize', yfn);
 // Curry all operators
 var op = require('Y/op');
 core.forEach(op, YFunction);
-Y['op'] = op.extend({}, core.map(yfn.curry, op));
+Y['op'] = op['curried'] = op.extend({}, core.map(yfn.curry, op));
 // Y['op'] = core.reduce(op, function(Yop, fn, k){
 //     Yop[k] = yfn.curry(fn);
 //     return Yop;
similarity index 86%
rename from src/Y/modules/y.cookies.js
rename to src/Y/modules/y.cookies.cjs
index 2342220..b3aedac 100644 (file)
@@ -1,12 +1,12 @@
-(function(Y, undefined){ if (!Y) return;
-
 var _document = document
+,   Y   = require('Y').Y
 ,   enc = encodeURIComponent
 ,   dec = decodeURIComponent
-,   ns  = Y.cookies = {}
 ;
 
-ns.get =
+Y['cookies'] = exports;
+
+exports['get'] =
     function getCookie(k){
         var cookies = Y(_document.cookie+'').fromKV('; ');
         if (k !== undefined)
@@ -15,7 +15,7 @@ ns.get =
             return cookies;
     };
 
-ns.set = 
+exports['set'] = 
     function setCookie(k, v, expires, path){
         expires = 'expires='+(expires || "Sun, 24-Mar-2024 11:11:11 GMT");
         path = 'path='+(path || "/");
@@ -24,5 +24,3 @@ ns.set =
     };
 
 // TODO: YCollection methods on ns over kv pairs.
-
-})(this.Y);
similarity index 94%
rename from src/Y/modules/y.event.js
rename to src/Y/modules/y.event.cjs
index d3d0be5..577aa02 100644 (file)
@@ -1,7 +1,4 @@
-(function(Y, undefined){
-
-var 
-ns = Y.event = {}
+Y['event'] = exports;
 
 /**
  * A simple event.
@@ -9,7 +6,7 @@ ns = Y.event = {}
  * TODO: If DOM event, wrap with consistent API.
  * TODO: use jQuery if present to wrap events.
  */
-, YEvent = ns.YEvent = 
+var YEvent = exports['YEvent'] = 
 Y.YObject.subclass('YEvent', {
     init : function init( type, target, trigger, data ){
         data = data || {};
@@ -69,9 +66,9 @@ Y.YObject.subclass('YEvent', {
             delegate[k] = methods[k].bind(this);
         return delegate;
     }
-}
+},
 
-, Emitter = ns.Emitter =
+Emitter = exports['Emitter'] =
 Y.YObject.subclass('Emitter', 
     Y.extend({
         'init' : function(target, parent){
@@ -90,7 +87,4 @@ Emitter.methods = methods;
 
 // Global Event Hub
 Emitter.global = new Emitter()
-Emitter.global.decorate(Y.event);
-
-
-})(this.Y);
+Emitter.global.decorate(exports);
similarity index 62%
rename from src/Y/modules/y.json.js
rename to src/Y/modules/y.json.cjs
index ec4cde6..5d7f673 100644 (file)
@@ -1,4 +1,4 @@
-(function(Y){
+var Y = require('Y').Y;
 
 function toJSON(o, k){
     var prefix = typeof(k) === 'string' ? '"'+k+'":' : '',
@@ -7,9 +7,8 @@ function toJSON(o, k){
 }
 
 function install(json_fn){
-    var args = new Y(arguments),
-        tojson = args.shift();
-    args.each(function(YThing){
+    var args = Y(arguments,1);
+    args.forEach(function(YThing){
         YThing.prototype.toJSON = json_fn;
     });
 }
@@ -29,7 +28,7 @@ function quoteJSON(){
 // Collections
 
 function reducer(acc, v, k, o){
-    var json = toJSON(v, Y.is.array(o) ? 0 : k);
+    var json = toJSON(v, Y.isArray(o) ? 0 : k);
     return json ? (acc ? acc+','+json : json) : acc;
 }
 
@@ -40,13 +39,12 @@ var collectJSON = Y(function(a, z){
 
 // Public API
 
-Y.toJSON = toJSON;
+Y['toJSON'] = exports['toJSON'] = toJSON;
 
-install( yNoJSON, Y.YGeneric, Y.YFunction, Y.YRegExp );
-install( yToJSON, Y, Y.YBoolean, Y.YNumber );
+// install( yNoJSON, Y.YBase, Y.YFunction, Y.YRegExp );
+// install( yToJSON, Y, Y.YBoolean, Y.YNumber );
+install( yNoJSON, Y.YBase, Y.YFunction );
+install( yToJSON, Y, Y.YNumber );
 install( quoteJSON, Y.YString );
-install( collectJSON.partial('{', '}'), Y.YCollection );
+install( collectJSON.partial('{', '}'), Y.YCollection, Y.YObject );
 install( collectJSON.partial('[', ']'), Y.YArray );
-
-
-})(this.Y);
similarity index 88%
rename from src/Y/modules/y.kv.js
rename to src/Y/modules/y.kv.cjs
index f6c2c82..a05be23 100644 (file)
@@ -1,6 +1,5 @@
-(function(Y, undefined){ if (!Y) return;
-
-var enc = encodeURIComponent
+var Y   = require('Y').Y
+,   enc = encodeURIComponent
 ,   dec = decodeURIComponent
 ;
 
@@ -25,4 +24,3 @@ Y.YString.prototype.fromKV =
             }, {});
     };
 
-})(this.Y);
index 97ef023..e621efa 100644 (file)
@@ -1,7 +1,7 @@
 /* A subset of the functional operators, used in Y's core */
 
-var Y    = require('Y').Y
-,   core = require('Y/core')
+var core = require('Y/core')
+,   slice = core.slice
 ,   op = { // XXX: Make these function statements?
     
     // comparison
@@ -41,6 +41,7 @@ var Y    = require('Y').Y
     nop:    function(x){},
     I:      function(x){       return x; },
     K:      function(k){       return function(){ return k; }; },
+    nth:    function(n){       return function(){ return arguments[n]; }; },
     val:    function(def,o){   return o !== undefined ? o : def; },
     ok:     function(o){       return o !== undefined && o !== null; },
     
@@ -57,10 +58,10 @@ var Y    = require('Y').Y
     set:     core.set,  // set(  o, key, value, def )
     attr:    core.attr, // attr( o, key, value, def )
     method: function(name){
-        var args = Y(arguments,1);
+        var args = slice.call(arguments,1);
         return function(obj){
             if (obj && obj[name])
-                return obj[name].apply( obj, args.concat(Y(arguments)) );
+                return obj[name].apply( obj, args.concat(slice.call(arguments)) );
             else
                 return obj;
         };
index 18b50e3..c1f568b 100644 (file)
@@ -1,35 +1,35 @@
-var Y = require('Y').Y;
+var YCollection = require('Y/types/collection').YCollection
+,   mixin = require('Y/utils').mixin
+,   slice = require('Y/core').slice
+;
 
 exports['YArray'] =
-Y.YCollection.subclass('YArray', function(YArray){
-    var yclass = require('Y/class');
+YCollection.subclass('YArray', function(YArray){
     
-    yclass.chainDelegates(YArray, 'push', 'unshift', 'sort', 'splice', 'reverse');
-    yclass.mixinNames(YArray, Array, ['reduce', 'map', 'forEach', 'filter', 'slice', 'some', 'every'],    true, true);
-    yclass.mixinNames(YArray, Array, ['indexOf', 'lastIndexOf', 'shift', 'pop', 'join'], true, false);
+    mixin(YArray, { donor:Array, chain:true,
+        names:'push unshift sort splice reverse'.split(' ') });
+    mixin(YArray, { donor:Array, wrap:YArray,
+        names:'map forEach filter slice'.split(' ') });
+    mixin(YArray, { donor:Array,
+        names:'reduce some every indexOf lastIndexOf shift pop join'.split(' ') });
     
     
-    
-    
-    this.init = function(o){
-        // YCollection.init.call(this, o || []);
+    this.init = function initYArray(o){
         this._o = o || [];
     };
     
     this.merge  =
     this.concat =
     function concat( donor ){
-        var A = this._o;
-        new Y(arguments).forEach(function( donor ){
-            A = A.concat(donor instanceof YArray ? donor.end() : donor);
-        });
-        return Y(A);
+        return new YArray( slice.call(arguments).reduce(function(A, donor ){
+            return A.concat(donor instanceof YArray ? donor.end() : donor);
+        }, this._o) );
     };
     
     this.remove =
     function remove(v){
         if (arguments.length > 1)
-            Y(arguments).forEach(this.remove, this);
+            slice.call(arguments).forEach(this.remove, this);
         else {
             var idx = this.indexOf(v);
             if ( idx != -1 )
@@ -62,12 +62,20 @@ Y.YCollection.subclass('YArray', function(YArray){
         // });
     };
     
+    // this.zip =
+    // function zip(){
+    //     var sequences = new YArray(slice.call(arguments)).map( Y.limit(1) ).unshift(this);
+    //     return this.map(function(_, k){
+    //         return sequences.invoke('attr', k);
+    //     }).invoke('end');
+    // };
+    
     // Like map, but produces a dict
     // Y(["Foo?", "R&D"]).generate(encodeURIComponent)
     //  -> Y({"Foo?":"Foo%3F", "R&D":"R%26D"})
     this.generate =
     function generate(fn, acc){
-        var args = Y(arguments),
+        var args = slice.call(arguments),
             fn = args.shift(),
             acc = args.shift();
         return this.reduce(function(acc, v, i){
@@ -84,7 +92,7 @@ Y.YCollection.subclass('YArray', function(YArray){
     
     this.clone =
     function clone(){
-        return Y(this._o.slice(0));
+        return new YArray(this._o.slice(0));
     };
     
     this.size =
index 669f942..56eb0b9 100644 (file)
@@ -1,25 +1,29 @@
 /** YCollection is the core of Y. */
 
-var Y = require('Y').Y
+var YBase      = require('Y/class').YBase
 ,   isFunction = require('Y/type').isFunction
-,   extend     = require('Y/core').extend
-,   bool       = require('Y/op').bool
+,   core       = require('Y/core')
+,   op         = require('Y/op')
+,   slice      = core.slice
+,   extend     = core.extend
+,   attr       = core.attr
+,   bool       = op.bool
 ;
 
 
 function extendY(){
-    extend.apply(this, [this._o].concat(Y(arguments)));
+    extend.apply(this, [this._o].concat(slice.call(arguments)));
     return this;
 }
 
 exports['YCollection'] =
-Y.YBase.subclass('YCollection', {
+YBase.subclass('YCollection', {
     'init' : function(o){
         this._o = o || {};
     },
     
     'attr'   : function attr(k, v, def){
-        var r = Y.attr(this._o, k, v, def);
+        var r = attr(this._o, k, v, def);
         if (r === this._o)
             return this;
         else
@@ -73,19 +77,35 @@ Y.YBase.subclass('YCollection', {
     },
     
     'clone' : function clone(){
-        return Y({}).extend(this);
+        return new this.constructor().extend(this);
     },
     
+    // 'remove' : function remove(v){
+    //     var o = this._o
+    //     ,   toRemove = new Y(arguments);
+    //     
+    //     for (var k in o) {
+    //         var v = o[k];
+    //         if ( toRemove.has(v) ) {
+    //             delete o[k];
+    //             toRemove.remove(v);
+    //         }
+    //     }
+    //     return this;
+    // },
+    
     'remove' : function remove(v){
         var o = this._o
-        ,   toRemove = new Y(arguments);
+        ,   toRemove = slice.call(arguments);
         
         for (var k in o) {
-            var v = o[k];
-            if ( toRemove.has(v) ) {
+            var v = o[k], idx = toRemove.indexOf(v);
+            if ( idx !== -1 ) {
                 delete o[k];
-                toRemove.remove(v);
+                toRemove.splice(idx,1);
             }
+            if (!toRemove.length)
+                break;
         }
         return this;
     },
@@ -105,10 +125,11 @@ Y.YBase.subclass('YCollection', {
     },
     
     'zip' : function zip(){
-        var sequences = new Y(arguments).map( Y.limit(1) ).unshift(this);
+        var sequences = slice.call(arguments);
+        sequences.unshift(this);
         return this.map(function(_, k){
-            return sequences.invoke('attr', k);
-        }).invoke('end');
+            return sequences.map(op.curried.kget(k));
+        });
     },
     
     'pluck' : function pluck(key){
@@ -118,9 +139,8 @@ Y.YBase.subclass('YCollection', {
     },
     
     'invoke' : function invoke(name){
-        var args = Y(arguments),
-            name = args.shift();
-        return this.map(function(o){
+        var args = slice.call(arguments,1);
+        return core.map(this, function(o){
             return o && o[name].apply(o, args);
         });
     },
index f354cb3..88e81ba 100644 (file)
@@ -2,14 +2,11 @@ var undefined
 ,   WRAPS   = "__wraps__"
 ,   globals = (function(){ r