spyne 0.19.1 → 0.20.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/.eslintignore +2 -0
- package/.eslintrc.js +4 -3
- package/.travis.yml +24 -11
- package/karma.conf.js +77 -87
- package/lib/spyne.esm.js +15 -0
- package/lib/spyne.esm.js.map +1 -0
- package/lib/spyne.js +248 -248
- package/lib/spyne.umd.js +3 -0
- package/lib/spyne.umd.js.LICENSE.txt +16 -0
- package/package.json +48 -27
- package/rollup.config.js +26 -0
- package/src/spyne/channels/channel-fetch-class.js +39 -43
- package/src/spyne/channels/channel-payload-class.js +61 -74
- package/src/spyne/channels/channel-proxy.js +25 -26
- package/src/spyne/channels/channel.js +141 -149
- package/src/spyne/channels/channels-config.js +46 -47
- package/src/spyne/channels/channels-map.js +61 -65
- package/src/spyne/channels/spyne-channel-lifecycle.js +12 -12
- package/src/spyne/channels/spyne-channel-route.js +241 -250
- package/src/spyne/channels/spyne-channel-ui.js +213 -75
- package/src/spyne/channels/spyne-channel-window.js +157 -157
- package/src/spyne/spyne-app.js +32 -19
- package/src/spyne/spyne-plugins.js +55 -70
- package/src/spyne/spyne.js +23 -23
- package/src/spyne/utils/channel-config-validator.js +10 -10
- package/src/spyne/utils/channel-fetch-util.js +72 -55
- package/src/spyne/utils/channel-payload-filter.js +89 -100
- package/src/spyne/utils/deep-merge.js +31 -29
- package/src/spyne/utils/frp-tools.js +108 -92
- package/src/spyne/utils/gc.js +6 -6
- package/src/spyne/utils/mixins/base-core-mixins.js +17 -15
- package/src/spyne/utils/mixins/base-streams-mixins.js +9 -9
- package/src/spyne/utils/route-channel-updater.js +23 -29
- package/src/spyne/utils/safe-clone.js +40 -58
- package/src/spyne/utils/sanitize-html.js +35 -0
- package/src/spyne/utils/security-policy.js +11 -0
- package/src/spyne/utils/spyne-app-properties.js +110 -114
- package/src/spyne/utils/spyne-logger.js +4 -11
- package/src/spyne/utils/spyne-plugins-methods.js +38 -63
- package/src/spyne/utils/spyne-trait.js +33 -33
- package/src/spyne/utils/spyne-utils-channel-route-url.js +229 -153
- package/src/spyne/utils/spyne-utils-channel-route.js +128 -138
- package/src/spyne/utils/spyne-utils-channel-window.js +39 -39
- package/src/spyne/utils/viewstream-animations.js +12 -12
- package/src/spyne/utils/viewstream-observables.js +45 -45
- package/src/spyne/views/dom-element-template.js +111 -114
- package/src/spyne/views/dom-element.js +82 -84
- package/src/spyne/views/view-stream-broadcaster.js +66 -62
- package/src/spyne/views/view-stream-element.js +105 -106
- package/src/spyne/views/view-stream-payload.js +25 -27
- package/src/spyne/views/view-stream-selector.js +157 -163
- package/src/spyne/views/view-stream.js +416 -640
- package/src/tests/channels/channel-dom.test.js +15 -15
- package/src/tests/channels/channel-fetch.test.js +51 -62
- package/src/tests/channels/channel-payload-class.test.js +50 -63
- package/src/tests/channels/channel-payload-filter.test.js +133 -193
- package/src/tests/channels/channel-route.test.js +102 -112
- package/src/tests/channels/channel-stream-item.test.js +19 -19
- package/src/tests/channels/channel-ui.test.js +15 -27
- package/src/tests/channels/channel-util-dom.test.js +31 -31
- package/src/tests/channels/channel.test.js +20 -25
- package/src/tests/channels/route-utils.test.js +61 -66
- package/src/tests/channels/url-utils.test.js +151 -151
- package/src/tests/channels/view-stream-broadcaster.test.js +7 -7
- package/src/tests/import.test.js +5 -5
- package/src/tests/index.js +6 -7
- package/src/tests/index.test.js +6 -8
- package/src/tests/mocks/channel-payload-data.js +218 -220
- package/src/tests/mocks/enhancer.test.js +5 -5
- package/src/tests/mocks/payload-ui.js +87 -90
- package/src/tests/mocks/routes-data.js +264 -266
- package/src/tests/mocks/spyne-docs.mocks.js +3 -3
- package/src/tests/mocks/template-renderer.mocks.js +47 -47
- package/src/tests/mocks/utils-data.js +78 -79
- package/src/tests/mocks/viewstream-internal-payload.mocks.js +50 -50
- package/src/tests/mocks/window-events-arr.js +1 -1
- package/src/tests/package-json.spec.test.js +9 -0
- package/src/tests/spyne-app.test.js +15 -18
- package/src/tests/spyne-plugin.test.js +16 -20
- package/src/tests/utils/channel-action-filter.test.js +84 -86
- package/src/tests/utils/channel-data-packet-generator.unused.js +62 -86
- package/src/tests/utils/channel-fetch-util.test.js +64 -66
- package/src/tests/utils/frp-tools.test.js +19 -19
- package/src/tests/utils/plugins-methods.test.js +31 -55
- package/src/tests/utils/security.test.js +10 -0
- package/src/tests/utils/spyne-app-properties.test.js +4 -8
- package/src/tests/views/dom-el-selectors.test.js +112 -119
- package/src/tests/views/dom-el-template-proxy.test.js +7 -0
- package/src/tests/views/dom-el-template.test.js +186 -156
- package/src/tests/views/dom-el.test.js +58 -56
- package/src/tests/views/view-stream-enhancer-loader.test.js +2 -2
- package/src/tests/views/view-stream-enhancer.test.js +11 -11
- package/src/tests/views/view-stream.test.js +22 -33
- package/webpack.config.js +76 -67
- package/docs/-_%20Solves%20equations%20of%20the%20form%20a%20_%20x%20=%20b.html +0 -487
- package/docs/DomItem.html +0 -298
- package/docs/DomItem_DomItem.html +0 -314
- package/docs/ViewStream.html +0 -2249
- package/docs/ViewStream_ViewStream.html +0 -503
- package/docs/custom/css/jsdoc-viewstream.css +0 -377
- package/docs/custom/layout.tmpl +0 -47
- package/docs/dom-item.js.html +0 -213
- package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
- package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
- package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
- package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/global.html +0 -548
- package/docs/index-custom.html +0 -79
- package/docs/index.html +0 -82
- package/docs/jsdoc.config.json +0 -22
- package/docs/scripts/linenumber.js +0 -25
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/scripts/prettify/lang-css.js +0 -2
- package/docs/scripts/prettify/prettify.js +0 -28
- package/docs/styles/jsdoc-default.css +0 -358
- package/docs/styles/prettify-jsdoc.css +0 -111
- package/docs/styles/prettify-tomorrow.css +0 -132
- package/docs/view-stream.js.html +0 -767
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { baseCoreMixins } from '../utils/mixins/base-core-mixins'
|
|
2
|
-
import {SpyneAppProperties} from '../utils/spyne-app-properties'
|
|
3
|
-
import { deepMerge } from '../utils/deep-merge'
|
|
4
|
-
import {safeClone} from '../utils/safe-clone'
|
|
1
|
+
import { baseCoreMixins } from '../utils/mixins/base-core-mixins'
|
|
2
|
+
import { SpyneAppProperties } from '../utils/spyne-app-properties'
|
|
3
|
+
import { deepMerge } from '../utils/deep-merge'
|
|
4
|
+
import { safeClone } from '../utils/safe-clone'
|
|
5
5
|
import {
|
|
6
6
|
findStrOrRegexMatchStr,
|
|
7
7
|
getConstructorName
|
|
8
|
-
} from '../utils/frp-tools'
|
|
9
|
-
import { ViewStreamElement } from './view-stream-element'
|
|
10
|
-
import { registeredStreamNames } from '../channels/channels-config'
|
|
11
|
-
import { ViewStreamBroadcaster } from './view-stream-broadcaster'
|
|
12
|
-
import { ViewStreamPayload } from './view-stream-payload'
|
|
13
|
-
import { ChannelPayloadFilter } from '../utils/channel-payload-filter'
|
|
14
|
-
import { ViewStreamObservable } from '../utils/viewstream-observables'
|
|
15
|
-
import {ViewStreamSelector} from './view-stream-selector'
|
|
16
|
-
import { Subject, of } from 'rxjs'
|
|
17
|
-
import { mergeMap, map, takeWhile, filter, tap, skip, finalize } from 'rxjs/operators'
|
|
8
|
+
} from '../utils/frp-tools'
|
|
9
|
+
import { ViewStreamElement } from './view-stream-element'
|
|
10
|
+
import { registeredStreamNames } from '../channels/channels-config'
|
|
11
|
+
import { ViewStreamBroadcaster } from './view-stream-broadcaster'
|
|
12
|
+
import { ViewStreamPayload } from './view-stream-payload'
|
|
13
|
+
import { ChannelPayloadFilter } from '../utils/channel-payload-filter'
|
|
14
|
+
import { ViewStreamObservable } from '../utils/viewstream-observables'
|
|
15
|
+
import { ViewStreamSelector } from './view-stream-selector'
|
|
16
|
+
import { Subject, of } from 'rxjs'
|
|
17
|
+
import { mergeMap, map, takeWhile, filter, tap, skip, finalize } from 'rxjs/operators'
|
|
18
18
|
import {
|
|
19
19
|
pick,
|
|
20
20
|
compose,
|
|
@@ -39,120 +39,29 @@ import {
|
|
|
39
39
|
path,
|
|
40
40
|
omit,
|
|
41
41
|
ifElse,
|
|
42
|
-
clone,
|
|
43
42
|
mergeRight,
|
|
44
43
|
where,
|
|
45
|
-
equals
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const rMap = require('ramda').map;
|
|
44
|
+
equals
|
|
45
|
+
, map as rMap
|
|
46
|
+
} from 'ramda'
|
|
49
47
|
|
|
50
48
|
export class ViewStream {
|
|
51
49
|
/**
|
|
52
50
|
* @module ViewStream
|
|
53
|
-
* @type extendable
|
|
54
51
|
*
|
|
55
52
|
* @desc
|
|
56
53
|
*
|
|
57
54
|
* <p>ViewStream is the interactive-view component, and its core functionality is comprised of two internal components: </p>
|
|
58
55
|
<ul class='basic'>
|
|
59
|
-
<li>LINK['ViewStreamElement', 'view-stream-element']: The “View” in ViewStream. Creates the HTML Element based on values from the props object, and is responsible for rendering and disposing of its view.
|
|
60
|
-
<li>LINK['ViewStreamObservable', 'view-stream-observable']: The “Stream” in ViewStream. Creates an observable that forks into three streams: the first is between ViewStream and its ViewStreamElement, the second stream is to a parent ViewStream instance, and and the third stream is to all appended ViewStream children.</ul>
|
|
61
|
-
<p>Other components used in ViewStream:</p>
|
|
62
|
-
<ul>
|
|
63
|
-
<li>LINK['ViewStreamBroadcaster', 'view-stream-broadcaster']: Takes the nested array from the <i>BroadcastEvents</i> method and creates RxJs observables that are delegated to either the CHANNEL_UI or CHANNEL_ROUTE
|
|
64
|
-
<li>LINK['ViewStreamSelector', 'view-stream-selector']: Provides selector and CSS utility methods.
|
|
65
|
-
<li>LINK['ViewStreamPayload', 'view-stream-payload']: Payload format for sending data to Channels using the <i>sendInfoToChannel</i> method.
|
|
66
|
-
</ul>
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* <h4>Rendering</h4>
|
|
70
|
-
* <p>ViewStream renders its element and any content based on the values within the <i>props</i> property.</p>
|
|
71
|
-
* <ul class='bullet'>
|
|
72
|
-
* <li>By default ViewStream renders an empty div</li>
|
|
73
|
-
* <li>Templates can be provided as a String or String literal of HTML tags, or as an HTML Element</li>
|
|
74
|
-
* <li>ViewStreams will apply any HTML attributes defined within <i>props</i> to the rendered element</li>
|
|
75
|
-
* <li>An existing element can be assigned to the props.el</li>
|
|
76
|
-
*
|
|
77
|
-
* </ul>
|
|
78
|
-
*
|
|
79
|
-
* The <i>props</i> property is also used to hold all of the internal values within the ViewStream instance.
|
|
80
|
-
*
|
|
81
|
-
* <h5>Appending to Document</h5>
|
|
82
|
-
* <p>ViewStreams renders an HTML DocumentFragment and only attaches that element to the DOM when appended to another ViewStream instance or to an existing HTML element.</p>
|
|
83
|
-
* <p>Below are the methods that appends the View to the DOM:</p>
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* <div class='method-section'>
|
|
87
|
-
* <h5>Appending To Other ViewStreams</h5>
|
|
88
|
-
*
|
|
89
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-append-view" href="/guide/reference/view-stream-append-view" >appendView</a>
|
|
90
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-prepend-view" href="/guide/reference/view-stream-prepend-view" >prependView</a>
|
|
91
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-append-view-to-parent" href="/guide/reference/view-stream-append-view-to-parent" >appendViewToParentEl</a>
|
|
92
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-prepend-view-to-parent" href="/guide/reference/view-stream-prepend-view-to-parent" >prependViewToParentEl</a>
|
|
93
|
-
* </div>
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* <div class='method-section'>
|
|
97
|
-
* <h5>Appending Directly to the DOM</h5>
|
|
98
|
-
*
|
|
99
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-append-to-dom" href="/guide/reference/view-stream-append-to-dom" >appendToDom</a>
|
|
100
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-prepend-to-dom" href="/guide/reference/view-stream-prepend-to-dom" >prependToDom</a>
|
|
101
|
-
*
|
|
102
|
-
* </div>
|
|
103
|
-
*
|
|
104
|
-
* <div class='method-section'>
|
|
105
|
-
* <h5>Appended but hidden</h5>
|
|
106
|
-
*
|
|
107
|
-
* <a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-append-to-null" href="/guide/reference/view-stream-append-to-null" >appendToNull</a>
|
|
108
|
-
*
|
|
109
|
-
* </div>
|
|
110
|
-
*
|
|
111
|
-
* <h4>Broadcasting Events</h4>
|
|
112
|
-
* <p>ViewStreams instances has two methods of broadcasting events:</p>
|
|
113
|
-
* <div class='method-section'>
|
|
114
|
-
* <h5><a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-broadcast-events" href="/guide/reference/view-stream-broadcast-events" >1. broadcastEvents Method</a></h5>
|
|
115
|
-
* <p> Elements listed here will automatically be published to the UI Channel, and the dataset values for that element will be returned along with the relevant action.</br>The event will be published to the ROUTE Channel when the element's dataset value for channel is set to "ROUTE"</p>
|
|
116
|
-
* </div>
|
|
117
|
-
* <div class='method-section'>
|
|
118
|
-
* <h5><a class='linker' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-send-info-to-channel" href="/guide/reference/view-stream-send-info-channel" >2. sendInfoToChannel Method</a></h5>
|
|
119
|
-
* <p>Any type of data can be sent to any channel using the sendInfoToChannel method. This can be especially useful to allow global communication of data from third-party libraries and resources.</p>
|
|
120
|
-
* </div>
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* <h4>Binding Data to Maintain State</h4>
|
|
124
|
-
* <p>ViewStream has several methods and features for instances to receive the exact data, at the right time, to maintain state:</p>
|
|
125
|
-
* <ul>
|
|
126
|
-
* <li>Channel actions are bound to local methods using the <a class='linker no-break' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-add-action-listeners" href="/guide/reference/view-stream-add=action-listeners" >addActionListeners</a> method.</li>
|
|
127
|
-
* <li><a class='linker no-break' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="channel-action-filter" href="/guide/reference/channel-action-filter" >ChannelActionFilters</a> calibrates the flow of data from Channel Actions before that data is sent to its bound local method.</li>
|
|
128
|
-
* <li>The single <b>props</b> property allows all instances to be evaluated with a consistent interface.</li>
|
|
129
|
-
* <li><b>props.el$</b> <a class='linker no-break' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="view-stream-selector" href="/guide/reference/view-stream-selector" >Selector</a> has special methods to adjust state with styles and CSS.</li>
|
|
130
|
-
* <li><a class='linker no-break' data-channel="ROUTE" data-event-prevent-default="true" data-menu-item="spyne-trait" href="/guide/reference/spyne-trait" >SpyneTraits</a> can enhance instances with functionality based on individual actions.</li>
|
|
131
|
-
|
|
132
|
-
*
|
|
133
|
-
* @constructor
|
|
134
|
-
* @param {object} props This json object takes in parameters to generate or reference the dom element
|
|
135
|
-
* @property {string} props.tagName - = 'div'; Defines the HTML Element.
|
|
136
|
-
* @property {domItem} props.el - = undefined; Assigns an existing DOM element. Defined attributes will be added to the element.
|
|
137
|
-
* @property {string|object} props.data - = undefined; Adds text to the element, or populates a template when defined as JSON.
|
|
138
|
-
* @property {boolean} props.sendLifecyleEvents = false; Broadcast lifecycle events of render and dispose to CHANNEL_LIFECYCLE.
|
|
139
|
-
* @property {string} props.id - = undefined; Generates a random id when undefined.
|
|
140
|
-
* @property {Array|SpyntTrait} props.traits - = undefined; Add a single SpyneTrait or array of SpyneTrait components.
|
|
141
|
-
* @property {template} props.template - = undefined; String, String literal or HTML template.
|
|
142
|
-
* @special {"name": "DomElement", "desc": "ViewStreams uses the DomElement class to render html tags and templates.", "link":"dom-item"}
|
|
143
|
-
* @special {"name": "ViewStreamSelector", "desc": "The <b>props.el$</b> property creates an instance of this class, used to query elements within the props.el element; also has methods to update css classes.", "link":"dom-item-selectors"}
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
56
|
*
|
|
149
57
|
*/
|
|
150
58
|
constructor(props = {}) {
|
|
151
|
-
this.vsnum = Math.random()
|
|
152
|
-
this.addMixins()
|
|
59
|
+
this.vsnum = Math.random()
|
|
60
|
+
this.addMixins()
|
|
61
|
+
this._postRenderCalled = false
|
|
153
62
|
this.defaults = () => {
|
|
154
|
-
const vsid = this.createId()
|
|
155
|
-
const id = props.id ? props.id : vsid
|
|
63
|
+
const vsid = this.createId()
|
|
64
|
+
const id = props.id ? props.id : vsid
|
|
156
65
|
return {
|
|
157
66
|
vsid,
|
|
158
67
|
id,
|
|
@@ -172,230 +81,98 @@ export class ViewStream {
|
|
|
172
81
|
template: undefined,
|
|
173
82
|
node: document.createDocumentFragment(),
|
|
174
83
|
name: getConstructorName(this)
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
this._state = {}
|
|
178
|
-
this.$dirs = ViewStreamObservable.createDirectionalFiltersObject()
|
|
179
|
-
this.addDefaultDirection = ViewStreamObservable.addDefaultDir
|
|
180
|
-
this.addDownInternalDir = ViewStreamObservable.addDownInternalDir
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this._state = {}
|
|
87
|
+
this.$dirs = ViewStreamObservable.createDirectionalFiltersObject()
|
|
88
|
+
this.addDefaultDirection = ViewStreamObservable.addDefaultDir
|
|
89
|
+
this.addDownInternalDir = ViewStreamObservable.addDownInternalDir
|
|
181
90
|
// this.props = Object.assigREADY_FOR_VS_DETRITUS_COLLECTn({}, this.defaults(), props);
|
|
182
|
-
this.props = deepMerge(this.defaults(), props)
|
|
183
|
-
this.sendLifecycleMethod = this.props.sendLifecyleEvents === true ? this.sendLifecycleMethodActive.bind(this) : this.sendLifecycleMethodInactive.bind(this)
|
|
184
|
-
|
|
91
|
+
this.props = deepMerge(this.defaults(), props)
|
|
92
|
+
this.sendLifecycleMethod = this.props.sendLifecyleEvents === true ? this.sendLifecycleMethodActive.bind(this) : this.sendLifecycleMethodInactive.bind(this)
|
|
93
|
+
const attributesArr = this.attributesArray
|
|
185
94
|
// let attributesArr = ['id', 'class', 'dataset'];
|
|
186
|
-
this.props
|
|
187
|
-
if (this.props.traits!==undefined){
|
|
188
|
-
this.addTraits(this.props.traits)
|
|
95
|
+
this.props.domAttributes = pick(attributesArr, this.props)
|
|
96
|
+
if (this.props.traits !== undefined) {
|
|
97
|
+
this.addTraits(this.props.traits)
|
|
189
98
|
}
|
|
190
|
-
this.loadAllMethods()
|
|
191
|
-
this.props.action = 'LOADED'
|
|
192
|
-
this.sink$ = new Subject()
|
|
193
|
-
const ViewClass = this.props.viewClass
|
|
99
|
+
this.loadAllMethods()
|
|
100
|
+
this.props.action = 'LOADED'
|
|
101
|
+
this.sink$ = new Subject()
|
|
102
|
+
const ViewClass = this.props.viewClass
|
|
194
103
|
this.view = new ViewClass(this.sink$, {}, this.props.vsid,
|
|
195
|
-
|
|
196
|
-
this.sourceStreams = this.view.sourceStreams
|
|
197
|
-
this._rawSource$ = this.view.getSourceStream()
|
|
198
|
-
this._rawSource
|
|
199
|
-
this.sendEventsDownStream = this.sendEventsDownStreamFn
|
|
200
|
-
this.initViewStream()
|
|
201
|
-
this.isDevMode = ViewStream.isDevMode()
|
|
202
|
-
this.props.addedChannels = []
|
|
203
|
-
this.checkIfElementAlreadyExists()
|
|
104
|
+
this.props.id)// new this.props.viewClass(this.sink$);
|
|
105
|
+
this.sourceStreams = this.view.sourceStreams
|
|
106
|
+
this._rawSource$ = this.view.getSourceStream()
|
|
107
|
+
this._rawSource$.viewName = this.props.name
|
|
108
|
+
this.sendEventsDownStream = this.sendEventsDownStreamFn
|
|
109
|
+
this.initViewStream()
|
|
110
|
+
this.isDevMode = ViewStream.isDevMode()
|
|
111
|
+
this.props.addedChannels = []
|
|
112
|
+
this.checkIfElementAlreadyExists()
|
|
204
113
|
}
|
|
205
114
|
|
|
206
115
|
// ============================= HASH KEY AND SPIGOT METHODS==============================
|
|
207
116
|
get source$() {
|
|
208
|
-
return this._source
|
|
117
|
+
return this._source$
|
|
209
118
|
}
|
|
210
119
|
|
|
211
120
|
get attributesArray() {
|
|
212
121
|
return [
|
|
213
|
-
|
|
214
|
-
'
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
'
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
'
|
|
221
|
-
'
|
|
222
|
-
'
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
'
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
'
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
'
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
'
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
'
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
'
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
'aria-setsize',
|
|
255
|
-
'async',
|
|
256
|
-
'autocapitalize',
|
|
257
|
-
'autocomplete',
|
|
258
|
-
'autofocus',
|
|
259
|
-
'autoplay',
|
|
260
|
-
'bgcolor',
|
|
261
|
-
'border',
|
|
262
|
-
'buffered',
|
|
263
|
-
'challenge',
|
|
264
|
-
'charset',
|
|
265
|
-
'checked',
|
|
266
|
-
'cite',
|
|
267
|
-
'class',
|
|
268
|
-
'code',
|
|
269
|
-
'codebase',
|
|
270
|
-
'color',
|
|
271
|
-
'cols',
|
|
272
|
-
'colspan',
|
|
273
|
-
'content',
|
|
274
|
-
'contenteditable',
|
|
275
|
-
'contextmenu',
|
|
276
|
-
'controls',
|
|
277
|
-
'coords',
|
|
278
|
-
'crossorigin',
|
|
279
|
-
'csp',
|
|
280
|
-
'dataset',
|
|
281
|
-
'datetime',
|
|
282
|
-
'decoding',
|
|
283
|
-
'default',
|
|
284
|
-
'defer',
|
|
285
|
-
'dir',
|
|
286
|
-
'dirname',
|
|
287
|
-
'disabled',
|
|
288
|
-
'download',
|
|
289
|
-
'draggable',
|
|
290
|
-
'dropzone',
|
|
291
|
-
'enctype',
|
|
292
|
-
'for',
|
|
293
|
-
'form',
|
|
294
|
-
'formaction',
|
|
295
|
-
'headers',
|
|
296
|
-
'height',
|
|
297
|
-
'hidden',
|
|
298
|
-
'high',
|
|
299
|
-
'href',
|
|
300
|
-
'hreflang',
|
|
301
|
-
'http-equiv',
|
|
302
|
-
'icon',
|
|
303
|
-
'id',
|
|
304
|
-
'importance',
|
|
305
|
-
'integrity',
|
|
306
|
-
'ismap',
|
|
307
|
-
'itemprop',
|
|
308
|
-
'keytype',
|
|
309
|
-
'kind',
|
|
310
|
-
'label',
|
|
311
|
-
'lang',
|
|
312
|
-
'language',
|
|
313
|
-
'lazyload',
|
|
314
|
-
'list',
|
|
315
|
-
'loop',
|
|
316
|
-
'low',
|
|
317
|
-
'manifest',
|
|
318
|
-
'max',
|
|
319
|
-
'maxlength',
|
|
320
|
-
'minlength',
|
|
321
|
-
'media',
|
|
322
|
-
'method',
|
|
323
|
-
'min',
|
|
324
|
-
'multiple',
|
|
325
|
-
'muted',
|
|
326
|
-
'name',
|
|
327
|
-
'novalidate',
|
|
328
|
-
'open',
|
|
329
|
-
'optimum',
|
|
330
|
-
'pattern',
|
|
331
|
-
'ping',
|
|
332
|
-
'placeholder',
|
|
333
|
-
'poster',
|
|
334
|
-
'preload',
|
|
335
|
-
'radiogroup',
|
|
336
|
-
'readonly',
|
|
337
|
-
'referrerpolicy',
|
|
338
|
-
'rel',
|
|
339
|
-
'required',
|
|
340
|
-
'reversed',
|
|
341
|
-
'role',
|
|
342
|
-
'rows',
|
|
343
|
-
'rowspan',
|
|
344
|
-
'sandbox',
|
|
345
|
-
'scope',
|
|
346
|
-
'scoped',
|
|
347
|
-
'selected',
|
|
348
|
-
'shape',
|
|
349
|
-
'size',
|
|
350
|
-
'sizes',
|
|
351
|
-
'slot',
|
|
352
|
-
'span',
|
|
353
|
-
'spellcheck',
|
|
354
|
-
'src',
|
|
355
|
-
'srcdoc',
|
|
356
|
-
'srclang',
|
|
357
|
-
'srcset',
|
|
358
|
-
'start',
|
|
359
|
-
'step',
|
|
360
|
-
'style',
|
|
361
|
-
'summary',
|
|
362
|
-
'tabindex',
|
|
363
|
-
'target',
|
|
364
|
-
'title',
|
|
365
|
-
'translate',
|
|
366
|
-
'type',
|
|
367
|
-
'usemap',
|
|
368
|
-
'value',
|
|
369
|
-
'width',
|
|
370
|
-
'wrap'
|
|
371
|
-
];
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
static isDevMode(){
|
|
375
|
-
return SpyneAppProperties.debug;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
static checkIfActionsAreRegistered(channelsArr=[], actionsArr){
|
|
379
|
-
if (actionsArr.length>0){
|
|
380
|
-
const getAllActions = (a)=>{
|
|
381
|
-
const getRegisteredActionsArr = (str)=>SpyneAppProperties.getChannelActions(str);
|
|
382
|
-
let arr = a.map(getRegisteredActionsArr);
|
|
383
|
-
return flatten(arr);
|
|
122
|
+
// Global Attributes
|
|
123
|
+
'accesskey', 'class', 'contenteditable', 'dir', 'draggable', 'hidden', 'id', 'lang', 'spellcheck', 'style', 'tabindex', 'title', 'translate',
|
|
124
|
+
|
|
125
|
+
// Accessiblity Attributes
|
|
126
|
+
'aria-autocomplete', 'aria-checked', 'aria-disabled', 'aria-expanded', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-level', 'aria-multiline', 'aria-multiselectable', 'aria-orientation', 'aria-pressed', 'aria-readonly', 'aria-required', 'aria-selected', 'aria-sort', 'aria-valuemax', 'aria-valuemin', 'aria-valuenow', 'aria-valuetext', 'aria-atomic', 'aria-busy', 'aria-live', 'aria-relevant', 'aria-dropeffect', 'aria-grabbed', 'aria-activedescendant', 'aria-controls', 'aria-describedby', 'aria-flowto', 'aria-labelledby', 'aria-owns', 'aria-posinset', 'aria-setsize',
|
|
127
|
+
|
|
128
|
+
// Specific Attributes for input
|
|
129
|
+
'accept', 'autocomplete', 'autofocus', 'checked', 'dirname', 'disabled', 'form', 'formaction',
|
|
130
|
+
'formenctype', 'formmethod', 'formnovalidate', 'formtarget', 'list', 'max', 'maxlength',
|
|
131
|
+
'min', 'minlength', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'step', 'value',
|
|
132
|
+
|
|
133
|
+
// Specific Attributes for img
|
|
134
|
+
'alt', 'srcset', 'sizes', 'usemap', 'ismap',
|
|
135
|
+
|
|
136
|
+
// Specific Attributes for a and link
|
|
137
|
+
'href', 'target', 'download', 'ping', 'rel', 'hreflang', 'as', 'media',
|
|
138
|
+
|
|
139
|
+
// Specific Attributes for form
|
|
140
|
+
'accept-charset', 'action', 'enctype', 'novalidate',
|
|
141
|
+
|
|
142
|
+
// Specific Attributes for meta
|
|
143
|
+
'content', 'charset', 'http-equiv',
|
|
144
|
+
|
|
145
|
+
// Specific Attributes for script
|
|
146
|
+
'async', 'defer', 'integrity', 'nomodule', 'nonce', 'referrerpolicy',
|
|
147
|
+
|
|
148
|
+
// Other Element-specific Attributes
|
|
149
|
+
'autocapitalize', 'autoplay', 'buffered', 'challenge', 'cite', 'code', 'codebase', 'color', 'cols', 'colspan', 'contextmenu', 'controls', 'coords', 'crossorigin', 'csp', 'dataset', 'datetime', 'decoding', 'default', 'for', 'headers', 'high', 'icon', 'importance', 'itemprop', 'keytype', 'kind', 'label', 'language', 'lazyload', 'loop', 'low', 'manifest', 'method', 'muted', 'open', 'optimum', 'poster', 'preload', 'radiogroup', 'reversed', 'role', 'rows', 'rowspan', 'sandbox', 'scope', 'scoped', 'selected', 'shape', 'slot', 'span', 'srcdoc', 'src', 'type', 'srclang', 'start', 'summary', 'wrap', 'width', 'height'
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static isDevMode() {
|
|
154
|
+
return SpyneAppProperties.debug
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static checkIfActionsAreRegistered(channelsArr = [], actionsArr) {
|
|
158
|
+
if (actionsArr.length > 0) {
|
|
159
|
+
const getAllActions = (a) => {
|
|
160
|
+
const getRegisteredActionsArr = (str) => SpyneAppProperties.getChannelActions(str)
|
|
161
|
+
const arr = a.map(getRegisteredActionsArr)
|
|
162
|
+
return flatten(arr)
|
|
384
163
|
}
|
|
385
164
|
const checkForMatch = (strMatch) => {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (actionIndex<0){
|
|
389
|
-
|
|
165
|
+
const re = new RegExp(strMatch)
|
|
166
|
+
const actionIndex = findIndex(test(re), getAllActionsArr)
|
|
167
|
+
if (actionIndex < 0) {
|
|
168
|
+
const channelSyntax = channelsArr.length === 1 ? 'from added channel' : 'from added channels'
|
|
390
169
|
console.warn(`Spyne Warning: The action, ${strMatch}, in ${this.props.name}, does not match any of the registered actions ${channelSyntax}, ${channelsArr.join(', ')}`)
|
|
391
170
|
}
|
|
392
171
|
// const vsnum = ()=> R.test(new RegExp(str), "CHANNEL_ROUTE_TEST_EVENT")
|
|
393
172
|
}
|
|
394
|
-
|
|
395
|
-
actionsArr.forEach(checkForMatch)
|
|
396
|
-
|
|
173
|
+
const getAllActionsArr = getAllActions(channelsArr)
|
|
174
|
+
actionsArr.forEach(checkForMatch)
|
|
397
175
|
}
|
|
398
|
-
|
|
399
176
|
}
|
|
400
177
|
|
|
401
178
|
/**
|
|
@@ -415,58 +192,56 @@ export class ViewStream {
|
|
|
415
192
|
*
|
|
416
193
|
* */
|
|
417
194
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const
|
|
421
|
-
const
|
|
422
|
-
const
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
return mapEventsArrFn(eventsArr);
|
|
195
|
+
static isValidNestedArr(eventsArr) {
|
|
196
|
+
const isTrue = equals(true)
|
|
197
|
+
const allIsTrue = all(isTrue)
|
|
198
|
+
const isString = is(String)
|
|
199
|
+
const isValidArr = compose(allIsTrue, rMap(isString), slice(0, 2), defaultTo([]))
|
|
200
|
+
const mapEventsArrFn = compose(allIsTrue, rMap(isValidArr), defaultTo([]))
|
|
201
|
+
return mapEventsArrFn(eventsArr)
|
|
426
202
|
}
|
|
427
203
|
|
|
428
204
|
static elIsDomElement(o) {
|
|
429
|
-
if (is(String,o)){
|
|
430
|
-
o = document.querySelector(o)
|
|
205
|
+
if (is(String, o)) {
|
|
206
|
+
o = document.querySelector(o)
|
|
431
207
|
}
|
|
432
208
|
|
|
433
|
-
|
|
434
|
-
return compose(lte(0), defaultTo(-1), prop('nodeType'))(o);
|
|
209
|
+
return compose(lte(0), defaultTo(-1), prop('nodeType'))(o)
|
|
435
210
|
}
|
|
436
211
|
|
|
437
212
|
updatePropsToMatchEl() {
|
|
438
|
-
const getTagName = compose(toLower, either(prop('tagName'), always('')))
|
|
439
|
-
this.props.tagName = getTagName(this.props.el)
|
|
213
|
+
const getTagName = compose(toLower, either(prop('tagName'), always('')))
|
|
214
|
+
this.props.tagName = getTagName(this.props.el)
|
|
440
215
|
}
|
|
441
216
|
|
|
442
217
|
// =====================================================================
|
|
443
218
|
|
|
444
219
|
checkIfElementAlreadyExists() {
|
|
445
|
-
const elIsDomElement = compose(lte(0), defaultTo(-1), prop('nodeType'))
|
|
446
|
-
const elIsRendered = el => document.body.contains(el)
|
|
220
|
+
const elIsDomElement = compose(lte(0), defaultTo(-1), prop('nodeType'))
|
|
221
|
+
const elIsRendered = el => document.body.contains(el)
|
|
447
222
|
const elIsReadyBool = propSatisfies(
|
|
448
|
-
|
|
223
|
+
allPass([elIsRendered, elIsDomElement]), 'el')
|
|
449
224
|
if (elIsReadyBool(this.props)) {
|
|
450
|
-
this.updatePropsToMatchEl()
|
|
451
|
-
this.postRender()
|
|
452
|
-
} else if(this.props.el === null){
|
|
225
|
+
this.updatePropsToMatchEl()
|
|
226
|
+
this.postRender()
|
|
227
|
+
} else if (this.props.el === null) {
|
|
453
228
|
console.error(`Spyne Error: The defined element for this ViewStream instance, ${this.constructor.name}, appears to not exist.`)
|
|
454
229
|
}
|
|
455
230
|
}
|
|
456
231
|
|
|
457
232
|
loadAllMethods() {
|
|
458
|
-
const channelFn = curry(this.onChannelMethodCall.bind(this))
|
|
459
|
-
|
|
460
|
-
let [action, funcStr, actionFilter] = arr
|
|
233
|
+
const channelFn = curry(this.onChannelMethodCall.bind(this))
|
|
234
|
+
const createExtraStatesMethod = (arr) => {
|
|
235
|
+
let [action, funcStr, actionFilter] = arr
|
|
461
236
|
if (is(String, actionFilter)) {
|
|
462
|
-
actionFilter = new ChannelPayloadFilter({selector:actionFilter})
|
|
237
|
+
actionFilter = new ChannelPayloadFilter({ selector:actionFilter })
|
|
463
238
|
}
|
|
464
239
|
this.props.extendedSourcesHashMethods[action] = channelFn(funcStr,
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
this.addActionListeners().forEach(createExtraStatesMethod)
|
|
240
|
+
actionFilter)
|
|
241
|
+
}
|
|
242
|
+
this.addActionListeners().forEach(createExtraStatesMethod)
|
|
468
243
|
this.props.hashSourceMethods = this.setSourceHashMethods(
|
|
469
|
-
|
|
244
|
+
this.props.extendedSourcesHashMethods)
|
|
470
245
|
}
|
|
471
246
|
|
|
472
247
|
/**
|
|
@@ -487,114 +262,107 @@ export class ViewStream {
|
|
|
487
262
|
* @returns Nested Array
|
|
488
263
|
*/
|
|
489
264
|
addActionListeners() {
|
|
490
|
-
return []
|
|
265
|
+
return []
|
|
491
266
|
}
|
|
492
267
|
|
|
493
268
|
onChannelMethodCall(str, actionFilter, p) {
|
|
494
|
-
const runFunc = (payload)=>{
|
|
495
|
-
if (this[str] === undefined){
|
|
269
|
+
const runFunc = (payload) => {
|
|
270
|
+
if (this[str] === undefined) {
|
|
496
271
|
console.warn(`Spyne Warning: The method, ${str} does not appear to exist in ${this.constructor.name}!`)
|
|
497
|
-
} else{
|
|
498
|
-
this[str](payload)
|
|
272
|
+
} else {
|
|
273
|
+
this[str](payload)
|
|
499
274
|
}
|
|
500
275
|
}
|
|
501
276
|
|
|
502
277
|
if (p.$dir !== undefined && p.$dir.includes('child') &&
|
|
503
278
|
this.deleted !== true) {
|
|
504
|
-
|
|
505
|
-
obj
|
|
506
|
-
this.sourceStreams.raw$.next(obj)
|
|
279
|
+
const obj = deepMerge({}, p)// Object.assign({}, p);
|
|
280
|
+
obj.$dir = this.$dirs.C
|
|
281
|
+
this.sourceStreams.raw$.next(obj)
|
|
507
282
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (actionFilter !== undefined) {
|
|
283
|
+
const filterPayload = defaultTo(always(true), actionFilter)
|
|
511
284
|
|
|
512
|
-
}
|
|
513
285
|
if (filterPayload(p) === true) {
|
|
514
286
|
p = omit(['$dir'], p)
|
|
515
|
-
|
|
516
|
-
if (actionFilter !== undefined) {
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
runFunc(p);
|
|
287
|
+
runFunc(p)
|
|
520
288
|
}
|
|
521
289
|
}
|
|
522
290
|
|
|
523
291
|
setSourceHashMethods(extendedSourcesHashMethods = {}) {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
292
|
+
const hashSourceKeys = {
|
|
293
|
+
EXTIRPATING: (p) => this.checkParentDispose(p),
|
|
294
|
+
EXTIRPATE: (p) => this.disposeViewStream(p),
|
|
527
295
|
// 'CHILD_EXTIRPATE' : (p) => this.disposeViewStream(p),
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
296
|
+
VS_SPAWNED: (p) => this.onVSRendered(p),
|
|
297
|
+
VS_SPAWNED_AND_ATTACHED_TO_DOM: (p) => this.onVSRendered(p),
|
|
298
|
+
VS_SPAWNED_AND_ATTACHED_TO_PARENT: (p) => this.onVSRendered(p),
|
|
531
299
|
// 'CHILD_VS_SPAWNED' : (p) => this.attachChildToView(p),
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
}
|
|
535
|
-
return deepMerge.all([{}, hashSourceKeys, extendedSourcesHashMethods])
|
|
300
|
+
READY_FOR_VS_DETRITUS_COLLECT: (p) => this.onReadyToGC(p),
|
|
301
|
+
VS_NULLITY: () => ({})
|
|
302
|
+
}
|
|
303
|
+
return deepMerge.all([{}, hashSourceKeys, extendedSourcesHashMethods])
|
|
536
304
|
}
|
|
537
305
|
|
|
538
306
|
// ====================== MAIN STREAM METHODS ==========================
|
|
539
307
|
initViewStream() {
|
|
540
308
|
this._source$ = this._rawSource$.pipe(map(
|
|
541
|
-
|
|
309
|
+
(payload) => this.onMapViewSource(payload)), takeWhile(this.notGCSTATE))
|
|
542
310
|
|
|
543
|
-
this.initAutoMergeSourceStreams()
|
|
544
|
-
this.updateSourceSubscription(this._source$, true)
|
|
311
|
+
this.initAutoMergeSourceStreams()
|
|
312
|
+
this.updateSourceSubscription(this._source$, true)
|
|
545
313
|
}
|
|
546
314
|
|
|
547
315
|
notGCSTATE(p) {
|
|
548
|
-
return !p.action.includes('READY_FOR_VS_DETRITUS_COLLECT')
|
|
316
|
+
return !p.action.includes('READY_FOR_VS_DETRITUS_COLLECT')
|
|
549
317
|
}
|
|
550
318
|
|
|
551
319
|
eqGCSTATE(p) {
|
|
552
|
-
return !p.action.includes('READY_FOR_VS_DETRITUS_COLLECT')
|
|
320
|
+
return !p.action.includes('READY_FOR_VS_DETRITUS_COLLECT')
|
|
553
321
|
}
|
|
554
322
|
|
|
555
323
|
notCOMPLETED(p) {
|
|
556
|
-
return !p.action.includes('COMPLETED')
|
|
324
|
+
return !p.action.includes('COMPLETED')
|
|
557
325
|
}
|
|
558
326
|
|
|
559
327
|
notGCCOMPLETE(p) {
|
|
560
|
-
return !p.action.includes('GC_COMPLETE')
|
|
328
|
+
return !p.action.includes('GC_COMPLETE')
|
|
561
329
|
}
|
|
562
330
|
|
|
563
331
|
testVal(p) {
|
|
564
|
-
console.log('TESTING VALL IS ', p)
|
|
332
|
+
console.log('TESTING VALL IS ', p)
|
|
565
333
|
}
|
|
566
334
|
|
|
567
335
|
addParentStream(obs, attachData) {
|
|
568
|
-
|
|
569
|
-
undefined
|
|
570
|
-
|
|
571
|
-
|
|
336
|
+
const filterOutNullData = (data) => data !== undefined && data.action !==
|
|
337
|
+
undefined
|
|
338
|
+
const checkIfDisposeOrFadeout = (d) => {
|
|
339
|
+
const data = deepMerge({}, d)
|
|
572
340
|
|
|
573
341
|
if (data.action === 'EXTIRPATE_AND_READY_FOR_VS_DETRITUS_COLLECT') {
|
|
574
|
-
this.disposeViewStream(data)
|
|
575
|
-
data.action = 'READY_FOR_VS_DETRITUS_COLLECT'
|
|
342
|
+
this.disposeViewStream(data)
|
|
343
|
+
data.action = 'READY_FOR_VS_DETRITUS_COLLECT'
|
|
576
344
|
}
|
|
577
|
-
return data
|
|
578
|
-
}
|
|
345
|
+
return data
|
|
346
|
+
}
|
|
579
347
|
|
|
580
348
|
this.parent$ = obs.pipe(
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
this.updateSourceSubscription(this.parent$, false, 'PARENT')
|
|
584
|
-
this.renderAndAttachToParent(attachData)
|
|
349
|
+
filter(filterOutNullData),
|
|
350
|
+
map(checkIfDisposeOrFadeout))
|
|
351
|
+
this.updateSourceSubscription(this.parent$, false, 'PARENT')
|
|
352
|
+
this.renderAndAttachToParent(attachData)
|
|
585
353
|
}
|
|
586
354
|
|
|
587
355
|
addChildStream(obs$) {
|
|
588
|
-
|
|
589
|
-
undefined
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
this.updateSourceSubscription(child$, true, 'CHILD')
|
|
356
|
+
const filterOutNullData = (data) => data !== undefined && data.action !==
|
|
357
|
+
undefined
|
|
358
|
+
const child$ = obs$.pipe(
|
|
359
|
+
filter(filterOutNullData),
|
|
360
|
+
tap(p => this.tracer('addChildStraem do ', p)),
|
|
361
|
+
map((p) => {
|
|
362
|
+
return p
|
|
363
|
+
}),
|
|
364
|
+
finalize(p => this.onChildCompleted(child$.source)))
|
|
365
|
+
this.updateSourceSubscription(child$, true, 'CHILD')
|
|
598
366
|
}
|
|
599
367
|
|
|
600
368
|
onChildDisposed(p) {
|
|
@@ -604,116 +372,115 @@ export class ViewStream {
|
|
|
604
372
|
// =======================================================================================
|
|
605
373
|
|
|
606
374
|
onChildCompleted(p) {
|
|
607
|
-
|
|
608
|
-
|
|
375
|
+
const findName = (x) => {
|
|
376
|
+
const finalDest = (y) => {
|
|
609
377
|
while (y.destination !== undefined) {
|
|
610
|
-
y = finalDest(y.destination)
|
|
378
|
+
y = finalDest(y.destination)
|
|
611
379
|
}
|
|
612
|
-
return y
|
|
613
|
-
}
|
|
614
|
-
return pick(['id', 'vsid'], finalDest(x))
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
this.tracer('onChildCompleted ', this.vsnum, p)
|
|
380
|
+
return y
|
|
381
|
+
}
|
|
382
|
+
return pick(['id', 'vsid'], finalDest(x))
|
|
383
|
+
}
|
|
384
|
+
const childCompletedData = findName(p)
|
|
385
|
+
this.tracer('onChildCompleted ', this.vsnum, p)
|
|
618
386
|
// console.log('obj is ',childCompletedName,obj,this.props);
|
|
619
|
-
this.onChildDisposed(childCompletedData, p)
|
|
620
|
-
return childCompletedData
|
|
387
|
+
this.onChildDisposed(childCompletedData, p)
|
|
388
|
+
return childCompletedData
|
|
621
389
|
}
|
|
622
390
|
|
|
623
391
|
initAutoMergeSourceStreams() {
|
|
624
392
|
// ====================== SUBSCRIPTION SOURCE =========================
|
|
625
|
-
|
|
393
|
+
const subscriber = {
|
|
626
394
|
next: this.onSubscribeToSourcesNext.bind(this),
|
|
627
395
|
error: this.onSubscribeToSourcesError.bind(this),
|
|
628
396
|
complete: this.onSubscribeToSourcesComplete.bind(this)
|
|
629
|
-
}
|
|
397
|
+
}
|
|
630
398
|
// let takeBeforeGCOld = (val) => val.action !== 'VS_DETRITUS_COLLECTED';
|
|
631
399
|
// let takeBeforeGC = (p) => !p.action.includes('READY_FOR_VS_DETRITUS_COLLECT');
|
|
632
400
|
// let mapToState = (val) => ({action:val});
|
|
633
401
|
// =====================================================================
|
|
634
402
|
// ========== METHODS TO CHECK FOR WHEN TO COMPLETE THE STREAM =========
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
this.
|
|
638
|
-
this.
|
|
639
|
-
this.
|
|
640
|
-
this.
|
|
641
|
-
this.
|
|
642
|
-
this.deleted
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
obsCount -= 1;
|
|
403
|
+
const completeAll = () => {
|
|
404
|
+
this.props.el$ = undefined
|
|
405
|
+
this.uberSource$.complete()
|
|
406
|
+
this.autoSubscriber$.complete()
|
|
407
|
+
this.sink$.complete()
|
|
408
|
+
this.props = undefined
|
|
409
|
+
this.deleted = true
|
|
410
|
+
this.tracer('completeAll', this.deleted, this.props)
|
|
411
|
+
}
|
|
412
|
+
const decrementOnObservableClosed = () => {
|
|
413
|
+
obsCount -= 1
|
|
647
414
|
if (obsCount === 0) {
|
|
648
|
-
completeAll()
|
|
415
|
+
completeAll()
|
|
649
416
|
}
|
|
650
|
-
}
|
|
417
|
+
}
|
|
651
418
|
// =====================================================================
|
|
652
419
|
// ======================== INIT STREAM METHODS ========================
|
|
653
|
-
let obsCount = 0
|
|
654
|
-
this.uberSource$ = new Subject()
|
|
420
|
+
let obsCount = 0
|
|
421
|
+
this.uberSource$ = new Subject()
|
|
655
422
|
// ======================= COMPOSED RXJS OBSERVABLE ======================
|
|
656
|
-
|
|
423
|
+
const incrementObservablesThatCloses = () => { obsCount += 1 }
|
|
657
424
|
this.autoMergeSubject$ = this.uberSource$.pipe(mergeMap((obsData) => {
|
|
658
|
-
|
|
659
|
-
|
|
425
|
+
const branchObservable$ = obsData.observable.pipe(filter(
|
|
426
|
+
(p) => p !== undefined && p.action !== undefined), map(p => {
|
|
660
427
|
// console.log('PAYLOAD IS ', p, this.constructor.name)
|
|
661
|
-
|
|
662
|
-
payload.action = p.action
|
|
663
|
-
this.tracer('autoMergeSubject$', payload)
|
|
664
|
-
return payload
|
|
665
|
-
}))
|
|
428
|
+
const payload = deepMerge({}, p)
|
|
429
|
+
payload.action = p.action// addRelationToState(obsData.rel, p.action);
|
|
430
|
+
this.tracer('autoMergeSubject$', payload)
|
|
431
|
+
return payload
|
|
432
|
+
}))
|
|
666
433
|
|
|
667
434
|
if (obsData.autoClosesBool === false) {
|
|
668
|
-
return branchObservable
|
|
435
|
+
return branchObservable$
|
|
669
436
|
} else {
|
|
670
|
-
incrementObservablesThatCloses()
|
|
671
|
-
return branchObservable$.pipe(finalize(decrementOnObservableClosed))
|
|
437
|
+
incrementObservablesThatCloses()
|
|
438
|
+
return branchObservable$.pipe(finalize(decrementOnObservableClosed))
|
|
672
439
|
}
|
|
673
|
-
}))
|
|
440
|
+
}))
|
|
674
441
|
// ============================= SUBSCRIBER ==============================
|
|
675
442
|
this.autoSubscriber$ = this.autoMergeSubject$
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
443
|
+
// .do((p) => console.log('SINK DATA ', this.constructor.name, p))
|
|
444
|
+
.pipe(filter((p) => p !== undefined && p.action !== undefined))
|
|
445
|
+
.subscribe(subscriber)
|
|
679
446
|
}
|
|
680
447
|
|
|
681
448
|
// ========================= MERGE STREAMS TO MAIN SUBSCRIBER =================
|
|
682
449
|
updateSourceSubscription(obs$, autoClosesBool = false, rel) {
|
|
683
450
|
// const directionArr = sendDownStream === true ? this.$dirs.DI : this.$dirs.I;
|
|
684
|
-
|
|
451
|
+
const obj = {
|
|
685
452
|
observable: obs$,
|
|
686
453
|
autoClosesBool,
|
|
687
454
|
rel
|
|
688
|
-
}
|
|
689
|
-
this.tracer('updateSourceSubscription ', this.vsnum, obj)
|
|
690
|
-
this.uberSource$.next(obj)
|
|
455
|
+
}
|
|
456
|
+
this.tracer('updateSourceSubscription ', this.vsnum, obj)
|
|
457
|
+
this.uberSource$.next(obj)
|
|
691
458
|
}
|
|
692
459
|
|
|
693
460
|
// ============================= SUBSCRIBER METHODS ==============================
|
|
694
461
|
onSubscribeToSourcesNext(payload = {}) {
|
|
695
|
-
|
|
462
|
+
const defaultToFn = defaultTo((p) => this.sendExtendedStreams(p))
|
|
696
463
|
|
|
697
464
|
// ****USE REGEX AS PREDICATE CHECK FOR PAYLOAD.ACTION IN HASH METHODS OBJ
|
|
698
465
|
// const hashAction = this.props.hashSourceMethods[payload.action];
|
|
699
466
|
const hashActionStr = findStrOrRegexMatchStr(this.props.hashSourceMethods,
|
|
700
|
-
|
|
701
|
-
const hashAction = this.props.hashSourceMethods[hashActionStr]
|
|
467
|
+
payload.action)
|
|
468
|
+
const hashAction = this.props.hashSourceMethods[hashActionStr]
|
|
702
469
|
// console.log('S PAYLOAD ', this.props.name, typeof (hashAction), payload);
|
|
703
470
|
|
|
704
|
-
|
|
471
|
+
const fn = defaultToFn(hashAction)
|
|
705
472
|
|
|
706
473
|
// console.log('hash methods ', fn, this.props.name, payload.action, hashActionStr, this.props.hashSourceMethods);
|
|
707
474
|
|
|
708
|
-
fn(payload)
|
|
475
|
+
fn(payload)
|
|
709
476
|
// console.log(fn, payload, ' THE PAYLOAD FROM SUBSCRIBE IS ', ' ---- ', ' ---> ', this.props);
|
|
710
477
|
// console.log('EXTIRPATER VS NEXT', this.constructor.name, payload);
|
|
711
478
|
|
|
712
|
-
this.tracer('onSubscribeToSourcesNext', { payload })
|
|
479
|
+
this.tracer('onSubscribeToSourcesNext', { payload })
|
|
713
480
|
}
|
|
714
481
|
|
|
715
482
|
onSubscribeToSourcesError(payload = '') {
|
|
716
|
-
console.log('ALL ERROR ', this.constructor.name, payload)
|
|
483
|
+
console.log('ALL ERROR ', this.constructor.name, payload)
|
|
717
484
|
}
|
|
718
485
|
|
|
719
486
|
/*
|
|
@@ -726,36 +493,36 @@ export class ViewStream {
|
|
|
726
493
|
|
|
727
494
|
onSubscribeToSourcesComplete() {
|
|
728
495
|
// console.log('==== EXTIRPATER ALL COMPLETED ====', this.constructor.name);
|
|
729
|
-
this.tracer('onSubscribeToSourcesComplete', 'VS_DETRITUS_COLLECT')
|
|
496
|
+
this.tracer('onSubscribeToSourcesComplete', 'VS_DETRITUS_COLLECT')
|
|
730
497
|
|
|
731
|
-
this.openSpigot('VS_DETRITUS_COLLECT')
|
|
498
|
+
this.openSpigot('VS_DETRITUS_COLLECT')
|
|
732
499
|
}
|
|
733
500
|
|
|
734
501
|
sendExtendedStreams(payload) {
|
|
735
|
-
this.tracer('sendExtendedStreams', payload)
|
|
502
|
+
this.tracer('sendExtendedStreams', payload)
|
|
736
503
|
// console.log('extended methods ', payload.action, payload);
|
|
737
|
-
this.openSpigot(payload.action, payload)
|
|
504
|
+
this.openSpigot(payload.action, payload)
|
|
738
505
|
}
|
|
739
506
|
|
|
740
507
|
// ===================================== VS_SPAWN METHODS ==================================
|
|
741
508
|
renderAndAttachToParent(attachData) {
|
|
742
509
|
// let childRenderData = attachData;
|
|
743
|
-
this.openSpigot('VS_SPAWN_AND_ATTACH_TO_PARENT', attachData)
|
|
510
|
+
this.openSpigot('VS_SPAWN_AND_ATTACH_TO_PARENT', attachData)
|
|
744
511
|
}
|
|
745
512
|
|
|
746
513
|
renderView() {
|
|
747
|
-
this.openSpigot('VS_SPAWN')
|
|
514
|
+
this.openSpigot('VS_SPAWN')
|
|
748
515
|
}
|
|
749
516
|
|
|
750
517
|
renderViewAndAttachToDom(node, type, attachType) {
|
|
751
|
-
|
|
752
|
-
this.openSpigot('VS_SPAWN_AND_ATTACH_TO_DOM', { attachData })
|
|
518
|
+
const attachData = { node, type, attachType }
|
|
519
|
+
this.openSpigot('VS_SPAWN_AND_ATTACH_TO_DOM', { attachData })
|
|
753
520
|
}
|
|
754
521
|
|
|
755
522
|
// ===================================== EXTIRPATE METHODS =================================
|
|
756
523
|
checkParentDispose(p) {
|
|
757
524
|
if (p.from$ === 'parent') {
|
|
758
|
-
this.disposeViewStream(p)
|
|
525
|
+
this.disposeViewStream(p)
|
|
759
526
|
}
|
|
760
527
|
}
|
|
761
528
|
|
|
@@ -774,14 +541,14 @@ export class ViewStream {
|
|
|
774
541
|
*
|
|
775
542
|
*/
|
|
776
543
|
|
|
777
|
-
setTimeout(fn, ms=0, bind=false){
|
|
778
|
-
const timeoutMethod = (...args)=>{
|
|
779
|
-
if (this!==undefined && this.props!==undefined){
|
|
780
|
-
const methodFn = bind===true ? fn.bind(this) : fn
|
|
781
|
-
apply(methodFn, args)
|
|
544
|
+
setTimeout(fn, ms = 0, bind = false) {
|
|
545
|
+
const timeoutMethod = (...args) => {
|
|
546
|
+
if (this !== undefined && this.props !== undefined) {
|
|
547
|
+
const methodFn = bind === true ? fn.bind(this) : fn
|
|
548
|
+
apply(methodFn, args)
|
|
782
549
|
}
|
|
783
550
|
}
|
|
784
|
-
window.setTimeout(timeoutMethod, ms)
|
|
551
|
+
window.setTimeout(timeoutMethod, ms)
|
|
785
552
|
}
|
|
786
553
|
|
|
787
554
|
/**
|
|
@@ -790,8 +557,8 @@ export class ViewStream {
|
|
|
790
557
|
*/
|
|
791
558
|
disposeViewStream(p) {
|
|
792
559
|
// console.log('EXTIRPATER VS onDispose ', this.constructor.name);
|
|
793
|
-
this.onBeforeDispose()
|
|
794
|
-
this.openSpigot('EXTIRPATE')
|
|
560
|
+
this.onBeforeDispose()
|
|
561
|
+
this.openSpigot('EXTIRPATE')
|
|
795
562
|
}
|
|
796
563
|
|
|
797
564
|
onChildDispose(p) {
|
|
@@ -799,35 +566,35 @@ export class ViewStream {
|
|
|
799
566
|
|
|
800
567
|
onParentDisposing(p) {
|
|
801
568
|
// this.updateSourceSubscription(this._source$);
|
|
802
|
-
this.openSpigot('EXTIRPATE')
|
|
569
|
+
this.openSpigot('EXTIRPATE')
|
|
803
570
|
}
|
|
804
571
|
|
|
805
572
|
onReadyToGC(p) {
|
|
806
|
-
const isInternal = p.from$ !== undefined && p.from$ === 'internal'
|
|
573
|
+
const isInternal = p.from$ !== undefined && p.from$ === 'internal'
|
|
807
574
|
if (isInternal) {
|
|
808
575
|
// this.openSpigot('VS_DETRITUS_COLLECT');
|
|
809
576
|
}
|
|
810
|
-
this.tracer('onReadyToGC', isInternal, p)
|
|
577
|
+
this.tracer('onReadyToGC', isInternal, p)
|
|
811
578
|
}
|
|
812
579
|
|
|
813
580
|
openSpigot(action, obj = {}) {
|
|
814
581
|
if (this.props !== undefined) {
|
|
815
|
-
this.props.action = action
|
|
816
|
-
|
|
817
|
-
//let data = Object.assign({}, this.props, obj);
|
|
582
|
+
this.props.action = action
|
|
583
|
+
const data = mergeRight(this.props, obj)
|
|
584
|
+
// let data = Object.assign({}, this.props, obj);
|
|
818
585
|
|
|
819
|
-
this.sink$.next(Object.freeze(data))
|
|
586
|
+
this.sink$.next(Object.freeze(data))
|
|
820
587
|
}
|
|
821
588
|
}
|
|
822
589
|
|
|
823
590
|
setAttachData(attachType, query) {
|
|
824
|
-
const checkQuery = ()=>{
|
|
825
|
-
|
|
826
|
-
const isDevMode = ViewStream.isDevMode()
|
|
827
|
-
if (isDevMode === true && is(String, query) && isNil(q)
|
|
828
|
-
console.warn(`Spyne Warning: The appendView query in ${this.props.name}, '${query}', appears to not exist!`)
|
|
591
|
+
const checkQuery = () => {
|
|
592
|
+
const q = this.props.el.querySelector(query)
|
|
593
|
+
const isDevMode = ViewStream.isDevMode()
|
|
594
|
+
if (isDevMode === true && is(String, query) && isNil(q)) {
|
|
595
|
+
console.warn(`Spyne Warning: The appendView query in ${this.props.name}, '${query}', appears to not exist!`)
|
|
829
596
|
}
|
|
830
|
-
return q
|
|
597
|
+
return q
|
|
831
598
|
}
|
|
832
599
|
|
|
833
600
|
return {
|
|
@@ -835,40 +602,40 @@ export class ViewStream {
|
|
|
835
602
|
type: 'ViewStreamObservable',
|
|
836
603
|
attachType,
|
|
837
604
|
query: checkQuery(query)
|
|
838
|
-
}
|
|
605
|
+
}
|
|
839
606
|
}
|
|
840
607
|
|
|
841
608
|
getParentEls(el, num) {
|
|
842
|
-
|
|
843
|
-
let iter = 0
|
|
844
|
-
let parentEl = el
|
|
609
|
+
const getElem = el => el.parentElement
|
|
610
|
+
let iter = 0
|
|
611
|
+
let parentEl = el
|
|
845
612
|
while (iter < num) {
|
|
846
|
-
parentEl = getElem(parentEl)
|
|
847
|
-
iter
|
|
613
|
+
parentEl = getElem(parentEl)
|
|
614
|
+
iter++
|
|
848
615
|
}
|
|
849
|
-
return parentEl
|
|
616
|
+
return parentEl
|
|
850
617
|
}
|
|
851
618
|
|
|
852
619
|
setAttachParentData(attachType, query, level) {
|
|
853
|
-
query = query!==
|
|
854
|
-
const node = this.getParentEls(this.props.el, level)
|
|
620
|
+
query = query !== '' ? query : undefined
|
|
621
|
+
const node = this.getParentEls(this.props.el, level)
|
|
855
622
|
return {
|
|
856
623
|
node,
|
|
857
624
|
type: 'ViewStreamObservable',
|
|
858
625
|
attachType,
|
|
859
626
|
query: node.querySelector(query)
|
|
860
|
-
}
|
|
627
|
+
}
|
|
861
628
|
}
|
|
862
629
|
|
|
863
630
|
onMapViewSource(payload = {}) {
|
|
864
|
-
this.props = mergeRight(this.props, payload)
|
|
865
|
-
return payload
|
|
631
|
+
this.props = mergeRight(this.props, payload)
|
|
632
|
+
return payload
|
|
866
633
|
}
|
|
867
634
|
|
|
868
635
|
// ====================== ATTACH STREAM AND DOM DATA AGGREGATORS==========================
|
|
869
636
|
exchangeViewsWithChild(childView, attachData) {
|
|
870
|
-
this.addChildStream(childView.sourceStreams.toParent$)
|
|
871
|
-
childView.addParentStream(this.sourceStreams.toChild$, attachData)
|
|
637
|
+
this.addChildStream(childView.sourceStreams.toParent$)
|
|
638
|
+
childView.addParentStream(this.sourceStreams.toChild$, attachData)
|
|
872
639
|
}
|
|
873
640
|
|
|
874
641
|
/**
|
|
@@ -885,18 +652,18 @@ export class ViewStream {
|
|
|
885
652
|
*
|
|
886
653
|
*/
|
|
887
654
|
appendToDom(node) {
|
|
888
|
-
//console.log("append to dom ",this.props.vsid, this.props.el);
|
|
889
|
-
if (this.props.el !== undefined){
|
|
655
|
+
// console.log("append to dom ",this.props.vsid, this.props.el);
|
|
656
|
+
if (this.props.el !== undefined) {
|
|
890
657
|
console.warn(`Spyne Warning: The ViewStream, ${this.props.name}, has an element, ${this.props.el}, that is already rendered and does not need to be appendedToDom. This may create unsusual side effects!`)
|
|
891
658
|
}
|
|
892
|
-
this.renderViewAndAttachToDom(node, 'dom', 'appendChild')
|
|
659
|
+
this.renderViewAndAttachToDom(node, 'dom', 'appendChild')
|
|
893
660
|
}
|
|
894
661
|
|
|
895
|
-
appendToDomAfter(node){
|
|
896
|
-
if (this.props.el !== undefined){
|
|
662
|
+
appendToDomAfter(node) {
|
|
663
|
+
if (this.props.el !== undefined) {
|
|
897
664
|
console.warn(`Spyne Warning: The ViewStream, ${this.props.name}, has an element, ${this.props.el}, that is already rendered and does not need to be appendedToDomAfter. This may create unsusual side effects!`)
|
|
898
665
|
}
|
|
899
|
-
this.renderViewAndAttachToDom(node, 'dom', 'after')
|
|
666
|
+
this.renderViewAndAttachToDom(node, 'dom', 'after')
|
|
900
667
|
}
|
|
901
668
|
|
|
902
669
|
/**
|
|
@@ -909,10 +676,10 @@ export class ViewStream {
|
|
|
909
676
|
*/
|
|
910
677
|
|
|
911
678
|
prependToDom(node) {
|
|
912
|
-
if (this.props.el !== undefined){
|
|
679
|
+
if (this.props.el !== undefined) {
|
|
913
680
|
console.warn(`Spyne Warning: The ViewStream, ${this.props.name}, has an element, ${this.props.el}, that is already rendered and does not need to be prependedToDom. This may create unsusual side effects!`)
|
|
914
681
|
}
|
|
915
|
-
this.renderViewAndAttachToDom(node, 'dom', 'prependChild')
|
|
682
|
+
this.renderViewAndAttachToDom(node, 'dom', 'prependChild')
|
|
916
683
|
}
|
|
917
684
|
|
|
918
685
|
/**
|
|
@@ -937,11 +704,11 @@ export class ViewStream {
|
|
|
937
704
|
*
|
|
938
705
|
* */
|
|
939
706
|
appendView(v, query) {
|
|
940
|
-
this.exchangeViewsWithChild(v, this.setAttachData('appendChild', query))
|
|
707
|
+
this.exchangeViewsWithChild(v, this.setAttachData('appendChild', query))
|
|
941
708
|
}
|
|
942
709
|
|
|
943
710
|
appendViewAfter(v, query) {
|
|
944
|
-
this.exchangeViewsWithChild(v, this.setAttachData('after', query))
|
|
711
|
+
this.exchangeViewsWithChild(v, this.setAttachData('after', query))
|
|
945
712
|
}
|
|
946
713
|
|
|
947
714
|
/**
|
|
@@ -969,7 +736,7 @@ export class ViewStream {
|
|
|
969
736
|
|
|
970
737
|
appendViewToParentEl(v, query, level = 1) {
|
|
971
738
|
this.exchangeViewsWithChild(v,
|
|
972
|
-
|
|
739
|
+
this.setAttachParentData('appendChild', query, level))
|
|
973
740
|
}
|
|
974
741
|
|
|
975
742
|
/**
|
|
@@ -992,7 +759,7 @@ export class ViewStream {
|
|
|
992
759
|
* */
|
|
993
760
|
prependViewToParentEl(v, query, level = 1) {
|
|
994
761
|
this.exchangeViewsWithChild(v,
|
|
995
|
-
|
|
762
|
+
this.setAttachParentData('prependChild', query, level))
|
|
996
763
|
}
|
|
997
764
|
|
|
998
765
|
/**
|
|
@@ -1019,15 +786,15 @@ export class ViewStream {
|
|
|
1019
786
|
* */
|
|
1020
787
|
|
|
1021
788
|
prependView(v, query) {
|
|
1022
|
-
this.exchangeViewsWithChild(v, this.setAttachData('prependChild', query))
|
|
789
|
+
this.exchangeViewsWithChild(v, this.setAttachData('prependChild', query))
|
|
1023
790
|
}
|
|
1024
791
|
|
|
1025
792
|
/**
|
|
1026
793
|
* Appends a ViewStream object that are not rendered to the #spyne-null-views div.
|
|
1027
794
|
*/
|
|
1028
795
|
appendToNull() {
|
|
1029
|
-
|
|
1030
|
-
this.renderViewAndAttachToDom(node, 'dom', 'appendChild')
|
|
796
|
+
const node = document.getElementById('spyne-null-views')
|
|
797
|
+
this.renderViewAndAttachToDom(node, 'dom', 'appendChild')
|
|
1031
798
|
}
|
|
1032
799
|
|
|
1033
800
|
onVSRendered(payload) {
|
|
@@ -1035,84 +802,83 @@ export class ViewStream {
|
|
|
1035
802
|
if (payload.from$ === 'internal') {
|
|
1036
803
|
// this.props['el'] = payload.el.el;
|
|
1037
804
|
|
|
1038
|
-
this.postRender()
|
|
805
|
+
this.postRender()
|
|
1039
806
|
// this.broadcaster = new Spyne.ViewStreamBroadcaster(this.props, this.broadcastEvents);
|
|
1040
807
|
}
|
|
1041
808
|
}
|
|
1042
809
|
|
|
1043
810
|
postRender() {
|
|
1044
|
-
this.
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
this.onRendered();
|
|
1048
|
-
const startAnimFrameAfterRendered = ()=>this.onAnimFrameAfterRendered();
|
|
1049
|
-
requestAnimationFrame(startAnimFrameAfterRendered);
|
|
811
|
+
if (this._postRenderedCalled === true) {
|
|
812
|
+
return
|
|
813
|
+
}
|
|
1050
814
|
|
|
815
|
+
this.beforeAfterRender()
|
|
816
|
+
this.afterRender()
|
|
1051
817
|
|
|
818
|
+
this.onRendered()
|
|
819
|
+
const startAnimFrameAfterRendered = () => this.onAnimFrameAfterRendered()
|
|
820
|
+
requestAnimationFrame(startAnimFrameAfterRendered)
|
|
1052
821
|
|
|
1053
|
-
if (this.isDevMode === true
|
|
1054
|
-
const eventsArr = this.broadcastEvents()
|
|
822
|
+
if (this.isDevMode === true) {
|
|
823
|
+
const eventsArr = this.broadcastEvents()
|
|
1055
824
|
const isValidArr = ViewStream.isValidNestedArr(eventsArr)
|
|
1056
|
-
if (isValidArr === false){
|
|
1057
|
-
console.warn(`Spyne Warning: The array returned from broadcastEvents in ${this.props.name}, '${JSON.stringify(eventsArr)}', does not appear to be properly formatted!`)
|
|
825
|
+
if (isValidArr === false) {
|
|
826
|
+
console.warn(`Spyne Warning: The array returned from broadcastEvents in ${this.props.name}, '${JSON.stringify(eventsArr)}', does not appear to be properly formatted!`)
|
|
1058
827
|
}
|
|
1059
|
-
|
|
1060
828
|
}
|
|
829
|
+
this.initializeChannels()
|
|
830
|
+
this.viewsStreamBroadcaster = new ViewStreamBroadcaster(this.props, this.broadcastEvents.bind(this))
|
|
831
|
+
this.afterBroadcastEvents()
|
|
1061
832
|
|
|
1062
|
-
this.
|
|
1063
|
-
this.broadcastEvents.bind(this));
|
|
1064
|
-
this.afterBroadcastEvents();
|
|
833
|
+
this._postRenderedCalled = true
|
|
1065
834
|
}
|
|
1066
835
|
|
|
1067
|
-
addTraits(traits){
|
|
1068
|
-
if (traits.constructor.name!=='Array'){
|
|
1069
|
-
traits = [traits]
|
|
836
|
+
addTraits(traits) {
|
|
837
|
+
if (traits.constructor.name !== 'Array') {
|
|
838
|
+
traits = [traits]
|
|
839
|
+
}
|
|
840
|
+
const addTrait = (TraitClass) => {
|
|
841
|
+
new TraitClass(this)
|
|
1070
842
|
}
|
|
1071
|
-
const addTrait=(TraitClass)=>{
|
|
1072
|
-
new TraitClass(this);
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
|
-
traits.forEach(addTrait);
|
|
1076
843
|
|
|
844
|
+
traits.forEach(addTrait)
|
|
1077
845
|
}
|
|
1078
846
|
|
|
1079
847
|
// ================================= METHODS TO BE EXTENDED ==============================
|
|
1080
848
|
|
|
1081
|
-
afterBroadcastEvents(){
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
const
|
|
1085
|
-
const nestedActionsArr = this.addActionListeners();
|
|
849
|
+
afterBroadcastEvents() {
|
|
850
|
+
if (this.isDevMode === true) {
|
|
851
|
+
const pullActionsFromList = (arr) => arr[0]
|
|
852
|
+
const nestedActionsArr = this.addActionListeners()
|
|
1086
853
|
|
|
1087
|
-
|
|
854
|
+
const actionsArr = nestedActionsArr.map(pullActionsFromList)
|
|
1088
855
|
|
|
1089
|
-
const isValidArr = ViewStream.isValidNestedArr(nestedActionsArr)
|
|
856
|
+
const isValidArr = ViewStream.isValidNestedArr(nestedActionsArr)
|
|
1090
857
|
|
|
1091
|
-
if (isValidArr === false){
|
|
1092
|
-
console.warn(`Spyne Warning: The array returned from addActionsListeners in ${this.props.name}, '${JSON.stringify(nestedActionsArr)}', does not appear to be properly formatted!`)
|
|
858
|
+
if (isValidArr === false) {
|
|
859
|
+
console.warn(`Spyne Warning: The array returned from addActionsListeners in ${this.props.name}, '${JSON.stringify(nestedActionsArr)}', does not appear to be properly formatted!`)
|
|
1093
860
|
} else {
|
|
1094
|
-
const checkForExistingMethod = (arr)=>{
|
|
1095
|
-
const method = defaultTo('', arr[1])
|
|
1096
|
-
const isMethod = is(Function, this[method])
|
|
1097
|
-
if (isMethod === false){
|
|
1098
|
-
console.warn(`Spyne Warning: The method in addActionListeners nested Array, '${JSON.stringify(arr)}', in ${this.props.name}, does not appear to exist!`)
|
|
861
|
+
const checkForExistingMethod = (arr) => {
|
|
862
|
+
const method = defaultTo('', arr[1])
|
|
863
|
+
const isMethod = is(Function, this[method])
|
|
864
|
+
if (isMethod === false) {
|
|
865
|
+
console.warn(`Spyne Warning: The method in addActionListeners nested Array, '${JSON.stringify(arr)}', in ${this.props.name}, does not appear to exist!`)
|
|
1099
866
|
}
|
|
1100
|
-
|
|
1101
867
|
}
|
|
1102
|
-
compose(forEach(checkForExistingMethod), defaultTo([]))(nestedActionsArr)
|
|
868
|
+
compose(forEach(checkForExistingMethod), defaultTo([]))(nestedActionsArr)
|
|
1103
869
|
}
|
|
1104
870
|
|
|
1105
|
-
const delayForProxyChannelResets = ()=>{
|
|
1106
|
-
if (path(['props','addedChannels'], this) !== undefined) {
|
|
1107
|
-
ViewStream.checkIfActionsAreRegistered.bind(this)(this.props.addedChannels, actionsArr)
|
|
871
|
+
const delayForProxyChannelResets = () => {
|
|
872
|
+
if (path(['props', 'addedChannels'], this) !== undefined) {
|
|
873
|
+
ViewStream.checkIfActionsAreRegistered.bind(this)(this.props.addedChannels, actionsArr)
|
|
1108
874
|
}
|
|
1109
|
-
}
|
|
1110
|
-
this.setTimeout(delayForProxyChannelResets, 500)
|
|
875
|
+
}
|
|
876
|
+
this.setTimeout(delayForProxyChannelResets, 500)
|
|
1111
877
|
}
|
|
1112
878
|
}
|
|
1113
879
|
|
|
1114
|
-
setDataVSID(){
|
|
1115
|
-
this.props.el.dataset.vsid = this.props.vsid
|
|
880
|
+
setDataVSID() {
|
|
881
|
+
this.props.el.dataset.vsid = this.props.vsid// String(this.props.vsid).replace(/^(vsid-)(.*)$/, '$2');
|
|
1116
882
|
}
|
|
1117
883
|
|
|
1118
884
|
beforeAfterRender() {
|
|
@@ -1120,11 +886,11 @@ export class ViewStream {
|
|
|
1120
886
|
return function(str = '') {
|
|
1121
887
|
return new DomItemSelectors(el, str);
|
|
1122
888
|
};
|
|
1123
|
-
}
|
|
889
|
+
}; */
|
|
1124
890
|
|
|
1125
|
-
//this.props.el$ = dm2(this.props.el);
|
|
1126
|
-
this.setDataVSID()
|
|
1127
|
-
this.props.el$ = ViewStreamSelector(this.props.el)
|
|
891
|
+
// this.props.el$ = dm2(this.props.el);
|
|
892
|
+
this.setDataVSID()
|
|
893
|
+
this.props.el$ = ViewStreamSelector(this.props.el)
|
|
1128
894
|
// console.log('EL IS ', this.props.el$.elArr);
|
|
1129
895
|
// window.theEl$ = this.props.el$;
|
|
1130
896
|
}
|
|
@@ -1163,7 +929,7 @@ export class ViewStream {
|
|
|
1163
929
|
|
|
1164
930
|
broadcastEvents() {
|
|
1165
931
|
// ADD BUTTON EVENTS AS NESTED ARRAYS
|
|
1166
|
-
return []
|
|
932
|
+
return []
|
|
1167
933
|
}
|
|
1168
934
|
|
|
1169
935
|
/**
|
|
@@ -1182,18 +948,31 @@ export class ViewStream {
|
|
|
1182
948
|
* */
|
|
1183
949
|
|
|
1184
950
|
getChannel(channel) {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
`channel name ${c} is not within ${registeredStreamNames}`)
|
|
1188
|
-
|
|
1189
|
-
|
|
951
|
+
const isValidChannel = c => registeredStreamNames().includes(c)
|
|
952
|
+
const error = c => console.warn(
|
|
953
|
+
`channel name ${c} is not within ${registeredStreamNames}`)
|
|
954
|
+
const startSubscribe = (c) => {
|
|
955
|
+
const obs$ = SpyneAppProperties.channelsMap.getStream(c).observer
|
|
956
|
+
|
|
957
|
+
return obs$.pipe(takeWhile(p => this.deleted !== true))
|
|
958
|
+
}// getGlobalParam('streamsController').getStream(c).observer;
|
|
1190
959
|
|
|
1191
|
-
|
|
1192
|
-
};// getGlobalParam('streamsController').getStream(c).observer;
|
|
960
|
+
const fn = ifElse(isValidChannel, startSubscribe, error)
|
|
1193
961
|
|
|
1194
|
-
|
|
962
|
+
return fn(channel)
|
|
963
|
+
}
|
|
1195
964
|
|
|
1196
|
-
|
|
965
|
+
/**
|
|
966
|
+
* CHECKS TO SEE IF CHANNELS HAVE BEEN ADDED TO props.channels object;
|
|
967
|
+
*/
|
|
968
|
+
initializeChannels() {
|
|
969
|
+
const addChannel = (channel) => {
|
|
970
|
+
const [channelName, skipFirst = false] = Array.isArray(channel) ? channel : [channel]
|
|
971
|
+
this?.addChannel(channelName, skipFirst)
|
|
972
|
+
}
|
|
973
|
+
if (Array.isArray(this?.props?.channels)) {
|
|
974
|
+
this?.props?.channels?.forEach(addChannel)
|
|
975
|
+
}
|
|
1197
976
|
}
|
|
1198
977
|
|
|
1199
978
|
/**
|
|
@@ -1223,46 +1002,46 @@ export class ViewStream {
|
|
|
1223
1002
|
*
|
|
1224
1003
|
* */
|
|
1225
1004
|
|
|
1226
|
-
addChannel(
|
|
1227
|
-
|
|
1228
|
-
const directionArr = sendDownStream === true ? this.$dirs.CI : this.$dirs.I;
|
|
1005
|
+
addChannel(channelName, skipFirst = false, sendDownStream = false, bool = false) {
|
|
1006
|
+
const directionArr = sendDownStream === true ? this.$dirs.CI : this.$dirs.I
|
|
1229
1007
|
const mapDirection = p => {
|
|
1230
|
-
//et p2 = defaultTo({}, clone(p));
|
|
1231
|
-
|
|
1232
|
-
pl
|
|
1233
|
-
return pl
|
|
1234
|
-
//return deepMerge(dirObj, p2);
|
|
1008
|
+
// et p2 = defaultTo({}, clone(p));
|
|
1009
|
+
const pl = p// || {};
|
|
1010
|
+
pl.$dir = directionArr
|
|
1011
|
+
return pl
|
|
1012
|
+
// return deepMerge(dirObj, p2);
|
|
1235
1013
|
// Object.assign({$dir: directionArr}, clone(p))
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
const
|
|
1014
|
+
}
|
|
1015
|
+
if (this?.props?.addedChannels?.includes(channelName) === true) {
|
|
1016
|
+
// CHECKS IF CHANNEL HAS ALREADY BEEN ADDED
|
|
1017
|
+
return
|
|
1018
|
+
}
|
|
1019
|
+
const isLocalEventCheck = path(['srcElement', 'isLocalEvent'])
|
|
1020
|
+
const cidCheck = path(['srcElement', 'vsid'])
|
|
1242
1021
|
const cidMatches = p => {
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
const filterEvent = isLocalEvent !== true || vsid === this.props.vsid
|
|
1022
|
+
const vsid = cidCheck(p)
|
|
1023
|
+
const isLocalEvent = isLocalEventCheck(p)
|
|
1024
|
+
const filterEvent = isLocalEvent !== true || vsid === this.props.vsid
|
|
1246
1025
|
// console.log("checks ",vsid,this.props.vsid, isLocalEvent,filterEvent);
|
|
1247
|
-
return filterEvent
|
|
1248
|
-
}
|
|
1026
|
+
return filterEvent
|
|
1027
|
+
}
|
|
1249
1028
|
|
|
1250
1029
|
const pipeArr = [map(mapDirection), filter(cidMatches)]
|
|
1251
|
-
if (skipFirst === true){
|
|
1252
|
-
pipeArr.unshift(skip(1))
|
|
1030
|
+
if (skipFirst === true) {
|
|
1031
|
+
pipeArr.unshift(skip(1))
|
|
1253
1032
|
}
|
|
1254
1033
|
|
|
1255
|
-
|
|
1256
|
-
this.updateSourceSubscription(channel$, false)
|
|
1257
|
-
this.props.addedChannels.push(
|
|
1034
|
+
const channel$ = this.getChannel(channelName).pipe(...pipeArr)
|
|
1035
|
+
this.updateSourceSubscription(channel$, false)
|
|
1036
|
+
this.props.addedChannels.push(channelName)
|
|
1258
1037
|
}
|
|
1259
1038
|
|
|
1260
1039
|
checkIfChannelExists(channelName) {
|
|
1261
|
-
|
|
1040
|
+
const channelExists = SpyneAppProperties.channelsMap.testStream(channelName)
|
|
1262
1041
|
if (channelExists !== true) {
|
|
1263
|
-
console.warn(`SPYNE WARNING: The ChannelPayload from ${this.props.name}, has been sent to a channel, ${channelName}, that has not been registered!`)
|
|
1042
|
+
console.warn(`SPYNE WARNING: The ChannelPayload from ${this.props.name}, has been sent to a channel, ${channelName}, that has not been registered!`)
|
|
1264
1043
|
}
|
|
1265
|
-
return channelExists
|
|
1044
|
+
return channelExists
|
|
1266
1045
|
}
|
|
1267
1046
|
|
|
1268
1047
|
/**
|
|
@@ -1280,41 +1059,38 @@ export class ViewStream {
|
|
|
1280
1059
|
*/
|
|
1281
1060
|
|
|
1282
1061
|
sendInfoToChannel(channelName, pl = {}, action) {
|
|
1283
|
-
const payload = pl
|
|
1062
|
+
const payload = pl
|
|
1284
1063
|
|
|
1285
|
-
|
|
1064
|
+
const defaultToAction = defaultTo('VIEWSTREAM_EVENT')
|
|
1286
1065
|
const channelDefaultActionHash = {
|
|
1287
|
-
CHANNEL_ROUTE:
|
|
1066
|
+
CHANNEL_ROUTE: 'CHANNEL_ROUTE_CHANGE_EVENT'
|
|
1288
1067
|
}
|
|
1289
1068
|
const getActionFn = compose(defaultToAction, prop(channelName))
|
|
1290
1069
|
|
|
1291
|
-
action = action || getActionFn(channelDefaultActionHash)
|
|
1070
|
+
action = action || getActionFn(channelDefaultActionHash)
|
|
1292
1071
|
|
|
1072
|
+
const data = { payload, action }
|
|
1293
1073
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
}
|
|
1308
|
-
let obs$ = of(data);
|
|
1309
|
-
return new ViewStreamPayload(channelName, obs$, data);
|
|
1310
|
-
|
|
1074
|
+
try {
|
|
1075
|
+
data.srcElement = compose(pick(['id', 'vsid', 'class', 'tagName']), prop('props'))(this)
|
|
1076
|
+
if (this.checkIfChannelExists(channelName) === true) {
|
|
1077
|
+
if (/CHANNEL_LIFECYCLE/.test(action) === false) {
|
|
1078
|
+
Object.defineProperties(data, {
|
|
1079
|
+
payload: {
|
|
1080
|
+
get: () => safeClone(pl)
|
|
1081
|
+
}
|
|
1082
|
+
})
|
|
1083
|
+
}
|
|
1084
|
+
const obs$ = of(data)
|
|
1085
|
+
return new ViewStreamPayload(channelName, obs$, data)
|
|
1311
1086
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1087
|
+
} catch (e) {
|
|
1088
|
+
console.warn('SPYNE WARNING ', e)
|
|
1089
|
+
}
|
|
1314
1090
|
}
|
|
1315
1091
|
|
|
1316
1092
|
tracer(...args) {
|
|
1317
|
-
this.sendLifecycleMethod(...args)
|
|
1093
|
+
this.sendLifecycleMethod(...args)
|
|
1318
1094
|
}
|
|
1319
1095
|
|
|
1320
1096
|
sendLifecycleMethodInactive() {
|
|
@@ -1322,27 +1098,27 @@ export class ViewStream {
|
|
|
1322
1098
|
}
|
|
1323
1099
|
|
|
1324
1100
|
sendLifecycleMethodActive(val, p) {
|
|
1325
|
-
|
|
1101
|
+
const isRendered = where({
|
|
1326
1102
|
from$: equals('internal'),
|
|
1327
1103
|
action: equals('VS_SPAWNED_AND_ATTACHED_TO_PARENT')
|
|
1328
|
-
}, p)
|
|
1329
|
-
|
|
1104
|
+
}, p)
|
|
1105
|
+
const isDisposed = p === 'VS_DETRITUS_COLLECT'
|
|
1330
1106
|
if (isRendered === true) {
|
|
1331
|
-
this.sendInfoToChannel('CHANNEL_LIFECYCLE', { action:'CHANNEL_LIFECYCLE_RENDERED_EVENT' }, 'CHANNEL_LIFECYCLE_RENDERED_EVENT')
|
|
1107
|
+
this.sendInfoToChannel('CHANNEL_LIFECYCLE', { action:'CHANNEL_LIFECYCLE_RENDERED_EVENT' }, 'CHANNEL_LIFECYCLE_RENDERED_EVENT')
|
|
1332
1108
|
} else if (isDisposed === true) {
|
|
1333
|
-
this.sendInfoToChannel('CHANNEL_LIFECYCLE', { action:'CHANNEL_LIFECYCLE_DISPOSED_EVENT' }, 'CHANNEL_LIFECYCLE_DISPOSED_EVENT')
|
|
1109
|
+
this.sendInfoToChannel('CHANNEL_LIFECYCLE', { action:'CHANNEL_LIFECYCLE_DISPOSED_EVENT' }, 'CHANNEL_LIFECYCLE_DISPOSED_EVENT')
|
|
1334
1110
|
}
|
|
1335
1111
|
}
|
|
1336
1112
|
|
|
1337
1113
|
createActionFilter(selectors, data) {
|
|
1338
|
-
return new ChannelPayloadFilter(selectors, data)
|
|
1114
|
+
return new ChannelPayloadFilter(selectors, data)
|
|
1339
1115
|
}
|
|
1340
1116
|
|
|
1341
1117
|
isLocalEvent(channelPayloadItem) {
|
|
1342
|
-
const itemEl = path(['srcElement', 'el'], channelPayloadItem)
|
|
1343
|
-
const thisEl = path(['props', 'el'], this)
|
|
1344
|
-
//console.log('this el is ',{thisEl, itemEl});
|
|
1345
|
-
return ViewStream.elIsDomElement(thisEl) && ViewStream.elIsDomElement(itemEl) && thisEl.contains(itemEl)
|
|
1118
|
+
const itemEl = path(['srcElement', 'el'], channelPayloadItem)
|
|
1119
|
+
const thisEl = path(['props', 'el'], this)
|
|
1120
|
+
// console.log('this el is ',{thisEl, itemEl});
|
|
1121
|
+
return ViewStream.elIsDomElement(thisEl) && ViewStream.elIsDomElement(itemEl) && thisEl.contains(itemEl)
|
|
1346
1122
|
}
|
|
1347
1123
|
|
|
1348
1124
|
// =======================================================================================
|
|
@@ -1350,7 +1126,7 @@ export class ViewStream {
|
|
|
1350
1126
|
// ==================================
|
|
1351
1127
|
// BASE CORE MIXINS
|
|
1352
1128
|
// ==================================
|
|
1353
|
-
|
|
1354
|
-
this.createId = coreMixins.createId
|
|
1129
|
+
const coreMixins = baseCoreMixins()
|
|
1130
|
+
this.createId = coreMixins.createId
|
|
1355
1131
|
}
|
|
1356
1132
|
}
|