alchemymvc 1.3.21 → 1.4.0-alpha.1
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/LICENSE +1 -1
- package/README.md +3 -3
- package/lib/app/behaviour/publishable_behaviour.js +5 -5
- package/lib/app/behaviour/revision_behaviour.js +10 -10
- package/lib/app/behaviour/sluggable_behaviour.js +14 -14
- package/lib/app/conduit/electron_conduit.js +9 -9
- package/lib/app/conduit/http_conduit.js +13 -13
- package/lib/app/conduit/loopback_conduit.js +15 -15
- package/lib/app/conduit/socket_conduit.js +43 -43
- package/lib/app/config/routes.js +26 -0
- package/lib/app/controller/00-default_app_controller.js +21 -0
- package/lib/app/controller/alchemy_info_controller.js +12 -12
- package/lib/app/datasource/mongo_datasource.js +16 -16
- package/lib/app/element/00-default_app_element.js +19 -0
- package/lib/app/element/time_ago.js +5 -5
- package/lib/app/helper/00-default_app_helper.js +11 -0
- package/lib/app/helper/alchemy_helper.js +22 -22
- package/lib/app/helper/backed_map.js +1 -1
- package/lib/app/helper/breadcrumb.js +10 -10
- package/lib/app/helper/client_collection.js +3 -3
- package/lib/app/helper/cron.js +29 -29
- package/lib/app/helper/enum_values.js +6 -6
- package/lib/app/helper/pagination_helper.js +36 -36
- package/lib/app/helper/router_helper.js +35 -35
- package/lib/app/helper/socket_helper.js +57 -57
- package/lib/app/helper/syncable.js +84 -59
- package/lib/app/helper_component/paginate_component.js +9 -9
- package/lib/app/helper_controller/component.js +1 -1
- package/lib/app/helper_controller/conduit.js +31 -31
- package/lib/app/helper_controller/controller.js +54 -39
- package/lib/app/helper_datasource/00-nosql_datasource.js +624 -70
- package/lib/app/helper_datasource/05-fallback_datasource.js +10 -10
- package/lib/app/helper_datasource/idb_datasource.js +6 -6
- package/lib/app/helper_datasource/indexed_db.js +22 -22
- package/lib/app/helper_datasource/remote_datasource.js +5 -5
- package/lib/app/helper_error/http_error.js +4 -4
- package/lib/app/helper_error/model_error.js +2 -2
- package/lib/app/helper_error/validation_error.js +12 -12
- package/lib/app/helper_field/00-objectid_field.js +7 -7
- package/lib/app/helper_field/05-string_field.js +16 -12
- package/lib/app/helper_field/06-text_field.js +2 -4
- package/lib/app/helper_field/10-number_field.js +9 -12
- package/lib/app/helper_field/11-date_field.js +15 -15
- package/lib/app/helper_field/15-local_temporal_field.js +10 -10
- package/lib/app/helper_field/20-decimal_field.js +8 -9
- package/lib/app/helper_field/belongsto_field.js +1 -1
- package/lib/app/helper_field/big_int_field.js +8 -8
- package/lib/app/helper_field/boolean_field.js +9 -11
- package/lib/app/helper_field/datetime_field.js +3 -3
- package/lib/app/helper_field/enum_field.js +13 -8
- package/lib/app/helper_field/fixed_decimal_field.js +6 -7
- package/lib/app/helper_field/geopoint_field.js +9 -10
- package/lib/app/helper_field/habtm_field.js +3 -3
- package/lib/app/helper_field/hasoneparent_field.js +1 -1
- package/lib/app/helper_field/html_field.js +2 -4
- package/lib/app/helper_field/integer_field.js +8 -11
- package/lib/app/helper_field/local_date_field.js +5 -5
- package/lib/app/helper_field/local_date_time_field.js +5 -5
- package/lib/app/helper_field/local_time_field.js +5 -5
- package/lib/app/helper_field/mixed_field.js +5 -5
- package/lib/app/helper_field/object_field.js +8 -8
- package/lib/app/helper_field/password_field.js +3 -3
- package/lib/app/helper_field/regexp_field.js +7 -9
- package/lib/app/helper_field/schema_field.js +91 -88
- package/lib/app/helper_field/settings_field.js +92 -0
- package/lib/app/helper_field/time_field.js +6 -6
- package/lib/app/helper_field/url_field.js +2 -4
- package/lib/app/helper_model/00-base_criteria.js +662 -0
- package/lib/app/helper_model/05-criteria_expressions.js +605 -0
- package/lib/app/helper_model/10-model_criteria.js +1182 -0
- package/lib/app/helper_model/data_provider.js +2 -2
- package/lib/app/helper_model/document.js +103 -92
- package/lib/app/helper_model/document_list.js +14 -14
- package/lib/app/helper_model/field_config.js +11 -11
- package/lib/app/helper_model/field_set.js +17 -17
- package/lib/app/helper_model/model.js +203 -124
- package/lib/app/helper_model/remote_data_provider.js +2 -2
- package/lib/app/helper_validator/00_validator.js +16 -16
- package/lib/app/helper_validator/not_empty_validator.js +9 -9
- package/lib/app/model/00-default_app_model.js +18 -0
- package/lib/app/model/05-system_model.js +27 -0
- package/lib/app/model/{alchemy_migration_model.js → system_migration_model.js} +4 -4
- package/lib/app/model/system_setting_model.js +154 -0
- package/lib/app/model/{alchemy_task_history_model.js → system_task_history_model.js} +7 -7
- package/lib/app/model/{alchemy_task_model.js → system_task_model.js} +11 -11
- package/lib/bootstrap.js +22 -312
- package/lib/class/accumulator.js +5 -5
- package/lib/class/behaviour.js +5 -5
- package/lib/class/component.js +3 -3
- package/lib/class/conduit.js +203 -163
- package/lib/class/controller.js +42 -42
- package/lib/class/datasource.js +74 -79
- package/lib/class/document.js +74 -95
- package/lib/class/document_list.js +5 -5
- package/lib/class/element.js +17 -17
- package/lib/class/error.js +3 -3
- package/lib/class/field.js +169 -91
- package/lib/class/field_value.js +6 -6
- package/lib/class/helper.js +3 -3
- package/lib/class/inode.js +17 -17
- package/lib/class/inode_dir.js +12 -12
- package/lib/class/inode_file.js +50 -25
- package/lib/class/inode_list.js +4 -4
- package/lib/class/migration.js +4 -4
- package/lib/class/model.js +182 -168
- package/lib/class/path_definition.js +22 -22
- package/lib/class/path_evaluator.js +5 -5
- package/lib/class/path_param_definition.js +7 -7
- package/lib/class/plugin.js +312 -0
- package/lib/class/postponement.js +29 -29
- package/lib/class/reciprocal.js +8 -8
- package/lib/class/route.js +33 -33
- package/lib/class/router.js +73 -73
- package/lib/class/schema.js +21 -21
- package/lib/class/schema_client.js +73 -67
- package/lib/class/session.js +63 -29
- package/lib/class/session_scene.js +4 -4
- package/lib/class/sitemap.js +16 -16
- package/lib/class/task.js +39 -39
- package/lib/class/task_service.js +43 -47
- package/lib/{init → core}/alchemy.js +413 -374
- package/lib/{init/functions.js → core/alchemy_functions.js} +171 -108
- package/lib/core/alchemy_load_functions.js +715 -0
- package/lib/core/base.js +50 -62
- package/lib/core/client_alchemy.js +144 -152
- package/lib/core/client_base.js +39 -52
- package/lib/core/discovery.js +16 -18
- package/lib/core/middleware.js +54 -43
- package/lib/core/{routing.js → prefix.js} +14 -16
- package/lib/core/setting.js +1684 -0
- package/lib/core/stage.js +758 -0
- package/lib/scripts/create_constants.js +119 -0
- package/lib/{init/languages.js → scripts/create_languages.js} +5 -5
- package/lib/scripts/create_settings.js +449 -0
- package/lib/scripts/create_shared_constants.js +95 -0
- package/lib/scripts/create_stages.js +55 -0
- package/lib/scripts/init_alchemy.js +51 -0
- package/lib/{init/requirements.js → scripts/preload_modules.js} +15 -2
- package/lib/scripts/setup_devwatch.js +238 -0
- package/lib/stages/00-load_core.js +342 -0
- package/lib/stages/05-load_app.js +57 -0
- package/lib/stages/10-datasource.js +61 -0
- package/lib/stages/15-tasks.js +27 -0
- package/lib/stages/20-settings.js +68 -0
- package/lib/stages/50-routes.js +218 -0
- package/lib/stages/90-server.js +347 -0
- package/package.json +5 -7
- package/lib/app/helper_model/criteria.js +0 -2294
- package/lib/app/helper_model/db_query.js +0 -1488
- package/lib/app/routes.js +0 -11
- package/lib/core/socket.js +0 -171
- package/lib/init/constants.js +0 -158
- package/lib/init/devwatch.js +0 -238
- package/lib/init/load_functions.js +0 -973
- package/lib/stages.js +0 -513
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
const STATUS = Symbol('status'),
|
|
2
|
+
STATUS_PLEDGE = Symbol('status_pledge'),
|
|
3
|
+
MAIN_PLEDGE = Symbol('main_pledge'),
|
|
4
|
+
PRE_STATUS = 'pre',
|
|
5
|
+
MAIN_STATUS = 'main',
|
|
6
|
+
CHILD_STATUS = 'children',
|
|
7
|
+
POST_STATUS = 'post';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The Stage class
|
|
11
|
+
*
|
|
12
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
13
|
+
* @since 1.4.0
|
|
14
|
+
* @version 1.4.0
|
|
15
|
+
*
|
|
16
|
+
* @param {string} name
|
|
17
|
+
* @param {Alchemy.Stages.Stages} parent
|
|
18
|
+
*/
|
|
19
|
+
const Stage = Function.inherits('Alchemy.Base', 'Alchemy.Stages', function Stage(name, parent) {
|
|
20
|
+
|
|
21
|
+
// The name of this stage
|
|
22
|
+
this.name = name;
|
|
23
|
+
|
|
24
|
+
// The path
|
|
25
|
+
this.id = parent ? parent.id + '.' + name : name;
|
|
26
|
+
|
|
27
|
+
// The parent Stage (if any)
|
|
28
|
+
this.parent = parent;
|
|
29
|
+
|
|
30
|
+
// The root stage
|
|
31
|
+
this.root_stage = parent ? parent.root_stage : this;
|
|
32
|
+
|
|
33
|
+
// The current status
|
|
34
|
+
this[STATUS] = null;
|
|
35
|
+
|
|
36
|
+
// The main pledge
|
|
37
|
+
this[MAIN_PLEDGE] = new Pledge.Swift();
|
|
38
|
+
|
|
39
|
+
// The dependencies of this stage
|
|
40
|
+
this.depends_on = null;
|
|
41
|
+
|
|
42
|
+
// Pre-tasks
|
|
43
|
+
this.pre_tasks = new Map();
|
|
44
|
+
|
|
45
|
+
// Main tasks
|
|
46
|
+
this.main_tasks = new Map();
|
|
47
|
+
|
|
48
|
+
// Child stages
|
|
49
|
+
this.child_stages = new Map();
|
|
50
|
+
|
|
51
|
+
// Post-tasks
|
|
52
|
+
this.post_tasks = new Map();
|
|
53
|
+
|
|
54
|
+
// When this started
|
|
55
|
+
this.started = null;
|
|
56
|
+
|
|
57
|
+
// When this ended
|
|
58
|
+
this.ended = null;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Is this the root stage?
|
|
63
|
+
*
|
|
64
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
65
|
+
* @since 1.4.0
|
|
66
|
+
* @version 1.4.0
|
|
67
|
+
*/
|
|
68
|
+
Stage.setProperty(function is_root() {
|
|
69
|
+
return this.root_stage === this;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get the main pledge
|
|
74
|
+
*
|
|
75
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
76
|
+
* @since 1.4.0
|
|
77
|
+
* @version 1.4.0
|
|
78
|
+
*/
|
|
79
|
+
Stage.setProperty(function pledge() {
|
|
80
|
+
return this[MAIN_PLEDGE];
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Add a dependency to this stage
|
|
85
|
+
*
|
|
86
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
87
|
+
* @since 1.4.0
|
|
88
|
+
* @version 1.4.0
|
|
89
|
+
*
|
|
90
|
+
* @param {string[]} stage_ids The id of the stage it depends on.
|
|
91
|
+
*
|
|
92
|
+
* @return {Alchemy.Stages.Stage}
|
|
93
|
+
*/
|
|
94
|
+
Stage.setMethod(function dependsOn(stage_ids) {
|
|
95
|
+
|
|
96
|
+
if (!this.depends_on) {
|
|
97
|
+
this.depends_on = [];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
stage_ids = Array.cast(stage_ids);
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < stage_ids.length; i++) {
|
|
103
|
+
let id = stage_ids[i];
|
|
104
|
+
|
|
105
|
+
if (typeof id != 'string') {
|
|
106
|
+
throw new Error('Stage id should be a string');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (!this.is_root && !id.startsWith(this.root_stage.name)) {
|
|
110
|
+
id = this.root_stage.name + '.' + id;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
stage_ids[i] = id;
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.depends_on.push(...stage_ids);
|
|
118
|
+
|
|
119
|
+
// Push these dependencies to the already existing children
|
|
120
|
+
for (let [name, stage] of this.child_stages) {
|
|
121
|
+
stage.dependsOn(stage_ids);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return this;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Add a new child stage
|
|
129
|
+
*
|
|
130
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
131
|
+
* @since 1.4.0
|
|
132
|
+
* @version 1.4.0
|
|
133
|
+
*
|
|
134
|
+
* @param {string} name Name of the stage
|
|
135
|
+
* @param {Function} fnc The function to execute as a main task
|
|
136
|
+
*
|
|
137
|
+
* @return {Alchemy.Stages.Stage}
|
|
138
|
+
*/
|
|
139
|
+
Stage.setMethod(function createStage(name, fnc) {
|
|
140
|
+
|
|
141
|
+
if (this.child_stages.has(name)) {
|
|
142
|
+
throw new Error('Stage "' + name + '" already exists');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
let stage = new Stage(name, this);
|
|
146
|
+
|
|
147
|
+
if (this.depends_on?.length) {
|
|
148
|
+
stage.dependsOn(this.depends_on);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.child_stages.set(name, stage);
|
|
152
|
+
|
|
153
|
+
if (fnc) {
|
|
154
|
+
stage.addMainTask(fnc);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return stage;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Add a certain task
|
|
162
|
+
*
|
|
163
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
164
|
+
* @since 1.4.0
|
|
165
|
+
* @version 1.4.0
|
|
166
|
+
*
|
|
167
|
+
* @param {string} type
|
|
168
|
+
* @param {Function} fnc
|
|
169
|
+
*/
|
|
170
|
+
Stage.setMethod(function _addTask(type, fnc) {
|
|
171
|
+
|
|
172
|
+
let task_map = this[type];
|
|
173
|
+
|
|
174
|
+
// First see if this type has already been started
|
|
175
|
+
let pledge = task_map[STATUS_PLEDGE];
|
|
176
|
+
|
|
177
|
+
// If it has, we can already start the task,
|
|
178
|
+
// but we have to set a new pledge.
|
|
179
|
+
if (pledge) {
|
|
180
|
+
let new_pledge = new Pledge.Swift();
|
|
181
|
+
task_map[STATUS_PLEDGE] = new_pledge;
|
|
182
|
+
|
|
183
|
+
let task_result;
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
task_result = fnc();
|
|
187
|
+
} catch (err) {
|
|
188
|
+
new_pledge.reject(err);
|
|
189
|
+
task_map.set(fnc, err);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!task_result) {
|
|
194
|
+
task_result = true;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
task_map.set(fnc, task_result);
|
|
198
|
+
} else {
|
|
199
|
+
task_map.set(fnc, null);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Do the given type of tasks
|
|
205
|
+
*
|
|
206
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
207
|
+
* @since 1.4.0
|
|
208
|
+
* @version 1.4.0
|
|
209
|
+
*
|
|
210
|
+
* @param {string} type
|
|
211
|
+
*/
|
|
212
|
+
Stage.setMethod(function _doTasks(type) {
|
|
213
|
+
|
|
214
|
+
let task_map = this[type];
|
|
215
|
+
|
|
216
|
+
let pledge = new Pledge.Swift();
|
|
217
|
+
task_map[STATUS_PLEDGE] = pledge;
|
|
218
|
+
|
|
219
|
+
let tasks = [];
|
|
220
|
+
let errors = [];
|
|
221
|
+
|
|
222
|
+
for (let [fnc, value] of task_map) {
|
|
223
|
+
|
|
224
|
+
// It already has a value: it has already been executed
|
|
225
|
+
if (value) {
|
|
226
|
+
if (Pledge.isThenable(value)) {
|
|
227
|
+
tasks.push(value);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// If needs to be executed
|
|
234
|
+
try {
|
|
235
|
+
value = fnc();
|
|
236
|
+
|
|
237
|
+
if (!value) {
|
|
238
|
+
value = true;
|
|
239
|
+
} else if (Pledge.isThenable(value)) {
|
|
240
|
+
tasks.push(value);
|
|
241
|
+
|
|
242
|
+
Pledge.cast(value).done((err, result) => {
|
|
243
|
+
task_map.set(fnc, result || err || true);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
task_map.set(fnc, value);
|
|
248
|
+
|
|
249
|
+
} catch (err) {
|
|
250
|
+
errors.push(err);
|
|
251
|
+
task_map.set(fnc, err);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (!tasks.length && !errors.length) {
|
|
256
|
+
pledge.resolve(true);
|
|
257
|
+
return pledge;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (errors.length) {
|
|
261
|
+
pledge.reject(errors[0]);
|
|
262
|
+
return pledge;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
Function.parallel(tasks).done((err) => {
|
|
266
|
+
if (err) {
|
|
267
|
+
pledge.reject(err);
|
|
268
|
+
} else {
|
|
269
|
+
pledge.resolve(this._doTasks(type));
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
return pledge;
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Add a pre-task to this stage:
|
|
278
|
+
* This task will be performed before the main tasks of this stage.
|
|
279
|
+
*
|
|
280
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
281
|
+
* @since 1.4.0
|
|
282
|
+
* @version 1.4.0
|
|
283
|
+
*
|
|
284
|
+
* @param {Function} fnc
|
|
285
|
+
*/
|
|
286
|
+
Stage.setMethod(function addPreTask(fnc) {
|
|
287
|
+
this._addTask('pre_tasks', fnc);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Add a main task to this stage:
|
|
292
|
+
* This task will be performed after the pre-tasks of this stage.
|
|
293
|
+
*
|
|
294
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
295
|
+
* @since 1.4.0
|
|
296
|
+
* @version 1.4.0
|
|
297
|
+
*
|
|
298
|
+
* @param {Function} fnc
|
|
299
|
+
*/
|
|
300
|
+
Stage.setMethod(function addMainTask(fnc) {
|
|
301
|
+
this._addTask('main_tasks', fnc);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Add a post task to this stage:
|
|
306
|
+
* This task will be performed after the main-tasks
|
|
307
|
+
* and the child stages of this stage.
|
|
308
|
+
*
|
|
309
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
310
|
+
* @since 1.4.0
|
|
311
|
+
* @version 1.4.0
|
|
312
|
+
*
|
|
313
|
+
* @param {Function} fnc
|
|
314
|
+
*/
|
|
315
|
+
Stage.setMethod(function addPostTask(fnc) {
|
|
316
|
+
this._addTask('post_tasks', fnc);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Have all the child stages finished?
|
|
321
|
+
*
|
|
322
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
323
|
+
* @since 1.4.0
|
|
324
|
+
* @version 1.4.0
|
|
325
|
+
*/
|
|
326
|
+
Stage.setMethod(function hasFinishedAllChildStages() {
|
|
327
|
+
|
|
328
|
+
if (this.child_stages.size == 0) {
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
for (let [name, stage] of this.child_stages) {
|
|
333
|
+
if (!stage.ended) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return true;
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Get a child stage by its path/id
|
|
343
|
+
*
|
|
344
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
345
|
+
* @since 1.4.0
|
|
346
|
+
* @version 1.4.0
|
|
347
|
+
*
|
|
348
|
+
* @param {string} id
|
|
349
|
+
*/
|
|
350
|
+
Stage.setMethod(function getStage(id) {
|
|
351
|
+
|
|
352
|
+
if (!id) {
|
|
353
|
+
throw new Error('Unable to get stage without id');
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
let parts = id.split('.');
|
|
357
|
+
|
|
358
|
+
if (this.is_root && parts[0] == this.name) {
|
|
359
|
+
parts.shift();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
let current = this;
|
|
363
|
+
|
|
364
|
+
while (parts.length) {
|
|
365
|
+
let part = parts.shift();
|
|
366
|
+
|
|
367
|
+
current = current.child_stages.get(part);
|
|
368
|
+
|
|
369
|
+
if (!current) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return current;
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Wait for the given child stages (without starting them)
|
|
379
|
+
*
|
|
380
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
381
|
+
* @since 1.4.0
|
|
382
|
+
* @version 1.4.0
|
|
383
|
+
*
|
|
384
|
+
* @param {string[]} stages
|
|
385
|
+
* @param {Function} callback
|
|
386
|
+
*/
|
|
387
|
+
Stage.setMethod(function afterStages(stages, callback) {
|
|
388
|
+
|
|
389
|
+
stages = Array.cast(stages);
|
|
390
|
+
|
|
391
|
+
let tasks = [];
|
|
392
|
+
|
|
393
|
+
for (let id of stages) {
|
|
394
|
+
let stage = this.getStage(id);
|
|
395
|
+
|
|
396
|
+
if (!stage) {
|
|
397
|
+
throw new Error('Child stage "' + id + '" not found');
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (stage.ended) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
tasks.push(async (next) => {
|
|
405
|
+
await stage.pledge;
|
|
406
|
+
next();
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return Function.series(tasks, callback);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Recursively get all the child-stages (including this one)
|
|
415
|
+
*
|
|
416
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
417
|
+
* @since 1.4.0
|
|
418
|
+
* @version 1.4.0
|
|
419
|
+
*
|
|
420
|
+
* @param {string[]} filter
|
|
421
|
+
*
|
|
422
|
+
* @return {Alchemy.Stage.Stage[]}
|
|
423
|
+
*/
|
|
424
|
+
Stage.setMethod(function getFlattenedStages(filter) {
|
|
425
|
+
|
|
426
|
+
let result = [];
|
|
427
|
+
|
|
428
|
+
result.push(this);
|
|
429
|
+
|
|
430
|
+
// If the filter is given, split each entry up into parts
|
|
431
|
+
if (filter) {
|
|
432
|
+
filter = Array.cast(filter);
|
|
433
|
+
|
|
434
|
+
for (let i = 0; i < filter.length; i++) {
|
|
435
|
+
let parts = filter[i].split('.');
|
|
436
|
+
|
|
437
|
+
if (this.is_root && parts[0] == this.name) {
|
|
438
|
+
parts.shift();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
filter[i] = parts;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
for (let [name, stage] of this.child_stages) {
|
|
446
|
+
|
|
447
|
+
let sub_filter;
|
|
448
|
+
|
|
449
|
+
if (filter) {
|
|
450
|
+
let matches_filter = false;
|
|
451
|
+
|
|
452
|
+
sub_filter = [];
|
|
453
|
+
|
|
454
|
+
for (let i = 0; i < filter.length; i++) {
|
|
455
|
+
let parts = filter[i];
|
|
456
|
+
|
|
457
|
+
if (parts[0] == name) {
|
|
458
|
+
matches_filter = true;
|
|
459
|
+
|
|
460
|
+
// Create a clone of the parts array
|
|
461
|
+
parts = parts.slice(0);
|
|
462
|
+
|
|
463
|
+
// Remove the first part
|
|
464
|
+
parts.shift();
|
|
465
|
+
|
|
466
|
+
if (parts.length) {
|
|
467
|
+
// And add it to the sub filter
|
|
468
|
+
sub_filter.push(parts);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (!matches_filter) {
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (!sub_filter.length) {
|
|
478
|
+
sub_filter = null;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
result.push(...stage.getFlattenedStages(sub_filter));
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return result;
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Recursively get all the child-stages (including this one)
|
|
490
|
+
* sorted in launch order.
|
|
491
|
+
*
|
|
492
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
493
|
+
* @since 1.4.0
|
|
494
|
+
* @version 1.4.0
|
|
495
|
+
*
|
|
496
|
+
* @param {string[]} filter
|
|
497
|
+
*
|
|
498
|
+
* @return {Alchemy.Stage.Stage[]}
|
|
499
|
+
*/
|
|
500
|
+
Stage.setMethod(function getSortedStages(filter) {
|
|
501
|
+
|
|
502
|
+
let stages = this.getFlattenedStages(filter);
|
|
503
|
+
|
|
504
|
+
stages.sortTopological('id', 'depends_on');
|
|
505
|
+
|
|
506
|
+
return stages;
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Launch this stage and all the given child stages.
|
|
511
|
+
*
|
|
512
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
513
|
+
* @since 1.4.0
|
|
514
|
+
* @version 1.4.0
|
|
515
|
+
*
|
|
516
|
+
* @param {string[]} child_stages The child stages to launch
|
|
517
|
+
*/
|
|
518
|
+
Stage.setMethod(async function launch(child_stages) {
|
|
519
|
+
|
|
520
|
+
if (child_stages == null) {
|
|
521
|
+
throw new Error('Unable to launch a stage without allowed child stages');
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (child_stages === true) {
|
|
525
|
+
child_stages = undefined;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
let stages = this.getSortedStages(child_stages);
|
|
529
|
+
|
|
530
|
+
for (let stage of stages) {
|
|
531
|
+
await stage._launch();
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Actually launch this stage and all the given child stages
|
|
537
|
+
*
|
|
538
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
539
|
+
* @since 1.4.0
|
|
540
|
+
* @version 1.4.0
|
|
541
|
+
*
|
|
542
|
+
* @param {string[]} child_stages The child stages to launch
|
|
543
|
+
*/
|
|
544
|
+
Stage.setMethod(async function _launch(child_stages) {
|
|
545
|
+
|
|
546
|
+
if (!this.started) {
|
|
547
|
+
this.started = Date.now();
|
|
548
|
+
|
|
549
|
+
this.emit('launching', this);
|
|
550
|
+
|
|
551
|
+
if (!this.is_root) {
|
|
552
|
+
this.root_stage.emit('launching', this);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (!this[STATUS]) {
|
|
557
|
+
this[STATUS] = PRE_STATUS;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
await this._doTasks('pre_tasks');
|
|
561
|
+
|
|
562
|
+
if (this[STATUS] == PRE_STATUS) {
|
|
563
|
+
this[STATUS] = MAIN_STATUS;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
await this._doTasks('main_tasks');
|
|
567
|
+
|
|
568
|
+
await this.pre_tasks[STATUS_PLEDGE];
|
|
569
|
+
await this.main_tasks[STATUS_PLEDGE];
|
|
570
|
+
|
|
571
|
+
if (this[STATUS] != POST_STATUS) {
|
|
572
|
+
this[STATUS] = CHILD_STATUS;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
await this.refreshStatus();
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Check if everything is finished
|
|
580
|
+
*
|
|
581
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
582
|
+
* @since 1.4.0
|
|
583
|
+
* @version 1.4.0
|
|
584
|
+
*/
|
|
585
|
+
Stage.setMethod(async function refreshStatus() {
|
|
586
|
+
|
|
587
|
+
if (!this.hasFinishedAllChildStages()) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
await this._doTasks('post_tasks');
|
|
592
|
+
|
|
593
|
+
if (!this.ended) {
|
|
594
|
+
this.ended = Date.now();
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
this[STATUS] = POST_STATUS;
|
|
598
|
+
|
|
599
|
+
this.pledge.resolve();
|
|
600
|
+
|
|
601
|
+
if (this.parent) {
|
|
602
|
+
this.parent.refreshStatus();
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Create a sputnik shim
|
|
608
|
+
*
|
|
609
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
610
|
+
* @since 1.4.0
|
|
611
|
+
* @version 1.4.0
|
|
612
|
+
*
|
|
613
|
+
* @param {Object} mapping
|
|
614
|
+
*
|
|
615
|
+
* @return {Alchemy.Stages.SputnikShim}
|
|
616
|
+
*/
|
|
617
|
+
Stage.setMethod(function createSputnikShim(mapping) {
|
|
618
|
+
return new SputnikShim(this, mapping);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Custom Janeway representation (left side)
|
|
623
|
+
*
|
|
624
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
625
|
+
* @since 1.4.0
|
|
626
|
+
* @version 1.4.0
|
|
627
|
+
*
|
|
628
|
+
* @return {string}
|
|
629
|
+
*/
|
|
630
|
+
Stage.setMethod(Symbol.for('janeway_arg_left'), function janewayClassIdentifier() {
|
|
631
|
+
return 'A.S.' + this.constructor.name;
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Custom Janeway representation (right side)
|
|
636
|
+
*
|
|
637
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
638
|
+
* @since 1.4.0
|
|
639
|
+
* @version 1.4.0
|
|
640
|
+
*
|
|
641
|
+
* @return {String}
|
|
642
|
+
*/
|
|
643
|
+
Stage.setMethod(Symbol.for('janeway_arg_right'), function janewayInstanceInfo() {
|
|
644
|
+
return this.id;
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* The SputnikShim class
|
|
649
|
+
*
|
|
650
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
651
|
+
* @since 1.4.0
|
|
652
|
+
* @version 1.4.0
|
|
653
|
+
*
|
|
654
|
+
* @param {Alchemy.Stages.Stages} stage
|
|
655
|
+
* @param {Object} mapping
|
|
656
|
+
*/
|
|
657
|
+
const SputnikShim = Function.inherits('Alchemy.Base', 'Alchemy.Stages', function SputnikShim(stage, mapping) {
|
|
658
|
+
this.stage = stage;
|
|
659
|
+
this.mapping = mapping;
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Get a stage by its old name
|
|
664
|
+
*
|
|
665
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
666
|
+
* @since 1.4.0
|
|
667
|
+
* @version 1.4.0
|
|
668
|
+
*
|
|
669
|
+
* @param {string} name
|
|
670
|
+
*
|
|
671
|
+
* @return {Alchemy.Stages.Stage}
|
|
672
|
+
*/
|
|
673
|
+
SputnikShim.setMethod(function getStage(name) {
|
|
674
|
+
|
|
675
|
+
if (!name) {
|
|
676
|
+
throw new Error('Unable to get stage without name');
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
let id = this.mapping[name];
|
|
680
|
+
|
|
681
|
+
if (!id) {
|
|
682
|
+
id = name;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
return this.stage.getStage(id);
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Do something before the given stage
|
|
690
|
+
*
|
|
691
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
692
|
+
* @since 1.4.0
|
|
693
|
+
* @version 1.4.0
|
|
694
|
+
*
|
|
695
|
+
* @param {string[]} names
|
|
696
|
+
* @param {Function} callback
|
|
697
|
+
*/
|
|
698
|
+
SputnikShim.setMethod(function before(names, callback) {
|
|
699
|
+
|
|
700
|
+
let pledges = [],
|
|
701
|
+
stage;
|
|
702
|
+
|
|
703
|
+
names = Array.cast(names);
|
|
704
|
+
|
|
705
|
+
for (let name of names) {
|
|
706
|
+
stage = this.getStage(name);
|
|
707
|
+
|
|
708
|
+
if (!stage) {
|
|
709
|
+
throw new Error('Stage "' + name + '" not found');
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
let pledge = new Pledge.Swift();
|
|
713
|
+
|
|
714
|
+
stage.addPreTask(() => {
|
|
715
|
+
pledge.resolve();
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
pledges.push(pledge);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
return Function.parallel(pledges).then(callback);
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Do something after the given stage
|
|
726
|
+
*
|
|
727
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
728
|
+
* @since 1.4.0
|
|
729
|
+
* @version 1.4.0
|
|
730
|
+
*
|
|
731
|
+
* @param {string[]} names
|
|
732
|
+
* @param {Function} callback
|
|
733
|
+
*/
|
|
734
|
+
SputnikShim.setMethod(function after(names, callback) {
|
|
735
|
+
|
|
736
|
+
let pledges = [],
|
|
737
|
+
stage;
|
|
738
|
+
|
|
739
|
+
names = Array.cast(names);
|
|
740
|
+
|
|
741
|
+
for (let name of names) {
|
|
742
|
+
stage = this.getStage(name);
|
|
743
|
+
|
|
744
|
+
if (!stage) {
|
|
745
|
+
throw new Error('Stage "' + name + '" not found');
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
let pledge = new Pledge.Swift();
|
|
749
|
+
|
|
750
|
+
stage.addPostTask(() => {
|
|
751
|
+
pledge.resolve();
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
pledges.push(pledge);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
return Function.parallel(pledges).then(callback);
|
|
758
|
+
});
|