0.2.7 • Published 12 years ago

meta-objects v0.2.7

Weekly downloads
79
License
-
Repository
github
Last release
12 years ago

meta-objects

This repo is in flux now due to the new revision of the Proxy API approved at the end of november. Direct Proxies make most of the work previously in this repo very easy to do. The API is much easier to work with.

Basic Usage

At first only one function is exposed. This function bootstraps a few shims onto the context without which the rest wouldn't work. This function will return the actual module once you run it.

var meta = require('meta-objects')();

Direct Proxy Shim for both Node and Spidermonkey/Firefox

Thanks to the hard work of @tvcutsem in both producing the API to begin with along with a shim to provide the functionality on top of existing Proxy functionality, we can start working with the API before browsers implement it. I've created a minimal wrapper around it for use as a node module. All of the work going forward will be based on this API rather than the old one. For now I'm just copying over the README that I created for that repo until I have more substantial additions.

I've also made some tenative changes that go against the new API but mostly in order to shim in behavior similar to what will eventually be done natively. There's also a couple questionable changes made to do things like allow configurable names on Functions, allow nearly genuine Array proxies, and a few other questionable things.

https://github.com/Benvie/Direct-Proxies-Shim-for-Node

Betond that it's also currently using WeakMaps and Maps. Maps are implemented in the latest versions of V8 but I don't think are available in Spidermonkey yet. Maps are very similar to WeakMaps but allow for primitive keys so are useful when combined with WeakMaps for storing sets of unknown properties.

I have implemented what's available for the Harmony Collections API and then some extra as a shim that works in any JS environment. Alternatively, uses of Map can probably be replaced with WeakMaps in most cases if you additional checking on the inputs.

https://github.com/Benvie/ES6-Harmony-Collections-Shim

Current Exposed Feature Set

Documentation for this will a lot of time. Many of these are simple functions, but the Proxy based APIs have a lot of depth to them

{ Dispatcher: [Function: Dispatcher],
  Trace:
  { tracer: [Function: tracer],
    traceDispatcher: [Function: traceDispatcher] },
  Partials: { [Function: FactoryFactory] ___: ___, $$$: $$$ },
  Function:
  { [Function: create],
    callbind: [Function],
    applybind: [Function],
    callapplybind: [Function: callapplybind],
    bindcallapply: [Function: bindcallapply],
    partial: [Function: partialbind],
    source: [Function],
    params: [Function: params],
    noop: [Function: noop],
    noopmap: [Function: noopmap] },
  Array:
  { [Function: create],
    argjoin: [Function: argjoin],
    clone: [Function: clone],
    pushall: [Function: pushall],
    reverse: [Function],
    slice: [Function: slice],
    unique: [Function: unique],
    unzip: [Function: unzip],
    zip: [Function: zip],
    zipwith: [Function: zipwith] },
  Object:
  { [Function: create],
    class: [Function: class],
    clone: [Function: clone],
    define: [Function: define],
    defines: [Function: defines],
    desc: [Function: desc],
    descs: [Function: descs],
    hasOwn: [Function: hasOwn],
    is: [Function: is],
    isArgs: [Function: isArguments],
    isDescriptor: [Function: isDescriptor],
    isPrimitive: [Function: isPrimitive],
    keys: [Function: keys],
    map: [Function: map],
    names: [Function: names],
    proto: [Function: proto] },
  String:
  { [Function: create],
    explode: [Function: explode],
    implode: [Function: implode],
    indent: [Function],
    repeat: [Function: repeat],
    replace: [Function: replace],
    reverse: [Function: reverse],
    strmap: [Function: strmap],
    trim: [Function: trim] },
  Descriptors: { getter: [Function], val: [Function], pfunc: [Function] },
  Reflectable:
  { getOwnPropertyDescriptor: [Function],
    getOwnPropertyNames: [Function],
    defineProperty: [Function],
    delete: [Function],
    freeze: [Function],
    seal: [Function],
    preventExtensions: [Function],
    has: [Function],
    hasOwn: [Function],
    get: [Function],
    set: [Function],
    enumerate: [Function],
    iterate: [Function],
    keys: [Function],
    apply: [Function],
    new: [Function],
    VirtualHandler: [Function] },
  WrapMap: [Function: WrapMap],
  WeakMapSet: [Function: WeakMapSet] }

Partials - Using meta objects for partial function factories

var metaobjects = require('../lib')();
    var Factory = metaobjects.Partials;



var sliceFactory = Factory(Array.prototype.slice);

sliceFactory.$this = Factory.$$$;
console.log(sliceFactory+'')
/* fake sources generated by the factory for factory.toString()
   The source is not actually run and the actual internal operation
   runs differently than this code, but it achieves the same end result */
//->
      function slice_factory($0){
        return (function slice_partial($1){
          return (function slice(){
          [native code]
          }).call($0 || $1 || this);
        });
      }


var slicepartial = sliceFactory();
console.log(slicepartial([1, 2, 3], 2))
      // [ 3 ]

// `new` create a clone snapshot of the factory but they don't share state after

var factory2 = new sliceFactory

factory2.$this = Factory.$$$;
factory2.$0 = 1;

var partial2 = factory2();
console.log(partial2([1, 2, 3]))
      // [ 2, 3 ]




function someFn(someArgs, itWillRead, andUse){
  if (typeof someArgs === 'function') {
     var val = someArgs(this.someProperty, "whatever");
  }
  return itWillRead() ? val : andUse;
}

var someFnFactory = Factory(someFn);
console.log(someFnFactory)
// ->
      { [Function: someFn_factory]
         someArgs: null,
         itWillRead: null,
         andUse: null }

someFnFactory.someArgs = Array;
someFnFactory.$this = { someProperty: "yeah" };
someFnFactory.itWillRead = Factory.___;
someFnFactory.andUse = Factory.___

console.log(someFnFactory)
//->
      { [Function: someFn_factory]
        someArgs: [Constructor: Array],
        itWillRead: ___,
        andUse: ___ }

console.log(someFnFactory+'')
//->
      function someFn_factory(){
        var someArgs = this.someArgs;
        var $this = this.$this;
        return (function someFn_partial(itWillRead, andUse){
          return (function someFn(someArgs, itWillRead, andUse){
           if (typeof someArgs === 'function') {
              var val = someArgs(this.someProperty, "whatever");
           }
           return itWillRead() ? val : andUse;
          }).call($this, someArgs, itWillRead, andUse);
        });
      }


var somePartial = someFnFactory();
// copying it before we do anything to it
var copied = new somePartial;

console.log(somePartial+'')
//matchs above inner function ->
     function someFn_partial(itWillRead, andUse){
       return (function someFn(someArgs, itWillRead, andUse){
        if (typeof someArgs === 'function') {
           var val = someArgs(this.someProperty, "whatever");
        }
        return itWillRead() ? val : andUse;
       }).call($this, someArgs, itWillRead, andUse);
     }



console.log(somePartial)
//->
      { [Function: someFn_partial]
        someArgs: [Constructor: Array],
        itWillRead: ___,
        andUse: ___ }


console.log(somePartial(Date, 1337));
//     [ "yeah", "whatever" ]

console.log(somePartial)
//->
      { [Function: someFn_partial],
        someArgs: [Constructor: Array],
        itWillRead: [Constructor: Date],
        andUse: 1337 }



// still matches the pre-call values, no shared state
console.log(copied)

Direct Proxies API Shim for Node

This module contains a very minimal amount changes to the reference implementation of the new Direct Proxies API that replaces the old Harmony Proxy proposal as of December 2011.

The reference source is available here and is, as of now, being updated frequently: es-lab DirectProxies.js

The reference test source is here: es-lab testDirectProxies.js

The official documentation and API is here: ES Wiki - Direct Proxies

Changes from the reference source

Changes have been made for two reasons. First, to be able to load it as a module as needed with an optional context to load it onto. Second, to force returned descriptors to be configurable to prevent constant errors from being thrown. The new API added support for non-configurable properties on Proxies but this isn't implemented in V8 yet and it causes the new API to be completely unusable instead of mostly usable if you know what you're doing. A better way to handle these properties could probably be implemented but the goal for this was the bare minimum changes to make it usable.

Usage

// initialize on context
require('direct-proxies')(global); // some context, `global` is default


// `Proxy` itself is now the creator for all proxies
var proxy = Proxy(target, handler);


// all traps now have their first parameter as `target` referencing the real object
{ getOwnPropertyDescriptor: function(target,name) }


// new global `Reflect` contains default traps
global.Reflect:
 { getOwnPropertyDescriptor,  // non-own `getProperty[Names|Descriptor]` gone
   getOwnPropertyNames,
   defineProperty,
   delete,
   freeze,                    // freeze/seal/preventExtensions separated
   seal,
   preventExtensions,
   has,
   hasOwn,
   get,
   set,
   enumerate,
   iterate,
   keys,
   apply,                     // apply/new are now traps on the handler
   new }


// for virtualized objects you can use this for your handler.prototype
// it implements some handlers but requires the others, like old fundamental traps
global.Reflect.VirtualHandler.prototype
 abstract { getOwnPropertyDescriptor,
 abstract   getOwnPropertyNames,
 abstract   defineProperty,
 abstract   delete,
            freeze,
            seal,
 abstract   preventExtensions,
            has,
            hasOwn,
            get,
            set,
            enumerate,
            iterate,
            keys,
 abstract   apply,
            new }

Compatability

Node 0.6.6 upgraded to V8 3.8 release candidate. The 3.7 branch introduced numerous important bug fixes to the Proxy and WeakMap implementations and is required to make this work.

If you are using Node >0.6.6 and are still getting "Illegal Access" errors see this: https://github.com/joyent/node/pull/2109

0.2.7

12 years ago

0.2.6

12 years ago

0.2.5

12 years ago

0.2.3

12 years ago

0.2.1

12 years ago

0.2.0

12 years ago

0.1.9

12 years ago

0.1.8

12 years ago

0.1.7

12 years ago

0.1.6

12 years ago

0.1.5

12 years ago

0.1.4

12 years ago

0.1.3

12 years ago

0.1.2

12 years ago

0.1.0

12 years ago

0.0.9

12 years ago

0.0.8

12 years ago

0.0.7

12 years ago

0.0.1

13 years ago