kojac 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/app/assets/javascripts/kojac.js +150 -60
- data/app/assets/javascripts/kojac_ember.js +136 -199
- data/app/controllers/kojac_base_controller.rb +5 -60
- data/app/controllers/kojac_front_methods.rb +66 -0
- data/app/controllers/kojac_metal_controller.rb +25 -0
- data/app/serializers/kojac_base_serializer.rb +0 -2
- data/lib/kojac/kojac_rails.rb +32 -32
- data/lib/kojac/version.rb +1 -1
- data/spec/can_cache_spec.js +2 -1
- data/spec/ember_factory_spec.js +1 -1
- data/spec/ember_model_spec.js +34 -34
- data/spec/ember_override_spec.js +81 -0
- data/spec/ember_tojsono_spec.js +1 -1
- data/spec/error_handling_spec.js +2 -0
- data/spec/kojac_caching_spec.js +2 -1
- data/spec/kojac_mock_spec.js +1 -0
- data/spec/kojac_operations_spec.js +1 -0
- data/spec/local_provider_spec.js +1 -0
- data/spec/operation_include_spec.js +1 -0
- data/spec/run.html +4 -3
- metadata +16 -11
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjYzYzc3ZjM3NmE1ODk3MDE0NDg0MTMwODA0MmUyOGM0OWRkNjY5YQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MGQzZDFmYzc4MjUzY2I1MTcwMWI3ODNlZTc1OTQ3YWMzNzk1ZmNlYQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MDEzMDliZTE1YzIwY2FmZTQwMGJlYWUzODA1YjUyNGYzYzA0N2U5M2U4YjAw
|
10
|
+
MjA2MTM3ODhiNjQzZmIwOWZmOTU1NGIwNTQwZjFkYmFiOWViYjQ1Njc1M2Fj
|
11
|
+
ODcxYWM4MGQzMzE5NTBkYWY4ZWRkZmJlNGQwNWNjMTkyZjA1YWM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YzJlNTE1YTdhNmM3MmZkMTJjZjliZWRiY2Y5ZWMwODdlOGFkZDQ3OTRlMzY1
|
14
|
+
NjU1ZGQ4ZDM5YWVjMjc3OTY2YzJhNzk1NTAwYWY1YWIyMGZiZjg3ZjcxMTRm
|
15
|
+
MGRkM2ZhZTQ5ZWNlNWE1ZjlkNTM1MWY1MmIzMGIxNjVjMzhmMDA=
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*--------------------------------------------------------------------------
|
2
2
|
*
|
3
3
|
* Key Oriented JSON Application Cache (KOJAC)
|
4
|
-
* (c) 2011-
|
4
|
+
* (c) 2011-14 Buzzware Solutions
|
5
5
|
* https://github.com/buzzware/KOJAC
|
6
6
|
*
|
7
7
|
* KOJAC is freely distributable under the terms of an MIT-style license.
|
@@ -328,7 +328,10 @@ Kojac.interpretValueAsType = function(aValue, aDestType) {
|
|
328
328
|
return aValue;
|
329
329
|
break;
|
330
330
|
case String:
|
331
|
-
|
331
|
+
if (aValue.trim()=='')
|
332
|
+
return null;
|
333
|
+
var n = Number(aValue);
|
334
|
+
return isFinite(n) ? n : null;
|
332
335
|
break;
|
333
336
|
}
|
334
337
|
break;
|
@@ -344,13 +347,13 @@ Kojac.interpretValueAsType = function(aValue, aDestType) {
|
|
344
347
|
return aValue ? 1 : 0;
|
345
348
|
break;
|
346
349
|
case Number:
|
347
|
-
|
348
|
-
return null;
|
349
|
-
else
|
350
|
-
return Math.round(aValue);
|
350
|
+
return isFinite(aValue) ? Math.round(aValue) : null;
|
351
351
|
break;
|
352
352
|
case String:
|
353
|
-
|
353
|
+
if (aValue.trim()=='')
|
354
|
+
return null;
|
355
|
+
var n = Number(aValue);
|
356
|
+
return isFinite(n) ? Math.round(n) : null;
|
354
357
|
break;
|
355
358
|
}
|
356
359
|
|
@@ -452,7 +455,7 @@ keySplit = function(aKey) {
|
|
452
455
|
parts = ia.split('.');
|
453
456
|
if (parts.length>=1) { // id
|
454
457
|
id = parts[0];
|
455
|
-
var id_as_i = Number(id);
|
458
|
+
var id_as_i = Number(id); // !!! watch for Number('') => 0
|
456
459
|
if (_.isFinite(id_as_i))
|
457
460
|
id = id_as_i;
|
458
461
|
result.push(id);
|
@@ -741,8 +744,8 @@ Kojac.Operation = Kojac.Object.extend({
|
|
741
744
|
} else if (aResponseOp.error) {
|
742
745
|
this.error = aResponseOp.error;
|
743
746
|
} else {
|
744
|
-
var request_key = this.
|
745
|
-
var response_key = aResponseOp.result_key || this.key;
|
747
|
+
var request_key = this.key;
|
748
|
+
var response_key = aResponseOp.result_key || aResponseOp.key || this.key;
|
746
749
|
var final_result_key = this.result_key || response_key; // result_key should not be specified unless trying to override
|
747
750
|
var results = _.isObjectStrict(aResponseOp.results) ? aResponseOp.results : _.createObject(response_key,aResponseOp.results); // fix up server mistake
|
748
751
|
var result;
|
@@ -768,6 +771,7 @@ Kojac.Operation = Kojac.Object.extend({
|
|
768
771
|
*/
|
769
772
|
Kojac.Request = Kojac.Object.extend({
|
770
773
|
kojac: null,
|
774
|
+
chaining: false,
|
771
775
|
options: {},
|
772
776
|
ops: [],
|
773
777
|
handlers: null,
|
@@ -811,9 +815,12 @@ Kojac.Request = Kojac.Object.extend({
|
|
811
815
|
op.key = keyResource(k);
|
812
816
|
if ((i===0) && result_key)
|
813
817
|
op.result_key = result_key;
|
814
|
-
op.value = v;
|
818
|
+
op.value = Kojac.Utils.toJsono(v,op.options);
|
815
819
|
}
|
816
|
-
|
820
|
+
if (this.chaining)
|
821
|
+
return this;
|
822
|
+
else
|
823
|
+
return this.request();
|
817
824
|
},
|
818
825
|
|
819
826
|
// !!! if aKeys is String, split on ',' into an array
|
@@ -835,7 +842,10 @@ Kojac.Request = Kojac.Object.extend({
|
|
835
842
|
else
|
836
843
|
op.result_key = k;
|
837
844
|
});
|
838
|
-
|
845
|
+
if (this.chaining)
|
846
|
+
return this;
|
847
|
+
else
|
848
|
+
return this.request();
|
839
849
|
},
|
840
850
|
|
841
851
|
cacheRead: function(aKeys,aOptions) {
|
@@ -862,9 +872,12 @@ Kojac.Request = Kojac.Object.extend({
|
|
862
872
|
first = false;
|
863
873
|
} else
|
864
874
|
op.result_key = k;
|
865
|
-
op.value = v;
|
875
|
+
op.value = Kojac.Utils.toJsono(v,op.options);
|
866
876
|
};
|
867
|
-
|
877
|
+
if (this.chaining)
|
878
|
+
return this;
|
879
|
+
else
|
880
|
+
return this.request();
|
868
881
|
},
|
869
882
|
|
870
883
|
destroy: function(aKeys,aOptions) {
|
@@ -884,7 +897,10 @@ Kojac.Request = Kojac.Object.extend({
|
|
884
897
|
else
|
885
898
|
op.result_key = k;
|
886
899
|
});
|
887
|
-
|
900
|
+
if (this.chaining)
|
901
|
+
return this;
|
902
|
+
else
|
903
|
+
return this.request();
|
888
904
|
},
|
889
905
|
|
890
906
|
execute: function(aKey,aValue,aOptions) {
|
@@ -896,12 +912,20 @@ Kojac.Request = Kojac.Object.extend({
|
|
896
912
|
op.options = _.extend({cacheResults: false, manufacture: false},aOptions || {});
|
897
913
|
op.params = (params && _.clone(params));
|
898
914
|
op.key = aKey;
|
899
|
-
op.value = aValue;
|
900
|
-
|
915
|
+
op.value = Kojac.Utils.toJsono(aValue,op.options);
|
916
|
+
if (this.chaining)
|
917
|
+
return this;
|
918
|
+
else
|
919
|
+
return this.request();
|
901
920
|
},
|
902
921
|
|
903
|
-
request: function() {
|
904
|
-
|
922
|
+
request: function(aDone) {
|
923
|
+
var result = this.kojac.performRequest(this);
|
924
|
+
if (aDone)
|
925
|
+
result = result.done(aDone);
|
926
|
+
if (this.kojac.errorHandler)
|
927
|
+
result = result.fail(this.kojac.errorHandler);
|
928
|
+
return result;
|
905
929
|
}
|
906
930
|
});
|
907
931
|
|
@@ -909,16 +933,58 @@ Kojac.Request = Kojac.Object.extend({
|
|
909
933
|
* The Kojac core object
|
910
934
|
* @class Kojac.Core
|
911
935
|
* @extends Kojac.Object
|
936
|
+
*
|
937
|
+
* Normal API V2 Usage
|
938
|
+
*
|
939
|
+
* App = {};
|
940
|
+
* App.cache = {};
|
941
|
+
* App.kojac = new Kojac.Core({
|
942
|
+
* remoteProvider: ...,
|
943
|
+
* cache: App.cache
|
944
|
+
* });
|
945
|
+
*
|
946
|
+
* App.kojac.read('products').done(...);
|
947
|
+
* App.kojac.chain().create('products').execute('refresh').request(function(aKR){ // using optional done handler
|
948
|
+
* // handle done here
|
949
|
+
* }).fail(function(aKR){
|
950
|
+
* // handle fail here
|
951
|
+
* });
|
952
|
+
*
|
953
|
+
* Old API V1 usage
|
954
|
+
*
|
955
|
+
* App = {};
|
956
|
+
* App.cache = {};
|
957
|
+
* App.kojac = new Kojac.Core({
|
958
|
+
* remoteProvider: ...,
|
959
|
+
* cache: App.cache,
|
960
|
+
* apiVersion: 1
|
961
|
+
* });
|
962
|
+
*
|
963
|
+
* App.kojac.readRequest('products').done(...);
|
964
|
+
* App.kojac.create('products').execute('refresh').request().done(function(aKR){
|
965
|
+
* // handle done here
|
966
|
+
* }).fail(function(aKR){
|
967
|
+
* // handle fail here
|
968
|
+
* });
|
969
|
+
*
|
912
970
|
*/
|
913
971
|
Kojac.Core = Kojac.Object.extend({
|
914
972
|
|
915
973
|
remoteProvider: null,
|
916
974
|
objectFactory: null,
|
917
975
|
cache: null,
|
976
|
+
errorHandler: null,
|
918
977
|
dependentKeys: {},
|
919
|
-
|
920
|
-
|
921
|
-
|
978
|
+
apiVersion: 2, // set this to 1 for old read() and readRequest()
|
979
|
+
|
980
|
+
newRequest: function(aOptions) {
|
981
|
+
if (!aOptions)
|
982
|
+
aOptions = {};
|
983
|
+
aOptions = _.extend(aOptions,{kojac: this});
|
984
|
+
if (!(this.chaining in aOptions)) {
|
985
|
+
aOptions.chaining = this.apiVersion < 2
|
986
|
+
}
|
987
|
+
return new Kojac.Request(aOptions);
|
922
988
|
},
|
923
989
|
|
924
990
|
// var v;
|
@@ -960,9 +1026,9 @@ Kojac.Core = Kojac.Object.extend({
|
|
960
1026
|
|
961
1027
|
for (var key in op.results) {
|
962
1028
|
var value = op.results[key];
|
963
|
-
if ((op.options.atomise!==false) && _.isObjectStrict(value)) {
|
1029
|
+
if ((op.options.atomise!==false) && _.isObjectStrict(value)) { // we are atomising and this is an object
|
964
1030
|
var existing = this.cache.retrieve(key);
|
965
|
-
if (_.isObjectStrict(existing)) {
|
1031
|
+
if (_.isObjectStrict(existing) && (op.options.cacheResults!==false)) { // object is already in cache, and we are caching, so update it
|
966
1032
|
if (existing.beginPropertyChanges) {
|
967
1033
|
existing.beginPropertyChanges();
|
968
1034
|
updatedObjects.push(existing);
|
@@ -972,9 +1038,17 @@ Kojac.Core = Kojac.Object.extend({
|
|
972
1038
|
else
|
973
1039
|
_.copyProperties(existing,value);
|
974
1040
|
value = existing;
|
975
|
-
} else {
|
976
|
-
if ((op.options.manufacture!==false) && (this.objectFactory))
|
977
|
-
|
1041
|
+
} else { // otherwise manufacture
|
1042
|
+
if ((op.options.manufacture!==false) && (this.objectFactory)) {
|
1043
|
+
// if primary key & reassigned by result_key then manufacture with original key
|
1044
|
+
var mkey = key; // use the key from results by default
|
1045
|
+
if (key === op.result_key) { // this is the result key, so may have been renamed
|
1046
|
+
var has_dot = op.key.indexOf('.') >= 0; // prefer original key unless it contains a dot
|
1047
|
+
if (!has_dot)
|
1048
|
+
mkey = op.key;
|
1049
|
+
}
|
1050
|
+
value = this.objectFactory.manufacture(value,mkey);
|
1051
|
+
}
|
978
1052
|
}
|
979
1053
|
}
|
980
1054
|
op.results[key] = value;
|
@@ -1063,28 +1137,21 @@ Kojac.Core = Kojac.Object.extend({
|
|
1063
1137
|
// BEGIN User Functions
|
1064
1138
|
|
1065
1139
|
// These functions enable the user to build and trigger requests to the server/remote provider
|
1066
|
-
|
1067
|
-
|
1140
|
+
|
1141
|
+
chain: function() {
|
1142
|
+
return this.newRequest({chaining: true});
|
1143
|
+
},
|
1068
1144
|
|
1069
1145
|
create: function(aKeyValues,aOptions) {
|
1070
1146
|
var req = this.newRequest();
|
1071
1147
|
return req.create(aKeyValues,aOptions);
|
1072
1148
|
},
|
1073
|
-
createRequest: function(aKeyValues,aOptions) {
|
1074
|
-
return this.create(aKeyValues,aOptions).request();
|
1075
|
-
},
|
1076
1149
|
|
1077
1150
|
read: function(aKeys,aOptions) {
|
1078
1151
|
var req = this.newRequest();
|
1079
1152
|
return req.read(aKeys,aOptions);
|
1080
1153
|
},
|
1081
|
-
|
1082
|
-
return this.read(aKeys,aOptions).request();
|
1083
|
-
},
|
1084
|
-
cacheReadRequest: function(aKeys,aOptions) {
|
1085
|
-
aOptions = _.extend({},aOptions,{preferCache: true});
|
1086
|
-
return this.read(aKeys,aOptions).request();
|
1087
|
-
},
|
1154
|
+
|
1088
1155
|
cacheRead: function(aKeys,aOptions) {
|
1089
1156
|
aOptions = _.extend({},aOptions,{preferCache: true});
|
1090
1157
|
return this.read(aKeys,aOptions);
|
@@ -1094,26 +1161,51 @@ Kojac.Core = Kojac.Object.extend({
|
|
1094
1161
|
var req = this.newRequest();
|
1095
1162
|
return req.update(aKeyValues,aOptions);
|
1096
1163
|
},
|
1097
|
-
updateRequest: function(aKeyValues,aOptions) {
|
1098
|
-
return this.update(aKeyValues,aOptions).request();
|
1099
|
-
},
|
1100
1164
|
|
1101
1165
|
destroy: function(aKeys,aOptions) {
|
1102
1166
|
var req = this.newRequest();
|
1103
1167
|
return req.destroy(aKeys,aOptions);
|
1104
1168
|
},
|
1105
|
-
destroyRequest: function(aKeys,aOptions) {
|
1106
|
-
return this.destroy(aKeys,aOptions).request();
|
1107
|
-
},
|
1108
1169
|
|
1109
1170
|
execute: function(aKey,aValue,aOptions) {
|
1110
1171
|
var req = this.newRequest();
|
1111
1172
|
return req.execute(aKey,aValue,aOptions);
|
1112
1173
|
},
|
1174
|
+
// END Convenience Functions
|
1175
|
+
|
1176
|
+
// BEGIN DEPRECATED API V1 FUNCTIONS
|
1177
|
+
createRequest: function(aKeyValues,aOptions) {
|
1178
|
+
if (this.apiVersion > 1)
|
1179
|
+
throw "*Request methods are deprecated, and only supported when apiVersion is 1";
|
1180
|
+
return this.create(aKeyValues,aOptions).request();
|
1181
|
+
},
|
1182
|
+
readRequest: function(aKeys,aOptions) {
|
1183
|
+
if (this.apiVersion > 1)
|
1184
|
+
throw "*Request methods are deprecated, and only supported when apiVersion is 1";
|
1185
|
+
return this.read(aKeys,aOptions).request();
|
1186
|
+
},
|
1187
|
+
cacheReadRequest: function(aKeys,aOptions) {
|
1188
|
+
if (this.apiVersion > 1)
|
1189
|
+
throw "*Request methods are deprecated, and only supported when apiVersion is 1";
|
1190
|
+
aOptions = _.extend({},aOptions,{preferCache: true});
|
1191
|
+
return this.read(aKeys,aOptions).request();
|
1192
|
+
},
|
1193
|
+
updateRequest: function(aKeyValues,aOptions) {
|
1194
|
+
if (this.apiVersion > 1)
|
1195
|
+
throw "*Request methods are deprecated, and only supported when apiVersion is 1";
|
1196
|
+
return this.update(aKeyValues,aOptions).request();
|
1197
|
+
},
|
1198
|
+
destroyRequest: function(aKeys,aOptions) {
|
1199
|
+
if (this.apiVersion > 1)
|
1200
|
+
throw "*Request methods are deprecated, and only supported when apiVersion is 1";
|
1201
|
+
return this.destroy(aKeys,aOptions).request();
|
1202
|
+
},
|
1113
1203
|
executeRequest: function(aKey,aValue,aOptions) {
|
1204
|
+
if (this.apiVersion > 1)
|
1205
|
+
throw "*Request methods are deprecated, and only supported when apiVersion is 1";
|
1114
1206
|
return this.execute(aKey,aValue,aOptions).request();
|
1115
1207
|
}
|
1116
|
-
// END
|
1208
|
+
// END DEPRECATED API V1 FUNCTIONS
|
1117
1209
|
});
|
1118
1210
|
|
1119
1211
|
Kojac.Cache = Kojac.Object.extend({
|
@@ -1438,6 +1530,7 @@ Kojac.LocalStorageRemoteProvider = Kojac.Object.extend({
|
|
1438
1530
|
*/
|
1439
1531
|
Kojac.ObjectFactory = Kojac.Object.extend({
|
1440
1532
|
|
1533
|
+
namespace: null,
|
1441
1534
|
matchers: null,
|
1442
1535
|
defaultClass: Object,
|
1443
1536
|
|
@@ -1462,7 +1555,13 @@ Kojac.ObjectFactory = Kojac.Object.extend({
|
|
1462
1555
|
newClass = pair[1];
|
1463
1556
|
break;
|
1464
1557
|
}
|
1465
|
-
if (newClass
|
1558
|
+
if (!newClass) {
|
1559
|
+
var ns = this.namespace || Window;
|
1560
|
+
var r = keyResource(aKey);
|
1561
|
+
if (r && (r[0]==r[0].toUpperCase()) && _.isFunction(ns[r]))
|
1562
|
+
newClass = ns[r];
|
1563
|
+
}
|
1564
|
+
if (!newClass)
|
1466
1565
|
newClass = this.defaultClass;
|
1467
1566
|
return newClass;
|
1468
1567
|
},
|
@@ -1472,27 +1571,18 @@ Kojac.ObjectFactory = Kojac.Object.extend({
|
|
1472
1571
|
return new aClass(aProperties);
|
1473
1572
|
},
|
1474
1573
|
|
1475
|
-
copyProperties: function(aDest,aSource) {
|
1476
|
-
return _.extend(aDest,aSource);
|
1477
|
-
},
|
1478
|
-
|
1479
1574
|
manufacture: function(aObject,aKey) {
|
1480
1575
|
var newClass = this.classFromKey(aKey);
|
1481
|
-
var result;
|
1482
|
-
var me = this;
|
1576
|
+
var result = [];
|
1483
1577
|
if (_.isArray(aObject)) {
|
1484
|
-
result = [];
|
1485
1578
|
for (var i=0; i<aObject.length; i++) {
|
1486
|
-
var newv =
|
1579
|
+
var newv = this.createInstance(newClass,aObject[i]);
|
1487
1580
|
result.push(newv);
|
1488
1581
|
}
|
1489
1582
|
} else {
|
1490
|
-
|
1491
|
-
result = me.createInstance(newClass,aObject);
|
1583
|
+
result = this.createInstance(newClass,aObject);
|
1492
1584
|
}
|
1493
|
-
console.log('END manufacture');
|
1494
1585
|
return result;
|
1495
1586
|
}
|
1496
|
-
|
1497
1587
|
});
|
1498
1588
|
|