epf-source 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/dist/epf.js +284 -145
- data/dist/epf.js.map +1 -0
- data/lib/epf/source.rb +4 -0
- metadata +3 -2
data/dist/epf.js
CHANGED
@@ -34,7 +34,7 @@
|
|
34
34
|
var cwd = '/';
|
35
35
|
return {
|
36
36
|
title: 'browser',
|
37
|
-
version: 'v0.
|
37
|
+
version: 'v0.10.13',
|
38
38
|
browser: true,
|
39
39
|
env: {},
|
40
40
|
argv: [],
|
@@ -55,7 +55,6 @@
|
|
55
55
|
require('/lib/model/index.js', module);
|
56
56
|
require('/lib/session/index.js', module);
|
57
57
|
require('/lib/serializer/index.js', module);
|
58
|
-
require('/lib/session/index.js', module);
|
59
58
|
require('/lib/local/index.js', module);
|
60
59
|
require('/lib/rest/index.js', module);
|
61
60
|
});
|
@@ -166,6 +165,22 @@
|
|
166
165
|
return null;
|
167
166
|
}
|
168
167
|
},
|
168
|
+
extractRevision: function (type, hash) {
|
169
|
+
var revision = this._revision(type);
|
170
|
+
if (hash.hasOwnProperty(revision) && hash[revision] !== null) {
|
171
|
+
return parseInt(hash[revision]);
|
172
|
+
} else {
|
173
|
+
return undefined;
|
174
|
+
}
|
175
|
+
},
|
176
|
+
extractClientRevision: function (type, hash) {
|
177
|
+
var revision = this._clientRevision(type);
|
178
|
+
if (hash.hasOwnProperty(revision) && hash[revision] !== null) {
|
179
|
+
return parseInt(hash[revision]);
|
180
|
+
} else {
|
181
|
+
return undefined;
|
182
|
+
}
|
183
|
+
},
|
169
184
|
extractHasMany: function (type, hash, key) {
|
170
185
|
return hash[key];
|
171
186
|
},
|
@@ -442,6 +457,8 @@
|
|
442
457
|
deserialize: mustImplement('deserialize'),
|
443
458
|
extractId: mustImplement('extractId'),
|
444
459
|
extractClientId: mustImplement('extractClientId'),
|
460
|
+
extractRevision: mustImplement('extractRevision'),
|
461
|
+
extractClientRevision: mustImplement('extractClientRevision'),
|
445
462
|
extractAttribute: mustImplement('extractAttribute'),
|
446
463
|
extractHasMany: mustImplement('extractHasMany'),
|
447
464
|
extractBelongsTo: mustImplement('extractBelongsTo'),
|
@@ -449,6 +466,8 @@
|
|
449
466
|
var model = this.createModel(type);
|
450
467
|
set(model, 'id', this.extractId(type, hash));
|
451
468
|
set(model, 'clientId', this.extractClientId(type, hash));
|
469
|
+
set(model, 'rev', this.extractRevision(type, hash));
|
470
|
+
set(model, 'clientRev', this.extractClientRevision(type, hash));
|
452
471
|
this.deserializeAttributes(model, hash);
|
453
472
|
this.deserializeRelationships(model, hash);
|
454
473
|
return model;
|
@@ -573,12 +592,18 @@
|
|
573
592
|
},
|
574
593
|
serialize: function (record, options) {
|
575
594
|
options = options || {};
|
576
|
-
var serialized = this.createSerializedForm(), id;
|
595
|
+
var serialized = this.createSerializedForm(), id, rev, clientRev;
|
577
596
|
if (options.includeId) {
|
578
597
|
if (id = get(record, 'id')) {
|
579
598
|
this._addId(serialized, record.constructor, id);
|
580
599
|
}
|
581
600
|
this._addClientId(serialized, record.constructor, get(record, 'clientId'));
|
601
|
+
if (rev = get(record, 'rev')) {
|
602
|
+
this._addRevision(serialized, record.constructor, get(record, 'rev'));
|
603
|
+
}
|
604
|
+
if (clientRev = get(record, 'clientRev')) {
|
605
|
+
this._addClientRevision(serialized, record.constructor, get(record, 'clientRev'));
|
606
|
+
}
|
582
607
|
}
|
583
608
|
if (options.includeType) {
|
584
609
|
this.addType(serialized, record.constructor);
|
@@ -601,6 +626,12 @@
|
|
601
626
|
serializeClientId: function (clientId) {
|
602
627
|
return clientId;
|
603
628
|
},
|
629
|
+
serializeRevision: function (rev) {
|
630
|
+
return rev;
|
631
|
+
},
|
632
|
+
serializeClientRevision: function (rev) {
|
633
|
+
return rev;
|
634
|
+
},
|
604
635
|
addAttributes: function (data, record) {
|
605
636
|
record.eachAttribute(function (name, attribute) {
|
606
637
|
this._addAttribute(data, record, name, attribute.type);
|
@@ -632,6 +663,12 @@
|
|
632
663
|
clientKey: function (type) {
|
633
664
|
return 'client_id';
|
634
665
|
},
|
666
|
+
revision: function (type) {
|
667
|
+
return 'rev';
|
668
|
+
},
|
669
|
+
clientRevision: function (type) {
|
670
|
+
return 'client_rev';
|
671
|
+
},
|
635
672
|
keyForBelongsTo: function (type, name) {
|
636
673
|
return this.keyForAttributeName(type, name);
|
637
674
|
},
|
@@ -654,6 +691,22 @@
|
|
654
691
|
return this.clientKey(type);
|
655
692
|
}
|
656
693
|
},
|
694
|
+
_revision: function (type) {
|
695
|
+
var config = this.configurationForType(type), revision = config && config.revision;
|
696
|
+
if (revision) {
|
697
|
+
return revision;
|
698
|
+
} else {
|
699
|
+
return this.revision(type);
|
700
|
+
}
|
701
|
+
},
|
702
|
+
_clientRevision: function (type) {
|
703
|
+
var config = this.configurationForType(type), clientRevision = config && config.clientRevision;
|
704
|
+
if (clientRevision) {
|
705
|
+
return clientRevision;
|
706
|
+
} else {
|
707
|
+
return this.clientRevision(type);
|
708
|
+
}
|
709
|
+
},
|
657
710
|
_addAttribute: function (data, record, attributeName, attributeType) {
|
658
711
|
var key = this._keyForAttributeName(record.constructor, attributeName);
|
659
712
|
var value = get(record, attributeName);
|
@@ -667,6 +720,14 @@
|
|
667
720
|
var clientKey = this._clientKey(type);
|
668
721
|
this.addId(hash, clientKey, this.serializeClientId(id));
|
669
722
|
},
|
723
|
+
_addRevision: function (hash, type, rev) {
|
724
|
+
var revision = this._revision(type);
|
725
|
+
this.addId(hash, revision, this.serializeRevision(rev));
|
726
|
+
},
|
727
|
+
_addClientRevision: function (hash, type, rev) {
|
728
|
+
var revision = this._clientRevision(type);
|
729
|
+
this.addId(hash, revision, this.serializeClientRevision(rev));
|
730
|
+
},
|
670
731
|
_keyForAttributeName: function (type, name) {
|
671
732
|
return this._keyFromMappingOrHook('keyForAttributeName', type, name);
|
672
733
|
},
|
@@ -1311,6 +1372,8 @@
|
|
1311
1372
|
Ep.ModelMixin = Ember.Mixin.create({
|
1312
1373
|
id: null,
|
1313
1374
|
clientId: null,
|
1375
|
+
rev: null,
|
1376
|
+
clientRev: 0,
|
1314
1377
|
session: null,
|
1315
1378
|
errors: null,
|
1316
1379
|
isEqual: function (model) {
|
@@ -1357,17 +1420,15 @@
|
|
1357
1420
|
Ep.Model = Ember.Object.extend(Ember.Copyable, Ep.ModelMixin, {
|
1358
1421
|
isPromise: false,
|
1359
1422
|
isProxy: false,
|
1423
|
+
isNew: true,
|
1360
1424
|
isDeleted: false,
|
1361
1425
|
isLoaded: true,
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
}
|
1369
|
-
return value;
|
1370
|
-
}),
|
1426
|
+
isDirty: Ember.computed(function () {
|
1427
|
+
var session = get(this, 'session');
|
1428
|
+
if (!session)
|
1429
|
+
return false;
|
1430
|
+
return get(session, 'dirtyModels').contains(this);
|
1431
|
+
}).volatile(),
|
1371
1432
|
diff: function (model) {
|
1372
1433
|
var diffs = [];
|
1373
1434
|
this.eachAttribute(function (name, meta) {
|
@@ -1456,7 +1517,10 @@
|
|
1456
1517
|
dest.beginPropertyChanges();
|
1457
1518
|
set(dest, 'id', get(this, 'id'));
|
1458
1519
|
set(dest, 'clientId', get(this, 'clientId'));
|
1520
|
+
set(dest, 'rev', get(this, 'rev'));
|
1521
|
+
set(dest, 'clientRev', get(this, 'clientRev'));
|
1459
1522
|
set(dest, 'errors', Ember.copy(get(this, 'errors')));
|
1523
|
+
set(dest, 'isNew', get(this, 'isNew'));
|
1460
1524
|
set(dest, 'isDeleted', get(this, 'isDeleted'));
|
1461
1525
|
this.eachAttribute(function (name, meta) {
|
1462
1526
|
var left = get(this, name);
|
@@ -1800,7 +1864,10 @@
|
|
1800
1864
|
Ep.ModelProxy = Ember.ObjectProxy.extend(Ember.Copyable, Ep.ModelMixin, {
|
1801
1865
|
id: passThrough('id'),
|
1802
1866
|
clientId: passThrough('clientId'),
|
1867
|
+
rev: passThrough('rev'),
|
1868
|
+
clientRev: passThrough('clientRev'),
|
1803
1869
|
type: passThrough('type'),
|
1870
|
+
isDirty: false,
|
1804
1871
|
isPromise: false,
|
1805
1872
|
isLoaded: passThrough('isLoaded', false),
|
1806
1873
|
isLoading: false,
|
@@ -1966,7 +2033,7 @@
|
|
1966
2033
|
var data = {};
|
1967
2034
|
data[root] = get(this, 'serializer').serialize(model, { includeId: true });
|
1968
2035
|
return this.ajax(this.buildURL(root), 'POST', { data: data }).then(function (json) {
|
1969
|
-
return Ember.run(adapter, '
|
2036
|
+
return Ember.run(adapter, 'didReceiveData', json, model);
|
1970
2037
|
}, function (xhr) {
|
1971
2038
|
throw Ember.run(adapter, 'didError', xhr, model);
|
1972
2039
|
});
|
@@ -2021,16 +2088,6 @@
|
|
2021
2088
|
result = model;
|
2022
2089
|
}
|
2023
2090
|
});
|
2024
|
-
return result || targetModel;
|
2025
|
-
},
|
2026
|
-
didReceiveDataForCreate: function (data, targetModel) {
|
2027
|
-
var result = null;
|
2028
|
-
this.processData(data, function (model) {
|
2029
|
-
if (targetModel && model.isEqual(targetModel)) {
|
2030
|
-
result = model;
|
2031
|
-
}
|
2032
|
-
});
|
2033
|
-
set(targetModel, 'id', get(result, 'id'));
|
2034
2091
|
return result;
|
2035
2092
|
},
|
2036
2093
|
didReceiveDataForLoad: function (data, type, id) {
|
@@ -2199,6 +2256,7 @@
|
|
2199
2256
|
shadows.add(copy);
|
2200
2257
|
}
|
2201
2258
|
}
|
2259
|
+
this._embeddedManager.updateParents(model);
|
2202
2260
|
}, this);
|
2203
2261
|
},
|
2204
2262
|
dirtyEmbeddedTree: function (model, models, shadows, session) {
|
@@ -2311,48 +2369,23 @@
|
|
2311
2369
|
require.define('/lib/rest/operation_graph.js', function (module, exports, __dirname, __filename) {
|
2312
2370
|
require('/lib/rest/operation.js', module);
|
2313
2371
|
var get = Ember.get, set = Ember.set;
|
2314
|
-
var Node = function (model) {
|
2315
|
-
this.op = null;
|
2316
|
-
this.children = Ember.Set.create();
|
2317
|
-
this.parents = Ember.Set.create();
|
2318
|
-
this.dirty = false;
|
2319
|
-
this.dirtyEmbeddedChildren = false;
|
2320
|
-
};
|
2321
|
-
Node.prototype = {
|
2322
|
-
addChild: function (childNode) {
|
2323
|
-
this.children.add(childNode);
|
2324
|
-
childNode.parents.add(this);
|
2325
|
-
},
|
2326
|
-
isRoot: function () {
|
2327
|
-
return this.parents.every(function (parent) {
|
2328
|
-
return !get(parent, 'dirty') && parent.isRoot();
|
2329
|
-
});
|
2330
|
-
},
|
2331
|
-
toString: function (depth) {
|
2332
|
-
if (!depth)
|
2333
|
-
depth = 0;
|
2334
|
-
var prefix = '';
|
2335
|
-
for (var i = 0; i < depth; i++) {
|
2336
|
-
prefix += ' ';
|
2337
|
-
}
|
2338
|
-
return prefix + this.op.toString() + this.children.map(function (child) {
|
2339
|
-
return '\n' + child.toString(depth + 1);
|
2340
|
-
});
|
2341
|
-
}
|
2342
|
-
};
|
2343
2372
|
Ep.OperationGraph = Ember.Object.extend({
|
2344
2373
|
models: null,
|
2345
2374
|
shadows: null,
|
2346
|
-
|
2375
|
+
rootOps: null,
|
2347
2376
|
adapter: null,
|
2348
|
-
nodes: null,
|
2349
2377
|
init: function () {
|
2350
|
-
|
2378
|
+
var graph = this;
|
2379
|
+
this.ops = Ember.MapWithDefault.create({
|
2351
2380
|
defaultValue: function (model) {
|
2352
|
-
return
|
2381
|
+
return Ep.Operation.create({
|
2382
|
+
model: model,
|
2383
|
+
graph: graph,
|
2384
|
+
adapter: get(graph, 'adapter')
|
2385
|
+
});
|
2353
2386
|
}
|
2354
2387
|
});
|
2355
|
-
this.
|
2388
|
+
this.rootOps = Ember.Set.create();
|
2356
2389
|
this.build();
|
2357
2390
|
},
|
2358
2391
|
perform: function () {
|
@@ -2362,63 +2395,60 @@
|
|
2362
2395
|
var adapter = get(this, 'adapter');
|
2363
2396
|
var models = get(this, 'models');
|
2364
2397
|
var shadows = get(this, 'shadows');
|
2365
|
-
var
|
2366
|
-
var
|
2398
|
+
var rootOps = get(this, 'rootOps');
|
2399
|
+
var ops = get(this, 'ops');
|
2367
2400
|
models.forEach(function (model) {
|
2368
2401
|
if (!get(model, 'isLoaded')) {
|
2369
2402
|
return;
|
2370
2403
|
}
|
2371
2404
|
var shadow = shadows.getModel(model);
|
2372
|
-
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
adapter
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
var
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
}
|
2386
|
-
var rels = get(node.op, 'dirtyRelationships');
|
2405
|
+
Ember.assert('Shadow does not exist for non-new model', shadow || get(model, 'isNew'));
|
2406
|
+
var op = ops.get(model);
|
2407
|
+
set(op, 'shadow', shadow);
|
2408
|
+
var isEmbedded = adapter.isEmbedded(model);
|
2409
|
+
if (get(op, 'isDirty') && isEmbedded) {
|
2410
|
+
var rootModel = adapter.findEmbeddedRoot(model, models);
|
2411
|
+
var rootOp = this.getOp(rootModel);
|
2412
|
+
set(rootOp, 'force', true);
|
2413
|
+
var parentModel = adapter._embeddedManager.findParent(model);
|
2414
|
+
var parentOp = this.getOp(parentModel);
|
2415
|
+
parentOp.addChild(op);
|
2416
|
+
}
|
2417
|
+
var rels = get(op, 'dirtyRelationships');
|
2387
2418
|
for (var i = 0; i < rels.length; i++) {
|
2388
2419
|
var d = rels[i];
|
2389
2420
|
var name = d.name;
|
2390
2421
|
var parentModel = model.get(name) || shadows.getModel(d.oldValue);
|
2391
2422
|
if (parentModel) {
|
2392
|
-
|
2393
|
-
|
2394
|
-
parentNode.addChild(node);
|
2423
|
+
var parentOp = this.getOp(parentModel);
|
2424
|
+
parentOp.addChild(op);
|
2395
2425
|
}
|
2396
2426
|
}
|
2397
2427
|
}, this);
|
2398
|
-
|
2399
|
-
if (
|
2400
|
-
|
2428
|
+
ops.forEach(function (model, op) {
|
2429
|
+
if (get(op, 'isDirty') && get(op, 'isRoot')) {
|
2430
|
+
rootOps.add(op);
|
2401
2431
|
}
|
2402
2432
|
}, this);
|
2403
2433
|
},
|
2434
|
+
getOp: function (model) {
|
2435
|
+
var models = get(this, 'models');
|
2436
|
+
return this.ops.get(models.getModel(model));
|
2437
|
+
},
|
2404
2438
|
createPromise: function () {
|
2405
|
-
var
|
2406
|
-
function createNestedPromise(
|
2407
|
-
var promise =
|
2439
|
+
var rootOps = get(this, 'rootOps'), adapter = get(this, 'adapter'), cumulative = [];
|
2440
|
+
function createNestedPromise(op) {
|
2441
|
+
var promise = op.perform();
|
2408
2442
|
promise = promise.then(function (model) {
|
2409
|
-
|
2410
|
-
cumulative.push(model.lazyCopy());
|
2411
|
-
} else {
|
2412
|
-
cumulative.push(model);
|
2413
|
-
}
|
2443
|
+
cumulative.push(model);
|
2414
2444
|
return model;
|
2415
2445
|
}, function (model) {
|
2416
2446
|
cumulative.push(model);
|
2417
2447
|
throw model;
|
2418
2448
|
});
|
2419
|
-
if (
|
2449
|
+
if (op.children.length > 0) {
|
2420
2450
|
promise = promise.then(function (model) {
|
2421
|
-
var childPromises =
|
2451
|
+
var childPromises = op.children.map(createNestedPromise);
|
2422
2452
|
return Ember.RSVP.all(childPromises).then(function (models) {
|
2423
2453
|
adapter.rebuildRelationships(models, model);
|
2424
2454
|
return model;
|
@@ -2427,7 +2457,7 @@
|
|
2427
2457
|
}
|
2428
2458
|
return promise;
|
2429
2459
|
}
|
2430
|
-
return Ember.RSVP.all(
|
2460
|
+
return Ember.RSVP.all(rootOps.map(createNestedPromise)).then(function () {
|
2431
2461
|
return cumulative;
|
2432
2462
|
}, function (err) {
|
2433
2463
|
throw cumulative;
|
@@ -2435,9 +2465,9 @@
|
|
2435
2465
|
},
|
2436
2466
|
toStringExtension: function () {
|
2437
2467
|
var result = '';
|
2438
|
-
var
|
2439
|
-
|
2440
|
-
result += '\n' +
|
2468
|
+
var rootOps = get(this, 'rootOps');
|
2469
|
+
rootOps.forEach(function (op) {
|
2470
|
+
result += '\n' + op.toString(1);
|
2441
2471
|
});
|
2442
2472
|
return result + '\n';
|
2443
2473
|
}
|
@@ -2449,6 +2479,8 @@
|
|
2449
2479
|
model: null,
|
2450
2480
|
shadow: null,
|
2451
2481
|
adapter: null,
|
2482
|
+
_promise: null,
|
2483
|
+
force: false,
|
2452
2484
|
init: function () {
|
2453
2485
|
this.children = Ember.Set.create();
|
2454
2486
|
this.parents = Ember.Set.create();
|
@@ -2478,6 +2510,9 @@
|
|
2478
2510
|
return rels;
|
2479
2511
|
}),
|
2480
2512
|
isDirty: Ember.computed(function () {
|
2513
|
+
return !!get(this, 'dirtyType');
|
2514
|
+
}),
|
2515
|
+
isDirtyFromUpdates: Ember.computed(function () {
|
2481
2516
|
var model = get(this, 'model'), shadow = get(this, 'shadow'), adapter = get(this, 'adapter');
|
2482
2517
|
var diff = model.diff(shadow);
|
2483
2518
|
var dirty = false;
|
@@ -2498,17 +2533,20 @@
|
|
2498
2533
|
return 'created';
|
2499
2534
|
} else if (get(model, 'isDeleted')) {
|
2500
2535
|
return 'deleted';
|
2501
|
-
} else if (get(this, '
|
2536
|
+
} else if (get(this, 'isDirtyFromUpdates') || get(this, 'force')) {
|
2502
2537
|
return 'updated';
|
2503
2538
|
}
|
2504
2539
|
}),
|
2505
|
-
perform: function (
|
2540
|
+
perform: function () {
|
2541
|
+
if (this._promise)
|
2542
|
+
return this._promise;
|
2506
2543
|
var adapter = get(this, 'adapter'), dirtyType = get(this, 'dirtyType'), model = get(this, 'model'), shadow = get(this, 'shadow'), promise;
|
2507
|
-
if (!dirtyType && forceUpdate) {
|
2508
|
-
dirtyType = 'updated';
|
2509
|
-
}
|
2510
2544
|
if (!dirtyType || !adapter.shouldSave(model)) {
|
2511
|
-
|
2545
|
+
if (adapter.isEmbedded(model)) {
|
2546
|
+
promise = this._promiseFromEmbeddedParent();
|
2547
|
+
} else {
|
2548
|
+
promise = Ember.RSVP.resolve();
|
2549
|
+
}
|
2512
2550
|
} else if (dirtyType === 'created') {
|
2513
2551
|
promise = adapter.create(model);
|
2514
2552
|
} else if (dirtyType === 'updated') {
|
@@ -2516,17 +2554,61 @@
|
|
2516
2554
|
} else if (dirtyType === 'deleted') {
|
2517
2555
|
promise = adapter.deleteModel(model);
|
2518
2556
|
}
|
2519
|
-
|
2557
|
+
promise = promise.then(function (serverModel) {
|
2558
|
+
if (!get(model, 'id')) {
|
2559
|
+
set(model, 'id', get(serverModel, 'id'));
|
2560
|
+
}
|
2561
|
+
if (!serverModel) {
|
2562
|
+
serverModel = model;
|
2563
|
+
} else if (!get(serverModel, 'clientRev')) {
|
2564
|
+
set(serverModel, 'clientRev', get(model, 'clientRev'));
|
2565
|
+
}
|
2566
|
+
return serverModel;
|
2567
|
+
}, function (serverModel) {
|
2520
2568
|
if (shadow) {
|
2521
|
-
shadow.set('errors',
|
2569
|
+
shadow.set('errors', serverModel.get('errors'));
|
2522
2570
|
throw shadow;
|
2523
2571
|
}
|
2524
|
-
throw
|
2572
|
+
throw serverModel;
|
2573
|
+
});
|
2574
|
+
return this._promise = promise;
|
2575
|
+
},
|
2576
|
+
_embeddedParent: Ember.computed(function () {
|
2577
|
+
var model = get(this, 'model'), parentModel = get(this, 'adapter')._embeddedManager.findParent(model), graph = get(this, 'graph');
|
2578
|
+
Ember.assert('Embedded parent does not exist!', parentModel);
|
2579
|
+
return graph.getOp(parentModel);
|
2580
|
+
}),
|
2581
|
+
_promiseFromEmbeddedParent: function () {
|
2582
|
+
var serializer = get(this, 'adapter.serializer');
|
2583
|
+
var model = this.model;
|
2584
|
+
function findInParent(parentModel) {
|
2585
|
+
var res = null;
|
2586
|
+
serializer.eachEmbeddedRecord(parentModel, function (child, embeddedType) {
|
2587
|
+
if (res)
|
2588
|
+
return;
|
2589
|
+
if (child.isEqual(model))
|
2590
|
+
res = child;
|
2591
|
+
});
|
2592
|
+
return res;
|
2593
|
+
}
|
2594
|
+
return get(this, '_embeddedParent').perform().then(function (parent) {
|
2595
|
+
return findInParent(parent);
|
2596
|
+
}, function (parent) {
|
2597
|
+
throw findInParent(parent);
|
2525
2598
|
});
|
2526
2599
|
},
|
2527
2600
|
toStringExtension: function () {
|
2528
2601
|
return '( ' + get(this, 'dirtyType') + ' ' + get(this, 'model') + ' )';
|
2529
|
-
}
|
2602
|
+
},
|
2603
|
+
addChild: function (child) {
|
2604
|
+
this.children.add(child);
|
2605
|
+
child.parents.add(this);
|
2606
|
+
},
|
2607
|
+
isRoot: Ember.computed(function () {
|
2608
|
+
return this.parents.every(function (parent) {
|
2609
|
+
return !get(parent, 'isDirty') && get(parent, 'isRoot');
|
2610
|
+
});
|
2611
|
+
}).volatile()
|
2530
2612
|
});
|
2531
2613
|
});
|
2532
2614
|
require.define('/lib/rest/embedded_manager.js', function (module, exports, __dirname, __filename) {
|
@@ -2878,34 +2960,70 @@
|
|
2878
2960
|
var get = Ember.get, set = Ember.set;
|
2879
2961
|
Ep.Session.reopen({
|
2880
2962
|
merge: function (model, strategy) {
|
2881
|
-
var shadows = get(this, 'shadows'), newModels = get(this, 'newModels');
|
2882
2963
|
this.reifyClientId(model);
|
2883
|
-
if (
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
2891
|
-
|
2964
|
+
if (get(model, 'hasErrors')) {
|
2965
|
+
return this._mergeError(model, strategy);
|
2966
|
+
} else {
|
2967
|
+
return this._mergeSuccess(model, strategy);
|
2968
|
+
}
|
2969
|
+
},
|
2970
|
+
_mergeSuccess: function (model, strategy) {
|
2971
|
+
var models = get(this, 'models'), shadows = get(this, 'shadows'), newModels = get(this, 'newModels'), originals = get(this, 'originals'), merged, ancestor, existing = models.getModel(model);
|
2972
|
+
if (existing && this._containsRev(existing, model)) {
|
2973
|
+
return existing;
|
2974
|
+
}
|
2975
|
+
var hasClientChanges = !existing || this._containsClientRev(model, existing);
|
2976
|
+
if (hasClientChanges) {
|
2977
|
+
ancestor = shadows.getModel(model);
|
2978
|
+
} else {
|
2979
|
+
ancestor = originals.getModel(model);
|
2980
|
+
}
|
2981
|
+
this.suspendDirtyChecking(function () {
|
2982
|
+
merged = this._mergeModel(existing, ancestor, model, strategy);
|
2983
|
+
}, this);
|
2984
|
+
if (hasClientChanges) {
|
2985
|
+
if (get(merged, 'isDeleted')) {
|
2986
|
+
this.remove(merged);
|
2987
|
+
} else {
|
2988
|
+
if (shadows.contains(model) && get(model, 'isLoaded')) {
|
2989
|
+
shadows.add(model);
|
2990
|
+
}
|
2991
|
+
originals.remove(model);
|
2992
|
+
if (!get(merged, 'isNew')) {
|
2993
|
+
newModels.remove(merged);
|
2994
|
+
}
|
2892
2995
|
}
|
2893
|
-
newModels.remove(model);
|
2894
2996
|
} else {
|
2997
|
+
}
|
2998
|
+
return merged;
|
2999
|
+
},
|
3000
|
+
_mergeError: function (model, strategy) {
|
3001
|
+
var models = get(this, 'models'), shadows = get(this, 'shadows'), newModels = get(this, 'newModels'), originals = get(this, 'originals'), merged, ancestor, existing = models.getModel(model);
|
3002
|
+
if (!existing) {
|
3003
|
+
Ember.assert('Errors returned for non-existant model: ' + model.toString(), model instanceof Ep.LoadError);
|
3004
|
+
return model;
|
3005
|
+
}
|
3006
|
+
ancestor = originals.getModel(model);
|
3007
|
+
if (ancestor && !this._containsRev(existing, model)) {
|
2895
3008
|
this.suspendDirtyChecking(function () {
|
2896
|
-
merged = this.
|
3009
|
+
merged = this._mergeModel(existing, ancestor, model, strategy);
|
2897
3010
|
}, this);
|
2898
|
-
|
3011
|
+
} else {
|
3012
|
+
merged = existing;
|
2899
3013
|
}
|
3014
|
+
set(merged, 'errors', Ember.copy(get(model, 'errors')));
|
3015
|
+
shadows.add(model);
|
3016
|
+
originals.remove(model);
|
2900
3017
|
return merged;
|
2901
3018
|
},
|
2902
|
-
|
2903
|
-
|
3019
|
+
_mergeModel: function (dest, ancestor, model, strategy) {
|
3020
|
+
if (!strategy)
|
3021
|
+
strategy = get(this, 'mergeStrategy').create({ session: this });
|
2904
3022
|
if (model === dest) {
|
2905
3023
|
return model;
|
2906
3024
|
}
|
2907
3025
|
if (get(model, 'isPromise')) {
|
2908
|
-
return this.
|
3026
|
+
return this._mergePromise(dest, ancestor, model, strategy);
|
2909
3027
|
}
|
2910
3028
|
var promise;
|
2911
3029
|
if (dest && get(dest, 'isPromise')) {
|
@@ -2918,18 +3036,24 @@
|
|
2918
3036
|
promise.resolve(dest);
|
2919
3037
|
}
|
2920
3038
|
}
|
3039
|
+
if (!get(model, 'hasErrors')) {
|
3040
|
+
set(dest, 'isNew', false);
|
3041
|
+
}
|
2921
3042
|
set(dest, 'id', get(model, 'id'));
|
2922
3043
|
set(dest, 'clientId', get(model, 'clientId'));
|
3044
|
+
set(dest, 'rev', get(model, 'rev'));
|
2923
3045
|
set(dest, 'isDeleted', get(model, 'isDeleted'));
|
2924
|
-
set(dest, 'errors', Ember.copy(get(model, 'errors')));
|
2925
3046
|
this.adopt(dest);
|
2926
|
-
|
3047
|
+
if (!ancestor) {
|
3048
|
+
ancestor = dest;
|
3049
|
+
}
|
3050
|
+
strategy.merge(dest, ancestor, model);
|
2927
3051
|
return dest;
|
2928
3052
|
},
|
2929
|
-
|
3053
|
+
_mergePromise: function (dest, ancestor, promise, strategy) {
|
2930
3054
|
var content = get(promise, 'content');
|
2931
3055
|
if (content) {
|
2932
|
-
return this.merge(content, strategy);
|
3056
|
+
return this.merge(dest, ancestor, content, strategy);
|
2933
3057
|
}
|
2934
3058
|
if (!dest) {
|
2935
3059
|
dest = promise.lazyCopy();
|
@@ -2937,14 +3061,15 @@
|
|
2937
3061
|
}
|
2938
3062
|
return dest;
|
2939
3063
|
},
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
2944
|
-
return
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
3064
|
+
_containsRev: function (modelA, modelB) {
|
3065
|
+
if (!get(modelA, 'rev'))
|
3066
|
+
return false;
|
3067
|
+
if (!get(modelB, 'rev'))
|
3068
|
+
return false;
|
3069
|
+
return get(modelA, 'rev') >= get(modelB, 'rev');
|
3070
|
+
},
|
3071
|
+
_containsClientRev: function (modelA, modelB) {
|
3072
|
+
return get(modelA, 'clientRev') >= get(modelB, 'clientRev');
|
2948
3073
|
}
|
2949
3074
|
});
|
2950
3075
|
});
|
@@ -2965,6 +3090,7 @@
|
|
2965
3090
|
this.collectionManager = Ep.CollectionManager.create();
|
2966
3091
|
this.belongsToManager = Ep.BelongsToManager.create();
|
2967
3092
|
this.shadows = Ep.ModelSet.create();
|
3093
|
+
this.originals = Ep.ModelSet.create();
|
2968
3094
|
this.newModels = Ep.ModelSet.create();
|
2969
3095
|
},
|
2970
3096
|
create: function (type, hash) {
|
@@ -3042,6 +3168,11 @@
|
|
3042
3168
|
}, this);
|
3043
3169
|
return dest;
|
3044
3170
|
},
|
3171
|
+
remove: function (model) {
|
3172
|
+
get(this, 'models').remove(model);
|
3173
|
+
get(this, 'shadows').remove(model);
|
3174
|
+
get(this, 'originals').remove(model);
|
3175
|
+
},
|
3045
3176
|
update: function (model) {
|
3046
3177
|
this.reifyClientId(model);
|
3047
3178
|
if (get(model, 'isProxy')) {
|
@@ -3135,7 +3266,10 @@
|
|
3135
3266
|
});
|
3136
3267
|
},
|
3137
3268
|
flush: function () {
|
3138
|
-
var session = this, dirtyModels = get(this, 'dirtyModels'), shadows = get(this, 'shadows');
|
3269
|
+
var session = this, dirtyModels = get(this, 'dirtyModels'), newModels = get(this, 'newModels'), shadows = get(this, 'shadows');
|
3270
|
+
dirtyModels.forEach(function (model) {
|
3271
|
+
model.incrementProperty('clientRev');
|
3272
|
+
}, this);
|
3139
3273
|
var promise = this.adapter.flush(this).then(function (models) {
|
3140
3274
|
var res = models.map(function (model) {
|
3141
3275
|
return session.merge(model);
|
@@ -3148,8 +3282,14 @@
|
|
3148
3282
|
throw res;
|
3149
3283
|
});
|
3150
3284
|
dirtyModels.forEach(function (model) {
|
3151
|
-
this.
|
3285
|
+
var original = this.originals.getModel(model);
|
3286
|
+
var shadow = this.shadows.getModel(model);
|
3287
|
+
if (shadow && (!original || original.get('rev') < shadow.get('rev'))) {
|
3288
|
+
this.originals.add(shadow);
|
3289
|
+
}
|
3290
|
+
this.shadows.remove(model);
|
3152
3291
|
}, this);
|
3292
|
+
newModels.clear();
|
3153
3293
|
return promise;
|
3154
3294
|
},
|
3155
3295
|
getModel: function (model) {
|
@@ -3189,6 +3329,7 @@
|
|
3189
3329
|
this.collectionManager.destroy();
|
3190
3330
|
this.belongsToManager.destroy();
|
3191
3331
|
this.shadows.destroy();
|
3332
|
+
this.originals.destroy();
|
3192
3333
|
this.newModels.destroy();
|
3193
3334
|
},
|
3194
3335
|
dirtyModels: Ember.computed(function () {
|
@@ -3243,23 +3384,21 @@
|
|
3243
3384
|
init: function () {
|
3244
3385
|
this.cache = Ep.ModelSet.create();
|
3245
3386
|
},
|
3246
|
-
merge: function (
|
3387
|
+
merge: function (ours, ancestor, theirs) {
|
3247
3388
|
if (this.cache.contains(ours))
|
3248
3389
|
return ours;
|
3249
3390
|
this.cache.addObject(theirs);
|
3250
3391
|
ours.beginPropertyChanges();
|
3251
|
-
|
3252
|
-
|
3253
|
-
this.mergeAttributes(theirs, ours, original);
|
3254
|
-
this.mergeRelationships(theirs, ours, original);
|
3392
|
+
this.mergeAttributes(ours, ancestor, theirs);
|
3393
|
+
this.mergeRelationships(ours, ancestor, theirs);
|
3255
3394
|
ours.endPropertyChanges();
|
3256
3395
|
return ours;
|
3257
3396
|
},
|
3258
|
-
mergeAttributes: function (
|
3397
|
+
mergeAttributes: function (ours, ancestor, theirs) {
|
3259
3398
|
ours.eachAttribute(function (name, meta) {
|
3260
3399
|
var oursValue = get(ours, name);
|
3261
3400
|
var theirsValue = get(theirs, name);
|
3262
|
-
var originalValue = get(
|
3401
|
+
var originalValue = get(ancestor, name);
|
3263
3402
|
if (oursValue === theirsValue)
|
3264
3403
|
return;
|
3265
3404
|
if (oursValue === originalValue) {
|
@@ -3267,13 +3406,13 @@
|
|
3267
3406
|
}
|
3268
3407
|
});
|
3269
3408
|
},
|
3270
|
-
mergeRelationships: function (
|
3409
|
+
mergeRelationships: function (ours, ancestor, theirs) {
|
3271
3410
|
var session = get(this, 'session');
|
3272
3411
|
ours.eachRelationship(function (name, relationship) {
|
3273
3412
|
if (relationship.kind === 'belongsTo') {
|
3274
3413
|
var oursValue = get(ours, name);
|
3275
3414
|
var theirsValue = get(theirs, name);
|
3276
|
-
var originalValue = get(
|
3415
|
+
var originalValue = get(ancestor, name);
|
3277
3416
|
var merged = mergeIfPresent(session, theirsValue, this);
|
3278
3417
|
if (isEqual(oursValue, originalValue)) {
|
3279
3418
|
set(ours, name, merged);
|
@@ -3281,7 +3420,7 @@
|
|
3281
3420
|
} else if (relationship.kind === 'hasMany') {
|
3282
3421
|
var theirChildren = get(theirs, name);
|
3283
3422
|
var ourChildren = get(ours, name);
|
3284
|
-
var originalChildren = get(
|
3423
|
+
var originalChildren = get(ancestor, name);
|
3285
3424
|
if (isEqual(ourChildren, originalChildren)) {
|
3286
3425
|
var existing = Ep.ModelSet.create();
|
3287
3426
|
existing.addObjects(ourChildren);
|
@@ -3310,7 +3449,7 @@
|
|
3310
3449
|
init: function () {
|
3311
3450
|
this.cache = Ep.ModelSet.create();
|
3312
3451
|
},
|
3313
|
-
merge: function (
|
3452
|
+
merge: function (dest, ancestor, model) {
|
3314
3453
|
if (this.cache.contains(model))
|
3315
3454
|
return dest;
|
3316
3455
|
this.cache.addObject(model);
|