Skip to content
This repository was archived by the owner on Feb 11, 2020. It is now read-only.

Commit 44b5f5d

Browse files
author
Dr. Safi
committed
Merge branch 'RefactorNestedUnitMethod'
2 parents 73ed4ea + 0e6f3a8 commit 44b5f5d

File tree

13 files changed

+233
-280
lines changed

13 files changed

+233
-280
lines changed

module/reusableNestedUnit/NestedUnit.class.js

Lines changed: 159 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { classDecorator as prototypeChainDebug} from 'appscript/module/prototypeChainDebug'
22
import { add, execute, applyMixin, conditional } from 'appscript/utilityFunction/decoratorUtility.js'
3+
import promiseProperRace from 'appscript/utilityFunction/promiseProperRace.js'
34

45
export default ({ Superclass }) => {
56
let self =
@@ -19,6 +20,73 @@ export default ({ Superclass }) => {
1920
return this
2021
}
2122

23+
/**
24+
* @description loops through all the insertion points and initializes each one to execute the children specific for it.
25+
*
26+
* @param {Class Instance} nestedUnitInstance Tree instance of the module using "reusableNestedUnit" pattern. instance should have "initializeInsertionPoint" function & "insertionPoint" Array.
27+
* @returns undifiend for false or any type of value depending on the module being applied.
28+
*/
29+
/**
30+
* @description loops through all the insertion points and initializes each one to execute the children specific for it.
31+
*
32+
* @param {Class Instance} nestedUnitInstance Tree instance of the module using "reusableNestedUnit" pattern. instance should have "initializeInsertionPoint" function & "insertionPoint" Array.
33+
* @returns undifiend for false or any type of value depending on the module being applied.
34+
*/
35+
async loopInsertionPoint({ type }) {
36+
switch (type) {
37+
case 'aggregateIntoObject':
38+
let view = {}
39+
if(this.insertionPoint) {
40+
for (let insertionPoint of this.insertionPoint) {
41+
let children = await this.filterAndOrderChildren({ insertionPointKey: insertionPoint.key })
42+
let subsequent = await this.initializeInsertionPoint({ insertionPoint, children })
43+
if(!(insertionPoint.name in view)) view[insertionPoint.name] = []
44+
Array.prototype.push.apply(
45+
view[insertionPoint.name],
46+
subsequent
47+
)
48+
}
49+
}
50+
return view;
51+
break;
52+
case 'aggregateIntoArray':
53+
let array = []
54+
if(this.insertionPoint) { // get callback from subtrees
55+
for (let insertionPoint of this.insertionPoint) {
56+
let children = await this.filterAndOrderChildren({ insertionPointKey: insertionPoint.key })
57+
let subsequentArray = await this.initializeInsertionPoint({ insertionPoint, children })
58+
if(array.length != 0) {
59+
await Array.prototype.push.apply(array, subsequentArray)
60+
} else {
61+
array = await subsequentArray.slice()
62+
}
63+
}
64+
}
65+
return array;
66+
break;
67+
/**
68+
* @description loops through all the insertion points and initializes each one to execute the children specific for it.
69+
*
70+
* @param {Class Instance} nestedUnitInstance Tree instance of the module using "reusableNestedUnit" pattern. instance should have "initializeInsertionPoint" function & "insertionPoint" Array.
71+
* @returns undifiend for false or any type of value depending on the module being applied.
72+
*/
73+
case 'returnedFirstValue':
74+
let returned;
75+
// get callback from subtrees
76+
for (let insertionPoint of this.insertionPoint) {
77+
// [1] get children immediate & relating to this insertion position.
78+
let children = await this.filterAndOrderChildren({ insertionPointKey: insertionPoint.key })
79+
// let children = await this.filterChildrenOfCurrentInsertionPoint({ insertionPointKey: insertionPoint.key })
80+
returned = await this.initializeInsertionPoint({ insertionPoint, children })
81+
if (returned) break
82+
}
83+
return returned;
84+
default:
85+
console.log(`"${type}" type doesn\'t match any kind.`)
86+
break;
87+
}
88+
}
89+
2290
/**
2391
* @description gets document from database using documentKey and populates the data to the instance.
2492
*
@@ -39,20 +107,27 @@ export default ({ Superclass }) => {
39107
* @param {any} {insertionPointKey, insertionPath = null}
40108
* @returns
41109
*/
42-
async filterChildren({insertionPointKey}) {
43-
let ownFilteredChildren = await this.filterAndModifyChildrenArray(this.children, insertionPointKey, null)
110+
async filterAndOrderChildren({ insertionPointKey, children = this.children }) {
111+
let ownFilteredChildren = await this.filterAndModifyChildrenArray(children, insertionPointKey, null)
44112
let additionalFilteredChildren = await this.filterAndModifyChildrenArray(this.additionalChildNestedUnit, insertionPointKey, this.pathPointerKey)
45113
return await this.mergeAndOrderChildren(ownFilteredChildren, additionalFilteredChildren);
46114
}
47-
48-
async filterAndModifyChildrenArray(childrenArray, insertionPointKey, pathPointerKey) {
49-
return childrenArray.filter((child, index) => { // filter children that correspont to the current insertionpoint.
50-
let result = (child.insertionPosition.insertionPoint == insertionPointKey && child.insertionPosition.insertionPathPointer == pathPointerKey)
51-
// if (result) childrenArray.splice(index, 1); // was ment to increase the performance of the program, preventing rechecking of already checked array items. But it causes some issues.
115+
/**
116+
* Get children corresponding to the current insertion point.
117+
* // Take into consideration the indirect children added from previous (inhereted) trees.
118+
* // filteredTreeChildren + immediateNextChildren
119+
* // let nextChildren;
120+
*/
121+
async filterAndModifyChildrenArray(children, insertionPointKey, pathPointerKey) {
122+
return children.filter((child, index) => { // filter children that correspont to the current insertionpoint.
123+
let result = (
124+
child.insertionPosition.insertionPoint == insertionPointKey &&
125+
child.insertionPosition.insertionPathPointer == pathPointerKey
126+
)
127+
// if (result) children.splice(index, 1); // was ment to increase the performance of the program, preventing rechecking of already checked array items. But it causes some issues.
52128
return result
53129
})
54130
}
55-
56131
// order additional children that will be mixed into ownChildren. According to a setting that needs to be added into each child object.
57132
async mergeAndOrderChildren(ownFilteredChildren, additionalFilteredChildren) {
58133
// metrge 2 arrays., appending one to the other.
@@ -108,6 +183,82 @@ export default ({ Superclass }) => {
108183
return Array.prototype.concat(firstChildren, orderedChildren, lastChildren)
109184
}
110185

186+
/**
187+
* Call correct execution type method of the current insertionpoint settings.
188+
*/
189+
async initializeInsertionPoint({ insertionPoint, children }) {
190+
// [2] check type of subtrees execution: race first, all ... .
191+
let callback;
192+
switch(insertionPoint.executionType) { // execution type callback name
193+
case 'raceFirstPromise':
194+
callback = 'initializeNestedUnitInRaceExecutionType'
195+
break;
196+
case 'middlewareArray': // TODO: Deprected name - Change middlewareArray in database to chronological
197+
case 'chronological':
198+
callback = 'initializeTreeInChronologicalSequence'
199+
break;
200+
default:
201+
console.log(`"${insertionPoint.executionType}" executionType doesn\'t match any kind.`)
202+
}
203+
// [3] call handler on them.
204+
return await this[callback](children)
205+
}
206+
207+
async initializeTreeInChronologicalSequence(children /* nestedUnitChildren / TreeChildren */) {
208+
let array = [] // nested Unit Array or rendered nested unit initalization results.
209+
for (var index = 0; index < children.length; index++) {
210+
let child = children[index]
211+
// Add the rest of the immediate children to the next tree as additional children. propagate children to the next tree.
212+
if(this.children.length != 0) {
213+
await Array.prototype.push.apply(this.children, this.additionalChildNestedUnit)
214+
} else {
215+
this.children = await this.additionalChildNestedUnit.slice()
216+
}
217+
let initialized = await this.initializeNestedUnit({
218+
nestedUnitKey: child.nestedUnit,
219+
additionalChildNestedUnit: this.children,
220+
pathPointerKey: child.pathPointerKey
221+
})
222+
let subsequentArray = Array.isArray(initialized) ? initialized : [ initialized ]; // Convert to array
223+
if(array.length != 0) {
224+
await Array.prototype.push.apply(array, subsequentArray)
225+
} else {
226+
array = await subsequentArray.slice()
227+
}
228+
}
229+
230+
return array
231+
}
232+
233+
async initializeNestedUnitInRaceExecutionType(children) {
234+
let promiseArray = []
235+
promiseArray = children.map(conditionTreeChild => {
236+
return new Promise(async (resolve, reject) => {
237+
// Add the rest of the immediate children to the next tree as additional children. propagate children to the next tree.
238+
239+
if(this.children.length != 0) {
240+
await Array.prototype.push.apply(this.children, this.additionalChildNestedUnit)
241+
} else {
242+
this.children = await this.additionalChildNestedUnit.slice()
243+
}
244+
245+
let callback = await this.initializeNestedUnit({
246+
nestedUnitKey: conditionTreeChild.nestedUnit,
247+
additionalChildNestedUnit: this.children,
248+
pathPointerKey: conditionTreeChild.pathPointerKey
249+
})
250+
if(!callback) reject('SZN - No callback choosen from this childTree.')
251+
resolve(callback)
252+
})
253+
})
254+
255+
let callback;
256+
await promiseProperRace(promiseArray).then((promiseReturnValueArray) => {
257+
callback = promiseReturnValueArray[0] // as only one promise is return in the array.
258+
}).catch(reason => { if(process.env.SZN_DEBUG == 'true' && this.portAppInstance.context.headers.debug == 'true') console.log(`🔀⚠️ promiseProperRace rejected because: ${reason}`) })
259+
return callback ? callback : false;
260+
}
261+
111262
}
112263

113264
return self

module/reusableNestedUnit/Unit.class.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { classDecorator as prototypeChainDebug} from 'appscript/module/prototypeChainDebug'
2-
import { add, execute, applyMixin, conditional } from 'appscript/utilityFunction/decoratorUtility.js'
2+
import { add, execute, applyMixin, conditional, executeOnceForEachInstance } from 'appscript/utilityFunction/decoratorUtility.js'
33

44
export default ({ Superclass }) => {
55
let self =
@@ -17,6 +17,19 @@ export default ({ Superclass }) => {
1717
this.key = databaseDocumentKey
1818
return this
1919
}
20+
21+
@executeOnceForEachInstance()
22+
async pupolateUnitWithFile({
23+
fileKey,
24+
getDocument, // function
25+
extract = null // object with two properties - extract: { sourceKey: 'key from source object', destinationKey: 'key to "this" destination' }
26+
}) {
27+
let File = await getDocument({
28+
key: fileKey,
29+
connection: self.rethinkdbConnection
30+
})
31+
if(extract) this[extract.destinationKey] = (extract.sourceKey) ? File[extract.sourceKey] : File;
32+
}
2033
}
2134

2235
return self

module/reusableNestedUnit/entrypoint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ function createStaticInstanceClasses({
4848
break;
4949

5050
default:
51-
console.log('No implementation chosen for building class tree in ReusableNestedUnit.')
51+
console.log('⚠️ No implementation chosen for building class tree in ReusableNestedUnit.')
5252
break;
5353
}
5454

module/reusableNestedUnit/implementation/condition/NestedUnit.class.js

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -18,81 +18,6 @@ export default ({ Superclass }) => {
1818
})
1919
@extendedSubclassPattern.Subclass()
2020
class NestedUnit extends Superclass {
21-
// static getDocumentQuery(connection, conditionTreeKey) {
22-
// getConditionTreeQuery(connection, conditionTreeKey)
23-
// }
24-
25-
// static createInstance(controllerInstanceArray, dataKey, getDocumentQueryCallback) {
26-
// NestedUnit.createInstance(controllerInstanceArray, dataKey, getDocumentQueryCallback)
27-
// }
28-
29-
/**
30-
* @description loops through all the insertion points and initializes each one to execute the children specific for it.
31-
*
32-
* @param {Class Instance} nestedUnitInstance Tree instance of the module using "reusableNestedUnit" pattern. instance should have "initializeInsertionPoint" function & "insertionPoint" Array.
33-
* @returns undifiend for false or any type of value depending on the module being applied.
34-
*/
35-
async loopInsertionPoint() {
36-
let returnedValue;
37-
// get callback from subtrees
38-
for (let insertionPoint of this.insertionPoint) {
39-
returnedValue = await this.initializeInsertionPoint({ insertionPoint })
40-
if (returnedValue) break
41-
}
42-
return returnedValue;
43-
}
44-
45-
async initializeInsertionPoint({insertionPoint}) {
46-
let callback;
47-
// [1] get children immediate & relating to this insertion position.
48-
let filteredTreeChildren = await this.filterChildren({ insertionPointKey: insertionPoint.key })
49-
// Take into consideration the indirect children added from previous (inhereted) trees.
50-
// filteredTreeChildren + immediateNextChildren
51-
// let nextChildren;
52-
53-
// [2] check type of subtrees execution: race first, all ... .
54-
let executionTypeCallbackName;
55-
switch(insertionPoint.executionType) {
56-
case 'raceFirstPromise':
57-
executionTypeCallbackName = 'initializeConditionTreeInRaceExecutionType'
58-
break;
59-
default:
60-
console.log('executionType doesn\'t match any kind.')
61-
}
62-
// [3] call handler on them.
63-
callback = await this[executionTypeCallbackName](filteredTreeChildren)
64-
// [4] return callback
65-
return callback ? callback : false;
66-
}
67-
68-
async initializeConditionTreeInRaceExecutionType(conditionTreeChildren) {
69-
let promiseArray = []
70-
promiseArray = conditionTreeChildren.map(conditionTreeChild => {
71-
return new Promise(async (resolve, reject) => {
72-
// Add the rest of the immediate children to the next tree as additional children. propagate children to the next tree.
73-
74-
if(this.children.length != 0) {
75-
await Array.prototype.push.apply(this.children, this.additionalChildNestedUnit)
76-
} else {
77-
this.children = await this.additionalChildNestedUnit.slice()
78-
}
79-
80-
let callback = await this.initializeNestedUnit({
81-
nestedUnitKey: conditionTreeChild.nestedUnit,
82-
additionalChildNestedUnit: this.children,
83-
pathPointerKey: conditionTreeChild.pathPointerKey
84-
})
85-
if(!callback) reject('SZN - No callback choosen from this childTree.')
86-
resolve(callback)
87-
})
88-
})
89-
90-
let callback;
91-
await promiseProperRace(promiseArray).then((promiseReturnValueArray) => {
92-
callback = promiseReturnValueArray[0] // as only one promise is return in the array.
93-
}).catch(reason => { if(process.env.SZN_DEBUG == 'true' && this.portAppInstance.context.headers.debug == 'true') console.log(`🔀⚠️ promiseProperRace rejected because: ${reason}`) })
94-
return callback ? callback : false;
95-
}
9621

9722
}
9823

module/reusableNestedUnit/implementation/condition/Unit.class.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { classDecorator as prototypeChainDebug} from 'appscript/module/prototypeChainDebug'
2-
import { add, execute, applyMixin, conditional } from 'appscript/utilityFunction/decoratorUtility.js'
2+
import { add, execute, applyMixin, conditional, executeOnceForEachInstance } from 'appscript/utilityFunction/decoratorUtility.js'
33
import { extendedSubclassPattern } from 'appscript/utilityFunction/extendedSubclassPattern.js'
44
import { curried as getTableDocumentCurried } from "appscript/utilityFunction/database/query/getTableDocument.query.js";
55

@@ -17,14 +17,16 @@ export default ({ Superclass }) => {
1717
})
1818
@extendedSubclassPattern.Subclass()
1919
class Unit extends Superclass {
20+
async pupolateUnitWithFile() {
21+
await super.pupolateUnitWithFile({
22+
getDocument: getDocument['File'],
23+
fileKey: this.valueReturningFileKey,
24+
extract: { destinationKey: 'valueReturningFile' }
25+
})
26+
}
27+
28+
@executeOnceForEachInstance()
2029
async checkCondition() {
21-
let valueReturningFileKey = this.valueReturningFileKey
22-
if(!('valueReturningFile' in this)) {
23-
this.valueReturningFile = await getDocument['File']({
24-
key: valueReturningFileKey,
25-
connection: self.rethinkdbConnection
26-
})
27-
}
2830
// [2] require & check condition
2931
if(!this.conditionResult) {
3032
let expectedReturn = this.expectedReturn

0 commit comments

Comments
 (0)