Skip to content

Commit

Permalink
Merge pull request rust-lang#91 from emberjs/weakmap
Browse files Browse the repository at this point in the history
WeakMap RFC
  • Loading branch information
mmun authored Jun 14, 2016
2 parents 8d8b335 + ddf743b commit 5e8001b
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions text/0066-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
- Start Date: 2015-09-11
- RFC PR: https://github.com/emberjs/ember.js/pull/12224
- Ember Issue: (leave this empty)

# Summary

Introduce `Ember.WeakMap` (`@ember/weakmap`), an ES6 enspired WeakMap. A
WeakMap provides a mechanism for storing and retriving private state. The
WeakMap itself does not retain a reference to the state, allowing the state to
be reclaimed when the key is reclaimed.

A traditional WeakMap (and the one that will be part of the language) allows
for weakness from key -> map, and also from map -> key. This allows either the
Map, or the key being reclaimed to also release the state.

Unforunately, this bi-directional weakness is problemative to polyfil. Luckily,
uni-directional weakness, in either direction, "just works". A polyfil must
just choose a direction.

*Note: Just like ES2015 WeakMap, only non null Objects can be used as keys*
*Note: `Ember.WeakMap` can be used interchangibly with the ES2015 WeakMap. This
will allow us to eventually cut over entirely to the Native WeakMap.*

# Motivation

It is a common pattern to want to store private state about a specific object.
When one stores this private state off-object, it can be tricky to understand
when to release the state. When one stores this state on-object, it will be
released when the object is released. Unfortunately, storing the state
on-object without poluting the object itself is non-obvious.

As it turns out, Ember's Meta already solves this problem for
listeners/caches/chains/descriptors etc. Unfortunately today, there is no
public API for apps or addons to utilize this. `Ember.WeakMap` aims to be
exactly that API.

Some examples:

* https://github.com/offirgolan/ember-cp-validations/blob/master/addon/utils/cycle-breaker.js
* https://github.com/stefanpenner/ember-state-services/ (will soon utilize the user-land polyfil of this) to prevent common leaks.

# Detailed design

## Public API

```js
import WeakMap from '@ember/weak-map'

var private = new WeakMap();
var object = {};
var otherObject = {};

private.set(object, {
id: 1,
name: 'My File',
progress: 0
}) === private;

private.get(object) === {
id: 1,
name: 'My File',
progress: 0
});


private.has(object) === true;
private.has(otherObject) === false;

private.delete(object) === private;
private.has(object) === false;
```

## Implementation Details

The backing store for `Ember.WeakMap` will reside in a lazy `ownMap` named
`weak` on the key objects `__meta__` object.

Each `WeakMap` has its own internal GUID, which will be the name of its slot,
in the key objects meta weak bucket. This will allow one object to belong in
multiple weakMaps without chance of collision.

Concrete Implementation: https://github.com/emberjs/ember.js/pull/12224
Polyfill: https://www.npmjs.com/package/ember-weakmap

# Drawbacks

* implementing bi-direction Weakness in userland is problematic.
* Using WeakMap will insert a non-enumerable `meta` onto the key Object.

# Alternatives

* Weakness could be implemented in the other direction, but this has questionable utility.

# Unresolved questions

N/A

0 comments on commit 5e8001b

Please sign in to comment.