alchemymvc 1.3.19 → 1.3.21
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.
- package/lib/app/behaviour/sluggable_behaviour.js +0 -0
- package/lib/app/datasource/mongo_datasource.js +94 -1
- package/lib/app/element/time_ago.js +0 -0
- package/lib/app/helper/alchemy_helper.js +8 -4
- package/lib/app/helper_controller/controller.js +1 -0
- package/lib/app/helper_datasource/00-nosql_datasource.js +0 -0
- package/lib/app/helper_field/{date_field.js → 11-date_field.js} +1 -3
- package/lib/app/helper_field/15-local_temporal_field.js +100 -0
- package/lib/app/helper_field/20-decimal_field.js +105 -0
- package/lib/app/helper_field/big_int_field.js +7 -13
- package/lib/app/helper_field/fixed_decimal_field.js +44 -0
- package/lib/app/helper_field/local_date_field.js +39 -0
- package/lib/app/helper_field/local_date_time_field.js +39 -0
- package/lib/app/helper_field/local_time_field.js +39 -0
- package/lib/app/helper_field/mixed_field.js +73 -0
- package/lib/app/helper_field/schema_field.js +121 -35
- package/lib/app/helper_model/criteria.js +13 -0
- package/lib/app/helper_model/document.js +229 -0
- package/lib/app/helper_model/field_set.js +0 -0
- package/lib/app/helper_model/model.js +91 -18
- package/lib/app/model/alchemy_task_history_model.js +0 -0
- package/lib/bootstrap.js +0 -0
- package/lib/class/conduit.js +2 -2
- package/lib/class/datasource.js +80 -0
- package/lib/class/document.js +27 -0
- package/lib/class/field.js +110 -0
- package/lib/class/inode_file.js +0 -0
- package/lib/class/model.js +50 -28
- package/lib/class/path_evaluator.js +16 -9
- package/lib/class/route.js +4 -1
- package/lib/class/router.js +4 -2
- package/lib/class/schema_client.js +163 -20
- package/lib/class/session.js +0 -0
- package/lib/class/task.js +48 -2
- package/lib/class/task_service.js +37 -8
- package/lib/core/base.js +19 -4
- package/lib/core/client_alchemy.js +84 -1
- package/lib/core/middleware.js +27 -7
- package/lib/init/alchemy.js +4 -1
- package/lib/init/constants.js +23 -0
- package/lib/init/requirements.js +0 -0
- package/package.json +3 -3
|
@@ -183,7 +183,7 @@ Schema.addRelationCreator('HasOneChild', {internal: false, singular: tru
|
|
|
183
183
|
*
|
|
184
184
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
185
185
|
* @since 1.3.4
|
|
186
|
-
* @version 1.3.
|
|
186
|
+
* @version 1.3.21
|
|
187
187
|
*
|
|
188
188
|
* @param {String} alias
|
|
189
189
|
* @param {String} modelname
|
|
@@ -239,7 +239,7 @@ Schema.setMethod(function addAssociation(relation_type, relation_config, alias,
|
|
|
239
239
|
*
|
|
240
240
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
241
241
|
* @since 0.2.0
|
|
242
|
-
* @version 1.3.
|
|
242
|
+
* @version 1.3.21
|
|
243
243
|
*
|
|
244
244
|
* @param {Boolean} is_internal Is this internal (A remote record's id is stored inside this record)
|
|
245
245
|
* @param {String} alias
|
|
@@ -295,12 +295,25 @@ Schema.setMethod(function getAssociationArguments(is_internal, alias, model_name
|
|
|
295
295
|
options.local_key = options.localKey = local_key;
|
|
296
296
|
options.foreign_key = options.foreignKey = foreign_key;
|
|
297
297
|
|
|
298
|
-
|
|
299
|
-
|
|
298
|
+
let field_options = options.field_options;
|
|
299
|
+
|
|
300
|
+
if (!field_options) {
|
|
301
|
+
options.field_options = field_options = {};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (options.required != null) {
|
|
305
|
+
field_options.required = options.required;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
let result = {
|
|
309
|
+
alias : alias,
|
|
300
310
|
model_name,
|
|
301
|
-
modelName
|
|
302
|
-
options
|
|
311
|
+
modelName : model_name,
|
|
312
|
+
options : options,
|
|
313
|
+
constraints : options?.constraints,
|
|
303
314
|
};
|
|
315
|
+
|
|
316
|
+
return result;
|
|
304
317
|
});
|
|
305
318
|
|
|
306
319
|
/**
|
|
@@ -402,7 +415,7 @@ Schema.setMethod(function toDry() {
|
|
|
402
415
|
*
|
|
403
416
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
404
417
|
* @since 1.1.0
|
|
405
|
-
* @version 1.3.
|
|
418
|
+
* @version 1.3.21
|
|
406
419
|
*/
|
|
407
420
|
Schema.setMethod(function init() {
|
|
408
421
|
this.associations = {};
|
|
@@ -434,6 +447,15 @@ Schema.setMethod(function init() {
|
|
|
434
447
|
// Validation rules
|
|
435
448
|
this.rules = new Deck();
|
|
436
449
|
|
|
450
|
+
// Computed fields
|
|
451
|
+
this.computed_fields = {};
|
|
452
|
+
|
|
453
|
+
// How many computed fields there are
|
|
454
|
+
this.has_computed_fields = 0;
|
|
455
|
+
|
|
456
|
+
// How many computed fields require a recompute after find
|
|
457
|
+
this.has_recompute_after_find = 0;
|
|
458
|
+
|
|
437
459
|
// Behaviour count
|
|
438
460
|
this.has_behaviours = 0;
|
|
439
461
|
});
|
|
@@ -456,11 +478,17 @@ Schema.setMethod(function setName(name) {
|
|
|
456
478
|
*
|
|
457
479
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
458
480
|
* @since 0.2.0
|
|
459
|
-
* @version
|
|
481
|
+
* @version 1.3.21
|
|
460
482
|
*
|
|
461
483
|
* @param {Schema} schema
|
|
462
484
|
*/
|
|
463
485
|
Schema.setMethod(function setParent(schema) {
|
|
486
|
+
|
|
487
|
+
if (schema != this.parent) {
|
|
488
|
+
schema.has_computed_fields += this.has_computed_fields;
|
|
489
|
+
schema.has_recompute_after_find += this.has_recompute_after_find;
|
|
490
|
+
}
|
|
491
|
+
|
|
464
492
|
this.parent = schema;
|
|
465
493
|
});
|
|
466
494
|
|
|
@@ -631,18 +659,69 @@ Schema.setMethod(function getPrivateFields() {
|
|
|
631
659
|
return result;
|
|
632
660
|
});
|
|
633
661
|
|
|
662
|
+
/**
|
|
663
|
+
* Add a computed field to this schema:
|
|
664
|
+
* The value of these fields will be computed
|
|
665
|
+
* when the document is saved or loaded.
|
|
666
|
+
*
|
|
667
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
668
|
+
* @since 1.3.21
|
|
669
|
+
* @version 1.3.21
|
|
670
|
+
*
|
|
671
|
+
* @param {String} name
|
|
672
|
+
* @param {String} type
|
|
673
|
+
* @param {Object} options
|
|
674
|
+
*
|
|
675
|
+
* @return {Alchemy.Field.Field}
|
|
676
|
+
*/
|
|
677
|
+
Schema.setMethod(function addComputedField(name, type, options) {
|
|
678
|
+
|
|
679
|
+
if (arguments.length < 3 || !type || !options) {
|
|
680
|
+
throw new Error('Schema#addComputedField expects at least 3 arguments');
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
if (!options.compute_method) {
|
|
684
|
+
throw new Error('Schema#addComputedField expects a compute_method option');
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (!this.name || this.model_name != this.name) {
|
|
688
|
+
throw new Error('Computed fields can only be added to the root schema');
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
options.is_computed = true;
|
|
692
|
+
|
|
693
|
+
let result = this.addField(name, type, options);
|
|
694
|
+
|
|
695
|
+
this.computed_fields[name] = result;
|
|
696
|
+
this.has_computed_fields++;
|
|
697
|
+
|
|
698
|
+
if (this.parent) {
|
|
699
|
+
this.parent.has_computed_fields++;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (options.compute_after_find) {
|
|
703
|
+
this.has_recompute_after_find++;
|
|
704
|
+
|
|
705
|
+
if (this.parent) {
|
|
706
|
+
this.parent.has_recompute_after_find++;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
return result;
|
|
711
|
+
});
|
|
712
|
+
|
|
634
713
|
/**
|
|
635
714
|
* Add a field to this schema
|
|
636
715
|
*
|
|
637
716
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
638
717
|
* @since 0.2.0
|
|
639
|
-
* @version 1.3.
|
|
718
|
+
* @version 1.3.21
|
|
640
719
|
*
|
|
641
720
|
* @param {String} name
|
|
642
721
|
* @param {String} type
|
|
643
722
|
* @param {Object} options
|
|
644
723
|
*
|
|
645
|
-
* @return {
|
|
724
|
+
* @return {Alchemy.Field.Field}
|
|
646
725
|
*/
|
|
647
726
|
Schema.setMethod(function addField(name, type, options) {
|
|
648
727
|
|
|
@@ -693,6 +772,43 @@ Schema.setMethod(function addField(name, type, options) {
|
|
|
693
772
|
}
|
|
694
773
|
}
|
|
695
774
|
|
|
775
|
+
if (options.constraints) {
|
|
776
|
+
let required_fields = options.required_fields,
|
|
777
|
+
optional_fields = options.optional_fields,
|
|
778
|
+
value,
|
|
779
|
+
key;
|
|
780
|
+
|
|
781
|
+
if (!required_fields) {
|
|
782
|
+
required_fields = [];
|
|
783
|
+
} else {
|
|
784
|
+
required_fields = required_fields.slice(0);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
if (!optional_fields) {
|
|
788
|
+
optional_fields = [];
|
|
789
|
+
} else {
|
|
790
|
+
optional_fields = optional_fields.slice(0);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
for (key in options.constraints) {
|
|
794
|
+
value = options.constraints[key];
|
|
795
|
+
|
|
796
|
+
if (value && typeof value == 'object') {
|
|
797
|
+
if (value instanceof Classes.Alchemy.PathEvaluator) {
|
|
798
|
+
required_fields.push(value);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (required_fields.length) {
|
|
804
|
+
options.required_fields = required_fields;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
if (optional_fields.length) {
|
|
808
|
+
options.optional_fields = optional_fields;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
696
812
|
field = new FieldClass(this, name, options);
|
|
697
813
|
|
|
698
814
|
if (field.requires_translating) {
|
|
@@ -723,7 +839,7 @@ Schema.setMethod(function addField(name, type, options) {
|
|
|
723
839
|
*
|
|
724
840
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
725
841
|
* @since 0.2.0
|
|
726
|
-
* @version 1.
|
|
842
|
+
* @version 1.3.21
|
|
727
843
|
*
|
|
728
844
|
* @param {String} rule_name
|
|
729
845
|
* @param {Object} options
|
|
@@ -738,10 +854,6 @@ Schema.setMethod(function addRule(rule_name, options) {
|
|
|
738
854
|
throw new Error('Custom function validators not yet implemented');
|
|
739
855
|
}
|
|
740
856
|
|
|
741
|
-
if (!options) {
|
|
742
|
-
throw new Error('No valid options were found for the ' + rule_name + ' validator');
|
|
743
|
-
}
|
|
744
|
-
|
|
745
857
|
let constructor = alchemy.getValidatorClass(rule_name);
|
|
746
858
|
|
|
747
859
|
if (!constructor) {
|
|
@@ -818,26 +930,57 @@ Schema.setMethod(function getField(name) {
|
|
|
818
930
|
return this.getFieldChain(name).last();
|
|
819
931
|
});
|
|
820
932
|
|
|
933
|
+
/**
|
|
934
|
+
* Get an association by name
|
|
935
|
+
*
|
|
936
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
937
|
+
* @since 1.3.21
|
|
938
|
+
* @version 1.3.21
|
|
939
|
+
*
|
|
940
|
+
* @param {String} name
|
|
941
|
+
*
|
|
942
|
+
* @return {Object}
|
|
943
|
+
*/
|
|
944
|
+
Schema.setMethod(function getAssociation(name) {
|
|
945
|
+
return this.associations[name];
|
|
946
|
+
});
|
|
947
|
+
|
|
821
948
|
/**
|
|
822
949
|
* Get a field
|
|
823
950
|
*
|
|
824
951
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
825
952
|
* @since 0.2.0
|
|
826
|
-
* @version 1.2.
|
|
953
|
+
* @version 1.2.21
|
|
827
954
|
*
|
|
828
|
-
* @param {String} name
|
|
955
|
+
* @param {String|PathEvaluator} name
|
|
829
956
|
*
|
|
830
957
|
* @return {FieldType[]}
|
|
831
958
|
*/
|
|
832
959
|
Schema.setMethod(function getFieldChain(name) {
|
|
833
960
|
|
|
834
|
-
let result
|
|
961
|
+
let result,
|
|
962
|
+
pieces;
|
|
963
|
+
|
|
964
|
+
if (typeof name == 'object') {
|
|
965
|
+
|
|
966
|
+
if (name instanceof Classes.Alchemy.PathEvaluator) {
|
|
967
|
+
pieces = name.path;
|
|
968
|
+
|
|
969
|
+
if (pieces[0] == '$0') {
|
|
970
|
+
pieces = pieces.slice(1);
|
|
971
|
+
return this.root_schema.getFieldChain(pieces);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
} else if (Array.isArray(name)) {
|
|
975
|
+
pieces = name;
|
|
976
|
+
} else if (typeof name == 'string' && name.indexOf('.') > -1) {
|
|
977
|
+
pieces = name.split('.');
|
|
978
|
+
}
|
|
835
979
|
|
|
836
980
|
// Allow getting a nested field by a path
|
|
837
|
-
if (
|
|
981
|
+
if (pieces) {
|
|
838
982
|
|
|
839
983
|
let current = this,
|
|
840
|
-
pieces = name.split('.'),
|
|
841
984
|
max = pieces.length - 1,
|
|
842
985
|
i;
|
|
843
986
|
|
package/lib/class/session.js
CHANGED
|
File without changes
|
package/lib/class/task.js
CHANGED
|
@@ -489,7 +489,7 @@ Task.setMethod(function getParam(name) {
|
|
|
489
489
|
*
|
|
490
490
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
491
491
|
* @since 1.3.17
|
|
492
|
-
* @version 1.3.
|
|
492
|
+
* @version 1.3.21
|
|
493
493
|
*/
|
|
494
494
|
Task.setMethod(function waitUntilResumed() {
|
|
495
495
|
|
|
@@ -497,9 +497,55 @@ Task.setMethod(function waitUntilResumed() {
|
|
|
497
497
|
return false;
|
|
498
498
|
}
|
|
499
499
|
|
|
500
|
-
|
|
500
|
+
let paused = this[PAUSE_PLEDGE];
|
|
501
|
+
|
|
502
|
+
if (paused) {
|
|
503
|
+
return paused;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return this.waitIfTooBusy();
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Wait if the system is too busy
|
|
511
|
+
*
|
|
512
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
513
|
+
* @since 1.3.21
|
|
514
|
+
* @version 1.3.21
|
|
515
|
+
*/
|
|
516
|
+
Task.setMethod(function waitIfTooBusy() {
|
|
517
|
+
|
|
518
|
+
if (!alchemy.isTooBusy()) {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return doAsyncLoopUntilNotBusy(10);
|
|
501
523
|
});
|
|
502
524
|
|
|
525
|
+
/**
|
|
526
|
+
* Do a loop until the system is no longer busy
|
|
527
|
+
*
|
|
528
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
529
|
+
* @since 1.3.21
|
|
530
|
+
* @version 1.3.21
|
|
531
|
+
*/
|
|
532
|
+
async function doAsyncLoopUntilNotBusy(max_tries) {
|
|
533
|
+
|
|
534
|
+
let tries = 0;
|
|
535
|
+
|
|
536
|
+
if (!max_tries || max_tries < 1) {
|
|
537
|
+
max_tries = 5;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
do {
|
|
541
|
+
console.log('Waiting for system to be less busy', tries)
|
|
542
|
+
await Pledge.after(500);
|
|
543
|
+
tries++;
|
|
544
|
+
} while (tries < max_tries && alchemy.isTooBusy());
|
|
545
|
+
|
|
546
|
+
return true;
|
|
547
|
+
}
|
|
548
|
+
|
|
503
549
|
/**
|
|
504
550
|
* Report command progress
|
|
505
551
|
*
|
|
@@ -105,7 +105,7 @@ Service.setMethod(function checksumSystemSchedule(type_path, cron, settings) {
|
|
|
105
105
|
*
|
|
106
106
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
107
107
|
* @since 1.3.17
|
|
108
|
-
* @version 1.3.
|
|
108
|
+
* @version 1.3.20
|
|
109
109
|
*/
|
|
110
110
|
Service.setMethod(async function initSchedules() {
|
|
111
111
|
|
|
@@ -179,6 +179,7 @@ Service.setMethod(async function initSchedules() {
|
|
|
179
179
|
// If this checksum has already been seen, also remove it
|
|
180
180
|
if (existing_system_records.has(checksum)) {
|
|
181
181
|
await record.remove();
|
|
182
|
+
continue;
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
// Update the record
|
|
@@ -188,6 +189,8 @@ Service.setMethod(async function initSchedules() {
|
|
|
188
189
|
|
|
189
190
|
await record.save();
|
|
190
191
|
|
|
192
|
+
existing_system_records.set(checksum, record);
|
|
193
|
+
|
|
191
194
|
} catch (err) {
|
|
192
195
|
alchemy.registerError(err);
|
|
193
196
|
}
|
|
@@ -230,7 +233,7 @@ Service.setMethod(async function initSchedules() {
|
|
|
230
233
|
*
|
|
231
234
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
232
235
|
* @since 1.3.17
|
|
233
|
-
* @version 1.3.
|
|
236
|
+
* @version 1.3.21
|
|
234
237
|
*/
|
|
235
238
|
Service.setMethod(function createJanewayTaskMenu() {
|
|
236
239
|
|
|
@@ -266,6 +269,10 @@ Service.setMethod(function createJanewayTaskMenu() {
|
|
|
266
269
|
}
|
|
267
270
|
});
|
|
268
271
|
|
|
272
|
+
if (!running_task_menu) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
269
276
|
if (!running_task_menu.addItem) {
|
|
270
277
|
return running_task_menu.remove();
|
|
271
278
|
}
|
|
@@ -526,12 +533,15 @@ class TaskSchedules {
|
|
|
526
533
|
*
|
|
527
534
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
528
535
|
* @since 1.3.17
|
|
529
|
-
* @version 1.3.
|
|
536
|
+
* @version 1.3.20
|
|
530
537
|
*/
|
|
531
|
-
#startFromMenu(task_record) {
|
|
538
|
+
async #startFromMenu(task_record) {
|
|
532
539
|
console.log('Manually starting', task_record.type, 'task:', task_record);
|
|
533
540
|
let schedule = new TaskSchedule(this, null, task_record.settings, task_record);
|
|
534
|
-
schedule.startManually();
|
|
541
|
+
let task_instance = await schedule.startManually();
|
|
542
|
+
console.log(' -- Started:', task_instance);
|
|
543
|
+
|
|
544
|
+
return task_instance;
|
|
535
545
|
}
|
|
536
546
|
|
|
537
547
|
/**
|
|
@@ -579,6 +589,7 @@ class TaskSchedule {
|
|
|
579
589
|
janeway_menu_item = null;
|
|
580
590
|
|
|
581
591
|
#change_counter = 0;
|
|
592
|
+
#instance_pledge = null;
|
|
582
593
|
|
|
583
594
|
/**
|
|
584
595
|
* Initialize the instance
|
|
@@ -845,10 +856,22 @@ class TaskSchedule {
|
|
|
845
856
|
*
|
|
846
857
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
847
858
|
* @since 1.3.17
|
|
848
|
-
* @version 1.3.
|
|
859
|
+
* @version 1.3.20
|
|
860
|
+
*
|
|
861
|
+
* @return {Task}
|
|
849
862
|
*/
|
|
850
863
|
async startManually() {
|
|
851
|
-
|
|
864
|
+
|
|
865
|
+
if (this.is_running) {
|
|
866
|
+
return false;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
let pledge = new Pledge();
|
|
870
|
+
this.#instance_pledge = pledge;
|
|
871
|
+
|
|
872
|
+
this.#run(true);
|
|
873
|
+
|
|
874
|
+
return pledge;
|
|
852
875
|
}
|
|
853
876
|
|
|
854
877
|
/**
|
|
@@ -856,7 +879,7 @@ class TaskSchedule {
|
|
|
856
879
|
*
|
|
857
880
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
858
881
|
* @since 1.3.17
|
|
859
|
-
* @version 1.3.
|
|
882
|
+
* @version 1.3.20
|
|
860
883
|
*/
|
|
861
884
|
async #run(started_manually = false) {
|
|
862
885
|
|
|
@@ -889,6 +912,12 @@ class TaskSchedule {
|
|
|
889
912
|
if (started_manually || await this.ownsScheduledTask()) {
|
|
890
913
|
let instance = this.createInstance();
|
|
891
914
|
this.task_instance = instance;
|
|
915
|
+
|
|
916
|
+
if (this.#instance_pledge) {
|
|
917
|
+
this.#instance_pledge.resolve(instance);
|
|
918
|
+
this.#instance_pledge = null;
|
|
919
|
+
}
|
|
920
|
+
|
|
892
921
|
await instance.start();
|
|
893
922
|
}
|
|
894
923
|
} catch (err) {
|
package/lib/core/base.js
CHANGED
|
@@ -471,7 +471,11 @@ Base.setMethod(function getClassPathAfter(after) {
|
|
|
471
471
|
*
|
|
472
472
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
473
473
|
* @since 1.0.0
|
|
474
|
-
* @version 1.
|
|
474
|
+
* @version 1.3.20
|
|
475
|
+
*
|
|
476
|
+
* @param {String} name The name of the method to call
|
|
477
|
+
* @param {Array} args The arguments to pass
|
|
478
|
+
* @param {Function} next The callback to call afterwards
|
|
475
479
|
*/
|
|
476
480
|
Base.setMethod(function callOrNext(name, args, next) {
|
|
477
481
|
|
|
@@ -480,14 +484,25 @@ Base.setMethod(function callOrNext(name, args, next) {
|
|
|
480
484
|
args = [];
|
|
481
485
|
}
|
|
482
486
|
|
|
483
|
-
|
|
487
|
+
const fnc = this[name];
|
|
488
|
+
|
|
489
|
+
if (typeof fnc == 'function') {
|
|
490
|
+
|
|
491
|
+
let has_callback = false,
|
|
492
|
+
promise;
|
|
484
493
|
|
|
485
|
-
if (next) {
|
|
494
|
+
if (next && fnc.length > args.length) {
|
|
495
|
+
has_callback = true;
|
|
486
496
|
args.push(next);
|
|
487
497
|
}
|
|
488
498
|
|
|
489
499
|
try {
|
|
490
|
-
this[name].apply(this, args);
|
|
500
|
+
promise = this[name].apply(this, args);
|
|
501
|
+
|
|
502
|
+
if (!has_callback) {
|
|
503
|
+
Pledge.done(promise, next);
|
|
504
|
+
}
|
|
505
|
+
|
|
491
506
|
} catch (err) {
|
|
492
507
|
next(err);
|
|
493
508
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
7
7
|
* @since 0.1.0
|
|
8
|
-
* @version 1.3.
|
|
8
|
+
* @version 1.3.21
|
|
9
9
|
*/
|
|
10
10
|
var Alchemy = Function.inherits('Alchemy.Client.Base', function Alchemy() {
|
|
11
11
|
|
|
@@ -24,6 +24,9 @@ var Alchemy = Function.inherits('Alchemy.Client.Base', function Alchemy() {
|
|
|
24
24
|
this.sent_subscriptions = [];
|
|
25
25
|
|
|
26
26
|
this.distinct_problems = new Map();
|
|
27
|
+
|
|
28
|
+
// Custom handlers
|
|
29
|
+
this.custom_handlers = new Map();
|
|
27
30
|
});
|
|
28
31
|
|
|
29
32
|
/**
|
|
@@ -196,6 +199,79 @@ Alchemy.setMethod(function distinctProblem(id, message, options = {}) {
|
|
|
196
199
|
return entry;
|
|
197
200
|
});
|
|
198
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Register a custom handler
|
|
204
|
+
*
|
|
205
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
206
|
+
* @since 1.3.21
|
|
207
|
+
* @version 1.3.21
|
|
208
|
+
*
|
|
209
|
+
* @param {string|symbol} type
|
|
210
|
+
* @param {Function} callback
|
|
211
|
+
* @param {Number} weight
|
|
212
|
+
*/
|
|
213
|
+
Alchemy.setMethod(function registerCustomHandler(type, callback, weight) {
|
|
214
|
+
|
|
215
|
+
if (typeof callback != 'function') {
|
|
216
|
+
throw new Error('Custom handler needs to be a function');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
let handlers = this.custom_handlers.get(type);
|
|
220
|
+
|
|
221
|
+
if (!handlers) {
|
|
222
|
+
handlers = new Deck();
|
|
223
|
+
this.custom_handlers.set(type, handlers);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (weight == null) {
|
|
227
|
+
weight = 10;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
handlers.push(callback, weight);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get the highest priority custom handler of the given type
|
|
235
|
+
*
|
|
236
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
237
|
+
* @since 1.3.21
|
|
238
|
+
* @version 1.3.21
|
|
239
|
+
*
|
|
240
|
+
* @param {string|symbol} type
|
|
241
|
+
*
|
|
242
|
+
* @return {Function}
|
|
243
|
+
*/
|
|
244
|
+
Alchemy.setMethod(function getCustomHandler(type) {
|
|
245
|
+
|
|
246
|
+
let handlers = this.custom_handlers.get(type);
|
|
247
|
+
|
|
248
|
+
if (handlers) {
|
|
249
|
+
return handlers.first();
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get all the custom handlers of the given type
|
|
255
|
+
*
|
|
256
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
257
|
+
* @since 1.3.21
|
|
258
|
+
* @version 1.3.21
|
|
259
|
+
*
|
|
260
|
+
* @param {string|symbol} type
|
|
261
|
+
*
|
|
262
|
+
* @return {Function[]}
|
|
263
|
+
*/
|
|
264
|
+
Alchemy.setMethod(function getAllCustomHandlers(type) {
|
|
265
|
+
|
|
266
|
+
let handlers = this.custom_handlers.get(type);
|
|
267
|
+
|
|
268
|
+
if (handlers) {
|
|
269
|
+
return [...handlers];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return [];
|
|
273
|
+
});
|
|
274
|
+
|
|
199
275
|
/**
|
|
200
276
|
* Actually print a log message
|
|
201
277
|
*
|
|
@@ -635,6 +711,13 @@ function getRoutesDict() {
|
|
|
635
711
|
|
|
636
712
|
// From here on, only client-side code is added
|
|
637
713
|
if (Blast.isBrowser) {
|
|
714
|
+
window.LocalDateTime = Blast.Classes.Develry.LocalDateTime;
|
|
715
|
+
window.LocalDate = Blast.Classes.Develry.LocalDate;
|
|
716
|
+
window.LocalTime = Blast.Classes.Develry.LocalTime;
|
|
717
|
+
window.Decimal = Blast.Classes.Develry.Decimal;
|
|
718
|
+
window.MutableDecimal = Blast.Classes.Develry.MutableDecimal;
|
|
719
|
+
window.FixedDecimal = Blast.Classes.Develry.FixedDecimal;
|
|
720
|
+
window.MutableFixedDecimal = Blast.Classes.Develry.MutableFixedDecimal;
|
|
638
721
|
window.alchemy = new Alchemy();
|
|
639
722
|
} else {
|
|
640
723
|
return;
|
package/lib/core/middleware.js
CHANGED
|
@@ -426,13 +426,29 @@ Alchemy.setMethod(function minifyScript(path, options, callback) {
|
|
|
426
426
|
|
|
427
427
|
let minify_options = {
|
|
428
428
|
compress: {
|
|
429
|
-
|
|
430
|
-
|
|
429
|
+
// Keep all function arguments
|
|
430
|
+
keep_fargs : true,
|
|
431
|
+
|
|
432
|
+
// Keep function names
|
|
433
|
+
keep_fnames : true,
|
|
434
|
+
|
|
435
|
+
// Keep classnames
|
|
431
436
|
keep_classnames : true,
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
437
|
+
|
|
438
|
+
// Do not hoist function declarations
|
|
439
|
+
hoist_funs : false,
|
|
440
|
+
|
|
441
|
+
// Only drop console calls when not debugging
|
|
442
|
+
drop_console : !alchemy.settings.debug,
|
|
443
|
+
|
|
444
|
+
// Remove dead code
|
|
445
|
+
dead_code : true,
|
|
446
|
+
|
|
447
|
+
// Remove symbol names
|
|
448
|
+
unsafe_symbols : true,
|
|
449
|
+
|
|
450
|
+
// Provide it some info on global definitions
|
|
451
|
+
global_defs : {
|
|
436
452
|
'__BLAST_IS_NODE' : false,
|
|
437
453
|
'__BLAST_IS_BROWSER' : true
|
|
438
454
|
}
|
|
@@ -440,7 +456,11 @@ Alchemy.setMethod(function minifyScript(path, options, callback) {
|
|
|
440
456
|
mangle: {
|
|
441
457
|
keep_fnames : true,
|
|
442
458
|
keep_classnames : true,
|
|
443
|
-
}
|
|
459
|
+
},
|
|
460
|
+
output: {
|
|
461
|
+
// Do not wrap functions that are arguments in parenthesis
|
|
462
|
+
wrap_func_args : false,
|
|
463
|
+
},
|
|
444
464
|
};
|
|
445
465
|
|
|
446
466
|
if (alchemy.settings.debug && alchemy.settings.source_map) {
|
package/lib/init/alchemy.js
CHANGED
|
@@ -19,7 +19,7 @@ var shared_objects = {},
|
|
|
19
19
|
*
|
|
20
20
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
21
21
|
* @since 0.0.1
|
|
22
|
-
* @version 1.3.
|
|
22
|
+
* @version 1.3.21
|
|
23
23
|
*/
|
|
24
24
|
global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
|
|
25
25
|
|
|
@@ -105,6 +105,9 @@ global.Alchemy = Function.inherits('Informer', 'Alchemy', function Alchemy() {
|
|
|
105
105
|
// Distinct problems
|
|
106
106
|
this.distinct_problems = new Map();
|
|
107
107
|
|
|
108
|
+
// Custom handlers
|
|
109
|
+
this.custom_handlers = new Map();
|
|
110
|
+
|
|
108
111
|
// Load the settings
|
|
109
112
|
this.loadSettings();
|
|
110
113
|
|