kojac 0.11.0 → 0.12.0
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.
- 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
|
|