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 CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b718cc81d1c3dedf9f6a4e92a627a92214a0d118
4
- data.tar.gz: aec9fe24896b2965108f802c435861f5b7db5f0e
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YjYzYzc3ZjM3NmE1ODk3MDE0NDg0MTMwODA0MmUyOGM0OWRkNjY5YQ==
5
+ data.tar.gz: !binary |-
6
+ MGQzZDFmYzc4MjUzY2I1MTcwMWI3ODNlZTc1OTQ3YWMzNzk1ZmNlYQ==
5
7
  SHA512:
6
- metadata.gz: 0bfff9ecf7789c0ad74e4aaf4d90062e8a565d2800199080e7d11daef67b9f0882eff16ddad1d54aef3da9ccfb0af1aa6c75379a6d1dd7d456a95b8db704bc2f
7
- data.tar.gz: a8c65fb7708a6eddd730fecbf58984c87528fbca403260a0ca895340058868794f5850755282cd0ec7824b270f55e2926cf70f7f80a1546f38853b8c9124e91d
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-12 Buzzware Solutions
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
- return Number(aValue);
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
- if (isNaN(aValue))
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
- return Math.round(Number(aValue));
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.result_key || this.key;
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
- return this;
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
- return this;
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
- return this;
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
- return this;
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
- return this;
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
- return this.kojac.performRequest(this);
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
- newRequest: function() {
921
- return new Kojac.Request({kojac: this});
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
- value = this.objectFactory.manufacture(value,key);
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
- // eg. kojac.read('cur_super').read('cur_super_products').request()
1067
- // or kojac.readRequest('cur_super','cur_super_products')
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
- readRequest: function(aKeys,aOptions) {
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 Convenience Functions
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===undefined)
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 = me.createInstance(newClass,aObject[i]);
1579
+ var newv = this.createInstance(newClass,aObject[i]);
1487
1580
  result.push(newv);
1488
1581
  }
1489
1582
  } else {
1490
- var newClass = this.classFromKey(aKey);
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