-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #82 from ampatspell/less-experimental-models
Models computed properties 2nd iteration
- Loading branch information
Showing
63 changed files
with
2,429 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { A } from '@ember/array'; | ||
import { assign } from '@ember/polyfills'; | ||
import property from './property'; | ||
|
||
const compact = array => A(array).compact(); | ||
|
||
const build = (opts, nested={}) => { | ||
opts = assign({}, opts, nested); | ||
let prop = property(opts); | ||
prop.owner = (...args) => build(opts, { parent: compact(args) }); | ||
prop.inline = arg => build(opts, { inline: arg }); | ||
prop.named = arg => build(opts, { named: arg }); | ||
prop.mapping = arg => build(opts, { mapping: arg }); | ||
return prop; | ||
} | ||
|
||
export default () => { | ||
let opts = { | ||
parent: [], | ||
object: [], | ||
inline: undefined, | ||
named: undefined, | ||
mapping: undefined | ||
}; | ||
|
||
return build(opts, {}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import Internal from '../../internal/internal'; | ||
import Runtime from './runtime'; | ||
|
||
export default Internal.extend({ | ||
|
||
parent: null, | ||
key: null, | ||
opts: null, | ||
|
||
runtime(create) { | ||
let runtime = this._runtime; | ||
if(!runtime && create) { | ||
let { parent, key, opts } = this.getProperties('parent', 'key', 'opts'); | ||
runtime = new Runtime(parent, key, opts, { | ||
updated: () => this.notifyPropertyChange() | ||
}); | ||
this._runtime = runtime; | ||
} | ||
return runtime; | ||
}, | ||
|
||
notifyPropertyChange() { | ||
let { parent, key } = this; | ||
if(parent.isDestroying) { | ||
return; | ||
} | ||
parent.notifyPropertyChange(key); | ||
}, | ||
|
||
model(create) { | ||
let runtime = this.runtime(create); | ||
return runtime && runtime.content; | ||
}, | ||
|
||
willDestroy() { | ||
this._super(...arguments); | ||
this._runtime && this._runtime.destroy(); | ||
} | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import destroyable from '../../util/destroyable'; | ||
import { getOwner } from '@ember/application'; | ||
|
||
const get = internal => internal.model(true); | ||
const reusable = () => false; | ||
|
||
const create = opts => function(key) { | ||
let parent = this; | ||
let owner = getOwner(this); | ||
return owner.factoryFor('zuglet:less-experimental/model/internal').create({ parent, key, opts }); | ||
} | ||
|
||
export default opts => { | ||
return destroyable({ | ||
create: create(opts), | ||
reusable, | ||
get | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import ModelFactory from '../util/model-factory'; | ||
import ObjectObserver from '../util/object-observer'; | ||
import { assert } from '@ember/debug'; | ||
import { typeOf } from '@ember/utils'; | ||
|
||
const validate = (opts, delegate) => { | ||
assert(`opts must be object`, typeOf(opts) === 'object'); | ||
assert(`delegate must be object`, typeOf(delegate) === 'object'); | ||
assert(`delegate.updated must be function`, typeOf(delegate.updated) === 'function'); | ||
} | ||
|
||
export default class ModelsRuntime { | ||
|
||
constructor(parent, key, opts, delegate) { | ||
validate(opts, delegate); | ||
this.parent = parent; | ||
this.key = key; | ||
this.opts = opts; | ||
this.delegate = delegate; | ||
|
||
this.modelFactory = new ModelFactory({ | ||
parent, | ||
key, | ||
inline: opts.inline, | ||
named: opts.named, | ||
mapping: opts.mapping, | ||
delegate: { | ||
mapping: () => [ parent ], | ||
named: () => [ parent ] | ||
} | ||
}); | ||
|
||
this.parentObserver = new ObjectObserver({ | ||
object: parent, | ||
observe: opts.parent, | ||
delegate: { | ||
updated: (object, key) => this.onParentPropertyUpdated(object, key) | ||
} | ||
}); | ||
|
||
this.rebuildModel(false); | ||
} | ||
|
||
createModel() { | ||
return this.modelFactory.create(); | ||
} | ||
|
||
rebuildModel(notify) { | ||
let previous = this.content; | ||
|
||
let content = this.createModel(); | ||
this.content = content; | ||
|
||
if(previous) { | ||
previous.destroy(); | ||
} | ||
|
||
if(previous !== content && notify) { | ||
this.delegate.updated(content); | ||
} | ||
} | ||
|
||
onParentPropertyUpdated() { | ||
this.rebuildModel(true); | ||
} | ||
|
||
destroy() { | ||
this.parentObserver.destroy(); | ||
let content = this.content; | ||
content && content.destroy(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { A } from '@ember/array'; | ||
import { assign } from '@ember/polyfills'; | ||
import property from './property'; | ||
|
||
const compact = array => A(array).compact(); | ||
|
||
// foo('docs') | ||
// foo('type', owner => owner.type) | ||
const source = args => { | ||
args = compact(args); | ||
if(args.length === 1) { | ||
return { dependencies: args, key: args[0] }; | ||
} else if(args.length > 1) { | ||
let last = args[args.length - 1]; | ||
if(typeof last === 'function') { | ||
let key = args.pop(); | ||
return { dependencies: args, key }; | ||
} | ||
} | ||
return undefined; | ||
} | ||
|
||
const build = (opts, nested={}) => { | ||
opts = assign({}, opts, nested); | ||
let prop = property(opts); | ||
prop.owner = (...args) => build(opts, { parent: compact(args) }); | ||
prop.object = (...args) => build(opts, { object: compact(args) }); | ||
prop.inline = arg => build(opts, { inline: arg }); | ||
prop.named = arg => build(opts, { named: arg }); | ||
prop.mapping = arg => build(opts, { mapping: arg }); | ||
prop.source = (...args) => build(opts, { source: source(args) }); | ||
return prop; | ||
} | ||
|
||
export default (...args) => { | ||
let opts = { | ||
source: undefined, | ||
parent: [], | ||
object: [], | ||
inline: undefined, | ||
named: undefined, | ||
mapping: undefined | ||
}; | ||
|
||
return build(opts, {}).source(...args); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Internal from '../../internal/internal'; | ||
import { getOwner } from '@ember/application'; | ||
import Runtime from './runtime'; | ||
|
||
export default Internal.extend({ | ||
|
||
parent: null, | ||
key: null, | ||
opts: null, | ||
|
||
runtime(create) { | ||
let runtime = this._runtime; | ||
if(!runtime && create) { | ||
let { parent, key, opts } = this.getProperties('parent', 'key', 'opts'); | ||
runtime = new Runtime(parent, key, opts); | ||
this._runtime = runtime; | ||
} | ||
return runtime; | ||
}, | ||
|
||
createModel() { | ||
let content = this.runtime(true).content; | ||
return getOwner(this.parent).factoryFor('zuglet:less-experimental/models').create({ _internal: this, content }); | ||
}, | ||
|
||
willDestroy() { | ||
this._super(...arguments); | ||
this._runtime && this._runtime.destroy(); | ||
} | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import ArrayProxy from '@ember/array/proxy'; | ||
import ModelMixin from '../../internal/model-mixin'; | ||
|
||
export default ArrayProxy.extend(ModelMixin); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import destroyable from '../../util/destroyable'; | ||
import { getOwner } from '@ember/application'; | ||
|
||
const get = internal => internal.model(true); | ||
const reusable = () => false; | ||
|
||
const create = opts => function(key) { | ||
let parent = this; | ||
let owner = getOwner(this); | ||
return owner.factoryFor('zuglet:less-experimental/models/internal').create({ parent, key, opts }); | ||
} | ||
|
||
export default opts => { | ||
return destroyable({ | ||
create: create(opts), | ||
reusable, | ||
get | ||
}); | ||
} |
Oops, something went wrong.