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 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