spyne 0.20.4 → 0.20.7

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.
Files changed (36) hide show
  1. package/lib/spyne.esm.js +13 -8
  2. package/lib/spyne.esm.js.map +1 -1
  3. package/lib/spyne.umd.js +2 -2
  4. package/lib/spyne.umd.js.LICENSE.txt +12 -7
  5. package/package.json +1 -1
  6. package/src/spyne/channels/channel-fetch-class.js +15 -12
  7. package/src/spyne/channels/channel-payload-class.js +2 -2
  8. package/src/spyne/channels/channel-proxy.js +3 -3
  9. package/src/spyne/channels/channel.js +77 -10
  10. package/src/spyne/channels/channels-config.js +1 -1
  11. package/src/spyne/channels/channels-map.js +5 -5
  12. package/src/spyne/channels/spyne-channel-lifecycle.js +1 -1
  13. package/src/spyne/channels/spyne-channel-route.js +43 -6
  14. package/src/spyne/channels/spyne-channel-ui.js +17 -1
  15. package/src/spyne/channels/spyne-channel-window.js +5 -5
  16. package/src/spyne/spyne-app.js +19 -12
  17. package/src/spyne/spyne-plugins.js +17 -2
  18. package/src/spyne/spyne.js +19 -19
  19. package/src/spyne/utils/channel-fetch-util.js +2 -0
  20. package/src/spyne/utils/channel-payload-filter.js +19 -2
  21. package/src/spyne/utils/mixins/base-streams-mixins.js +1 -1
  22. package/src/spyne/utils/route-channel-updater.js +1 -1
  23. package/src/spyne/utils/safe-clone.js +1 -1
  24. package/src/spyne/utils/spyne-app-properties.js +73 -7
  25. package/src/spyne/utils/spyne-trait.js +1 -1
  26. package/src/spyne/utils/spyne-utils-channel-route-url.js +16 -2
  27. package/src/spyne/utils/spyne-utils-channel-route.js +1 -1
  28. package/src/spyne/views/dom-element-template.js +5 -2
  29. package/src/spyne/views/dom-element.js +3 -3
  30. package/src/spyne/views/view-stream-broadcaster.js +15 -4
  31. package/src/spyne/views/view-stream-element.js +12 -7
  32. package/src/spyne/views/view-stream-payload.js +3 -3
  33. package/src/spyne/views/view-stream-selector.js +1 -1
  34. package/src/spyne/views/view-stream.js +22 -18
  35. package/src/tests/utils/channel-data-packet-generator.unused.js +1 -1
  36. package/src/spyne/utils/channel-config-validator.js +0 -14
@@ -1,16 +1,21 @@
1
1
  /*!
2
- * Spyne 0.20.4
2
+ * Spyne 0.20.7
3
3
  * https://spynejs.org
4
4
  *
5
- * @license Copyright 2017-2021, Frank Batista, Relevant Context, LLC. All rights reserved.
6
- * Spyne is licensed under the GNU Lesser General Public License v3.0
5
+ * @license
6
+ * Copyright 2017-2025, Frank Batista,
7
+ * Relevant Context, LLC. All rights reserved.
7
8
  *
8
- * @author: Frank Batista,
9
- * @email: frbatista.nyc@gmail.com
10
- */
9
+ * Licensed under the GNU Lesser General Public License v3.0 (the "License");
10
+ * You may not use this file except in compliance with the License.
11
+ * A copy of the License is located in the project root, or at:
12
+ * https://www.gnu.org/licenses/lgpl-3.0.html
13
+ *
14
+ * This notice may not be removed or altered from any distribution.
15
+ */
11
16
 
12
17
  /*!
13
- * spynejs 0.20.4
18
+ * spynejs 0.20.7
14
19
  * https://spynejs.org
15
20
  * (c) 2017-present Frank Batista
16
21
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spyne",
3
- "version": "0.20.4",
3
+ "version": "0.20.7",
4
4
  "description": "Reactive Real-DOM Framework for Advanced Javascript applications",
5
5
  "sideEffects": true,
6
6
  "main": "./lib/spyne.esm.js",
@@ -1,5 +1,5 @@
1
- import { Channel } from './channel'
2
- import { ChannelFetchUtil } from '../utils/channel-fetch-util'
1
+ import { Channel } from './channel.js'
2
+ import { ChannelFetchUtil } from '../utils/channel-fetch-util.js'
3
3
  import { path, pick, mergeDeepRight, all, allPass, either, values, defaultTo, reject, compose, isNil } from 'ramda'
4
4
 
5
5
  export class ChannelFetch extends Channel {
@@ -16,12 +16,12 @@ export class ChannelFetch extends Channel {
16
16
  * <li>Extends Channel and uses the ChannelFetchUtil to make any type of http(s) request.</li>
17
17
  * <li>Requires a url property at instantiation.</li>
18
18
  * <li>The response data is published as a ChannelPayload.</li>
19
- * <li>The action for the returned ChannelFetch data is always in the following format, "CHANNEL_NAME_DATA_EVENT"</li>
19
+ * <li>The action for the returned ChannelFetch data is always in the following format, "CHANNEL_NAME_RESPONSE_EVENT"</li>
20
20
  * <li>The default request type is a GET request that returns a JSON object.</li>
21
21
  * <li>However, any type of request and return type can be configured by using the body property when creating the instance.</li>
22
22
  * <li>The mapFn gives access to the returned response and can be use to parse the data before it is published to other Channels and ViewStream instances.</li>
23
23
  * <li>Channel Fetch will send the last response to future subscribers, and will not make further http(s) requests unless directed to do so.</li>
24
- * <li>Data can be Fetched again, by sending a "CHANNEL_NAME_UPDATE_DATA_EVENT" action from a ViewStream's sendInfoToChannel method.</li>
24
+ * <li>Data can be Fetched again, by sending a "CHANNEL_NAME_UPDATE_RESPONSE_EVENT" action from a ViewStream's sendInfoToChannel method.</li>
25
25
  * </ul>
26
26
  *
27
27
  * @constructor
@@ -35,7 +35,7 @@ export class ChannelFetch extends Channel {
35
35
  *
36
36
  * @example
37
37
  * TITLE["<h4>A ViewStream Instance Sending A Fetch Update Request</h4>"]
38
- * const action = "CHANNEL_FETCHCHANNEL_NAME_UPDATE_DATA_EVENT";
38
+ * const action = "CHANNEL_FETCHCHANNEL_NAME_UPDATE_RESPONSE_EVENT";
39
39
  * const url = "//site.com/json/";
40
40
  * const body = {
41
41
  * method: "POST"
@@ -55,8 +55,8 @@ export class ChannelFetch extends Channel {
55
55
  props.mapFn = props.map
56
56
  }
57
57
  props.extendedActionsArr = [
58
- `${name}_DATA_EVENT`,
59
- [`${name}_UPDATE_DATA_EVENT`, 'onFetchUpdate']
58
+ `${name}_RESPONSE_EVENT`,
59
+ [`${name}_REQUEST_EVENT`, 'onFetchUpdate']
60
60
  ]
61
61
  props.sendCachedPayload = true
62
62
  super(name, props)
@@ -80,14 +80,17 @@ export class ChannelFetch extends Channel {
80
80
  return true
81
81
  }
82
82
 
83
- onRegistered() {
84
- this.startFetch()
83
+ onRegistered(props = this.props) {
84
+ if (props?.pause !== true) {
85
+ this.startFetch()
86
+ }
85
87
  }
86
88
 
87
89
  addRegisteredActions(name) {
88
90
  const arr = [
89
- 'CHANNEL_DATA_EVENT',
90
- ['CHANNEL_UPDATE_DATA_EVENT', 'onFetchUpdate']
91
+ 'CHANNEL_RESPONSE_EVENT',
92
+ ['CHANNEL_UPDATE_RESPONSE_EVENT', 'onFetchUpdate'],
93
+ ['CHANNEL_FETCH_REQUEST_EVENT', 'onFetchUpdate']
91
94
  ]
92
95
 
93
96
  const extendedArr = compose(defaultTo([]), path(['props', 'extendedActionsArr']))
@@ -108,7 +111,7 @@ export class ChannelFetch extends Channel {
108
111
  return this.createChannelPayloadItem(streamItem)
109
112
  }
110
113
 
111
- createChannelPayloadItem(payload, action = `${this.props.name}_DATA_EVENT`) {
114
+ createChannelPayloadItem(payload, action = `${this.props.name}_RESPONSE_EVENT`) {
112
115
  const { name, sendCachedPayload, url } = this.props
113
116
  const srcElement = { name, sendCachedPayload, url }
114
117
  this.sendChannelPayload(action, payload, srcElement)
@@ -11,8 +11,8 @@ import {
11
11
  prop,
12
12
  is
13
13
  } from 'ramda'
14
- import { SpyneAppProperties } from '../utils/spyne-app-properties'
15
- import { safeClone } from '../utils/safe-clone'
14
+ import { SpyneAppProperties } from '../utils/spyne-app-properties.js'
15
+ import { safeClone } from '../utils/safe-clone.js'
16
16
 
17
17
  export class ChannelPayload {
18
18
  /**
@@ -1,8 +1,8 @@
1
- import { Channel } from './channel'
2
- import { SpyneAppProperties } from '../utils/spyne-app-properties'
1
+ import { Channel } from './channel.js'
2
+ import { SpyneAppProperties } from '../utils/spyne-app-properties.js'
3
3
  import { Subject, ReplaySubject, merge } from 'rxjs'
4
4
  import { includes } from 'ramda'
5
- import { delayCall } from '../utils/frp-tools'
5
+ import { delayCall } from '../utils/frp-tools.js'
6
6
 
7
7
  export class ChannelProxy extends Channel {
8
8
  /**
@@ -1,9 +1,10 @@
1
- import { registeredStreamNames } from './channels-config'
2
- import { ChannelPayload } from './channel-payload-class'
3
- import { SpyneAppProperties } from '../utils/spyne-app-properties'
4
- import { RouteChannelUpdater } from '../utils/route-channel-updater'
5
- import { ReplaySubject, Subject } from 'rxjs'
6
- import { filter, map } from 'rxjs/operators'
1
+ import { registeredStreamNames } from './channels-config.js'
2
+ import { ChannelPayload } from './channel-payload-class.js'
3
+ import { SpyneAppProperties } from '../utils/spyne-app-properties.js'
4
+ import { RouteChannelUpdater } from '../utils/route-channel-updater.js'
5
+
6
+ import { ReplaySubject, Subject, forkJoin, EMPTY } from 'rxjs'
7
+ import { filter, map, take, combineLatestWith } from 'rxjs/operators'
7
8
  import {
8
9
  ifElse,
9
10
  identity,
@@ -69,22 +70,45 @@ export class Channel {
69
70
  constructor(CHANNEL_NAME, props = {}) {
70
71
  this.addRegisteredActions.bind(this)
71
72
  this.createChannelActionsObj(CHANNEL_NAME, props.extendedActionsArr)
73
+
74
+ // Basic props setup
72
75
  props.name = CHANNEL_NAME
73
76
  props.defaultActions = props.data !== undefined ? [`${props.name}_EVENT`] : []
74
77
  this.props = props
78
+
75
79
  this.props.isRegistered = false
76
- this.props.isProxy = this.props.isProxy === undefined ? false : this.props.isProxy
80
+ this.props.isProxy =
81
+ this.props.isProxy === undefined ? false : this.props.isProxy
82
+
83
+ // Determine a default from presence of props.data
77
84
  const defaultCachedPayloadBool = this.props.data !== undefined
78
- this.props.sendCachedPayload = this.props.sendCachedPayload === undefined ? defaultCachedPayloadBool : this.props.sendCachedPayload
85
+
86
+ // If props.replay is defined, override sendCachedPayload with it.
87
+ // Otherwise, use the existing sendCachedPayload property or default.
88
+ if (typeof this.props.replay !== 'undefined') {
89
+ this.props.sendCachedPayload = this.props.replay
90
+ } else {
91
+ this.props.sendCachedPayload =
92
+ this.props.sendCachedPayload === undefined
93
+ ? defaultCachedPayloadBool
94
+ : this.props.sendCachedPayload
95
+ }
96
+
79
97
  this.sendPayloadToRouteChannel = new RouteChannelUpdater(this)
80
98
  this.createChannelActionMethods()
99
+
100
+ // Set up streams
81
101
  this.streamsController = SpyneAppProperties.channelsMap
82
102
  const observer$ = this.getMainObserver()
83
103
  this.checkForPersistentDataMode = Channel.checkForPersistentDataMode.bind(this)
84
104
  this.observer$ = this.props.observer = observer$
105
+
106
+ // Subscribe to DISPATCHER
85
107
  const dispatcherStream$ = this.streamsController.getStream('DISPATCHER')
86
108
  const payloadPredByChannelName = propEq(props.name, 'name')
87
- dispatcherStream$.pipe(filter(payloadPredByChannelName)).subscribe((val) => this.onReceivedObservable(val))
109
+ dispatcherStream$
110
+ .pipe(filter(payloadPredByChannelName))
111
+ .subscribe((val) => this.onReceivedObservable(val))
88
112
  }
89
113
 
90
114
  getMainObserver() {
@@ -324,7 +348,7 @@ export class Channel {
324
348
  *
325
349
  *
326
350
  */
327
- onViewStreamInfo(obj) {
351
+ onViewStreamInfo(obs) {
328
352
  }
329
353
 
330
354
  /**
@@ -398,6 +422,49 @@ export class Channel {
398
422
  return fn(channelName)
399
423
  }
400
424
 
425
+ /**
426
+ * Merge Channels is a convenience method to forkJoin Channel.observer$
427
+ *
428
+ * */
429
+
430
+ mergeChannels(channelsArr, emitOnce = true) {
431
+ // 1) Normalize inputs to Observables
432
+ const channelObservables = channelsArr.map(item => {
433
+ if (typeof item === 'string') {
434
+ const chan$ = this.getChannel(item)
435
+ return emitOnce ? chan$.pipe(take(1)) : chan$
436
+ }
437
+ return emitOnce ? item.pipe(take(1)) : item
438
+ })
439
+
440
+ // 2) Combine them
441
+ let combined$
442
+ if (emitOnce) { // one‑shot: snapshot then complete
443
+ combined$ = forkJoin(channelObservables)
444
+ } else { // live updates: combineLatestWith
445
+ if (channelObservables.length === 0) {
446
+ combined$ = EMPTY
447
+ } else if (channelObservables.length === 1) {
448
+ combined$ = channelObservables[0]
449
+ } else {
450
+ const [first$, ...rest$] = channelObservables
451
+ combined$ = first$.pipe(combineLatestWith(...rest$))
452
+ }
453
+ }
454
+
455
+ // 3) Map array → keyed object
456
+ return combined$.pipe(
457
+ map(resultsArr => {
458
+ const obj = {}
459
+ channelsArr.forEach((item, idx) => {
460
+ const key = typeof item === 'string' ? item : `channel_${idx}`
461
+ obj[key] = resultsArr[idx]
462
+ })
463
+ return obj
464
+ })
465
+ )
466
+ }
467
+
401
468
  static checkForNotTrackFlag(props = {}) {
402
469
  if (props.doNotTrack === true) {
403
470
  SpyneAppProperties.doNotTrackChannel(props.channelName)
@@ -1,4 +1,4 @@
1
- import { SpyneAppProperties } from '../utils/spyne-app-properties'
1
+ import { SpyneAppProperties } from '../utils/spyne-app-properties.js'
2
2
  import { compose, path, is } from 'ramda'
3
3
  import { Observable, Subject } from 'rxjs'
4
4
 
@@ -1,10 +1,10 @@
1
- import { SpyneChannelRoute } from './spyne-channel-route'
2
- import { SpyneChannelUI } from './spyne-channel-ui'
3
- import { SpyneChannelWindow } from './spyne-channel-window'
4
- import { SpyneChannelLifecycle } from './spyne-channel-lifecycle'
1
+ import { SpyneChannelRoute } from './spyne-channel-route.js'
2
+ import { SpyneChannelUI } from './spyne-channel-ui.js'
3
+ import { SpyneChannelWindow } from './spyne-channel-window.js'
4
+ import { SpyneChannelLifecycle } from './spyne-channel-lifecycle.js'
5
5
 
6
6
  import { Subject } from 'rxjs'
7
- import { ChannelProxy } from './channel-proxy'
7
+ import { ChannelProxy } from './channel-proxy.js'
8
8
  import { propEq, pluck, prop, filter, pathEq, reject, compose, join, map as rMap } from 'ramda'
9
9
 
10
10
  const _map = new Map()
@@ -1,4 +1,4 @@
1
- import { Channel } from './channel'
1
+ import { Channel } from './channel.js'
2
2
 
3
3
  export class SpyneChannelLifecycle extends Channel {
4
4
  /**
@@ -1,7 +1,7 @@
1
- import { Channel } from './channel'
2
- import { SpyneUtilsChannelRouteUrl } from '../utils/spyne-utils-channel-route-url'
3
- import { SpyneUtilsChannelRoute } from '../utils/spyne-utils-channel-route'
4
- import { SpyneAppProperties } from '../utils/spyne-app-properties'
1
+ import { Channel } from './channel.js'
2
+ import { SpyneUtilsChannelRouteUrl } from '../utils/spyne-utils-channel-route-url.js'
3
+ import { SpyneUtilsChannelRoute } from '../utils/spyne-utils-channel-route.js'
4
+ import { SpyneAppProperties } from '../utils/spyne-app-properties.js'
5
5
  import { ReplaySubject, merge } from 'rxjs'
6
6
  import { map } from 'rxjs/operators'
7
7
 
@@ -184,6 +184,9 @@ export class SpyneChannelRoute extends Channel {
184
184
  const routeConfig = this.getRouteConfig()
185
185
  const action = 'CHANNEL_ROUTE_CONFIG_UPDATED_EVENT'
186
186
 
187
+ // reverse because routeDatasetsArr turns out that way
188
+ routeConfig.navLinks = [...routeConfig?.routeDatasetsArr]
189
+
187
190
  this.routeConfigJson = routeConfig
188
191
  this.bindStaticMethodsWithConfigData()
189
192
 
@@ -237,7 +240,23 @@ export class SpyneChannelRoute extends Channel {
237
240
  }
238
241
  // ===============================================================
239
242
  if (actn === 'CHANNEL_ROUTE_DEEPLINK_EVENT') {
240
- payload.linksData = prop('routeDatasetsArr', config)
243
+ payload.navLinks = prop('routeDatasetsArr', config)
244
+ // payload.linksData = payload.navLinks
245
+ // SpyneAppProperties.linksData = payload.navLinks
246
+
247
+ // define an alias property using Object.defineProperty
248
+ Object.defineProperty(payload, 'linksData', {
249
+ get() {
250
+ console.warn('get links data is deprecated in ROUTE DEEPLINK DATA, use navLinks')
251
+ return this.navLinks
252
+ },
253
+ set(value) {
254
+ console.warn('set links data is deprecated in ROUTE DEEPLINK DATA, use navLinks')
255
+
256
+ // this.navLinks = value;
257
+ },
258
+ enumerable: true
259
+ })
241
260
  }
242
261
  const keywordArrs = this.compareRouteKeywords.compare(payload.routeData, payload.paths)
243
262
  payload = rMerge(payload, keywordArrs)
@@ -335,7 +354,25 @@ export class SpyneChannelRoute extends Channel {
335
354
  }
336
355
 
337
356
  onViewStreamInfo(pl) {
338
- const action = this.channelActions.CHANNEL_ROUTE_CHANGE_EVENT
357
+ const action = pl.action ?? this.channelActions.CHANNEL_ROUTE_CHANGE_EVENT
358
+
359
+ function domStringMapToObject(domStringMap) {
360
+ const obj = {}
361
+ for (const key in domStringMap) {
362
+ // Check if it’s a direct property (though dataset rarely has anything on the prototype):
363
+ if (Object.prototype.hasOwnProperty.call(domStringMap, key)) {
364
+ obj[key] = domStringMap[key]
365
+ }
366
+ }
367
+ return obj
368
+ }
369
+
370
+ if (pl?.srcElement?.el?.dataset) {
371
+ pl.payload = domStringMapToObject(pl?.srcElement?.el?.dataset) ?? pl.payload
372
+ }
373
+
374
+ // console.log('ROUTE CHANNEL VSI ', { pl })
375
+
339
376
  SpyneChannelRoute.checkForEventMethods(pl)
340
377
  pl = this.checkForEndRoute(pl)
341
378
  let payload = this.getDataFromParams(pl)
@@ -1,4 +1,4 @@
1
- import { Channel } from './channel'
1
+ import { Channel } from './channel.js'
2
2
  import { Observable } from 'rxjs'
3
3
  import { map } from 'rxjs/operators'
4
4
  import { equals, path, compose, prop, filter, replace, lensProp, over, omit, test, keys, either, toUpper } from 'ramda'
@@ -314,11 +314,27 @@ export class SpyneChannelUI extends Channel {
314
314
  }
315
315
 
316
316
  onUIEvent(obs) {
317
+ function domStringMapToObject(domStringMap) {
318
+ const obj = {}
319
+ for (const key in domStringMap) {
320
+ // Check if it’s a direct property (though dataset rarely has anything on the prototype):
321
+ if (Object.prototype.hasOwnProperty.call(domStringMap, key)) {
322
+ obj[key] = domStringMap[key]
323
+ }
324
+ }
325
+ return obj
326
+ }
327
+
328
+ obs.payload = domStringMapToObject(obs?.srcElement?.el?.dataset) ?? obs.payload
329
+
317
330
  SpyneChannelUI.checkForEventMethods(obs)
318
331
  obs.action = this.getActionState(obs)
319
332
  const action = obs.action// this.getActionState(obs);
333
+ // const { srcElement } = obs
320
334
  const { payload, srcElement } = obs
335
+
321
336
  const event = obs.event
337
+ // const payload = domStringMapToObject(srcElement?.el?.dataset) ?? obs.payload
322
338
  this.sendChannelPayload(action, payload, srcElement, event)
323
339
  }
324
340
  }
@@ -1,11 +1,11 @@
1
- import { Channel } from './channel'
2
- import { checkIfObjIsNotEmptyOrNil } from '../utils/frp-tools'
3
- import { SpyneAppProperties } from '../utils/spyne-app-properties'
4
- import { SpyneUtilsChannelWindow } from '../utils/spyne-utils-channel-window'
1
+ import { Channel } from './channel.js'
2
+ import { checkIfObjIsNotEmptyOrNil } from '../utils/frp-tools.js'
3
+ import { SpyneAppProperties } from '../utils/spyne-app-properties.js'
4
+ import { SpyneUtilsChannelWindow } from '../utils/spyne-utils-channel-window.js'
5
5
  import { merge } from 'rxjs'
6
6
  import { map, debounceTime, skipWhile } from 'rxjs/operators'
7
7
  import { curry, pick, partialRight, mapObjIndexed, apply, map as rMap } from 'ramda'
8
- import { deepMerge } from '../utils/deep-merge'
8
+ import { deepMerge } from '../utils/deep-merge.js'
9
9
 
10
10
  export class SpyneChannelWindow extends Channel {
11
11
  /**
@@ -1,11 +1,11 @@
1
- import { ChannelsMap } from './channels/channels-map'
2
- import { ViewStream } from './views/view-stream'
3
- import { SpyneUtilsChannelRoute } from './utils/spyne-utils-channel-route'
4
- import { SpyneAppProperties } from './utils/spyne-app-properties'
5
- import { sanitizeHTMLConfigure } from './utils/sanitize-html'
1
+ import { ChannelsMap } from './channels/channels-map.js'
2
+ import { ViewStream } from './views/view-stream.js'
3
+ import { SpyneUtilsChannelRoute } from './utils/spyne-utils-channel-route.js'
4
+ import { SpyneAppProperties } from './utils/spyne-app-properties.js'
5
+ import { sanitizeHTMLConfigure } from './utils/sanitize-html.js'
6
6
 
7
7
  const _channels = new ChannelsMap()
8
- const version = '0.20.4'
8
+ const version = '0.20.7'
9
9
 
10
10
  class SpyneApplication {
11
11
  /**
@@ -42,15 +42,20 @@ class SpyneApplication {
42
42
  init(config = {}, testMode = false) {
43
43
  // this.channels = new ChannelsMap();
44
44
  /*!
45
- * Spyne 0.20.4
45
+ * Spyne 0.20.7
46
46
  * https://spynejs.org
47
47
  *
48
- * @license Copyright 2017-2021, Frank Batista, Relevant Context, LLC. All rights reserved.
49
- * Spyne is licensed under the GNU Lesser General Public License v3.0
48
+ * @license
49
+ * Copyright 2017-2025, Frank Batista,
50
+ * Relevant Context, LLC. All rights reserved.
50
51
  *
51
- * @author: Frank Batista,
52
- * @email: frbatista.nyc@gmail.com
53
- */
52
+ * Licensed under the GNU Lesser General Public License v3.0 (the "License");
53
+ * You may not use this file except in compliance with the License.
54
+ * A copy of the License is located in the project root, or at:
55
+ * https://www.gnu.org/licenses/lgpl-3.0.html
56
+ *
57
+ * This notice may not be removed or altered from any distribution.
58
+ */
54
59
  /* eslint-disable */
55
60
 
56
61
 
@@ -82,6 +87,8 @@ class SpyneApplication {
82
87
 
83
88
  },
84
89
  tmp: {},
90
+ ephemeralProps: {},
91
+ tmpProps: {},
85
92
  channels: {
86
93
  WINDOW: {
87
94
  mediaQueries: {
@@ -1,5 +1,5 @@
1
- import { DomElement } from './views/dom-element'
2
- import { SpyneAppProperties } from './utils/spyne-app-properties'
1
+ import { DomElement } from './views/dom-element.js'
2
+ import { SpyneAppProperties } from './utils/spyne-app-properties.js'
3
3
  import { is, clone, pathSatisfies } from 'ramda'
4
4
  let _spyneAppProps = SpyneAppProperties
5
5
  export class SpynePlugin {
@@ -123,6 +123,21 @@ export class SpynePlugin {
123
123
  onBeforeRegistered() {
124
124
  // this.props.pluginName = this.props.name
125
125
  // this.props.config = _spyneAppProps.getPluginConfigByPluginName(this.props.pluginName)
126
+ this.checkForRequiredWindowEvent()
127
+ }
128
+
129
+ checkForRequiredWindowEvent() {
130
+ const requiredEvents = this.props.requiredEvents ?? []
131
+ const windowConfig = SpyneAppProperties.getChannelConfig('WINDOW')
132
+
133
+ const missingEvents = requiredEvents.filter(evt => !windowConfig.events.includes(evt))
134
+
135
+ // If any are missing, log a single warning listing them
136
+ if (missingEvents.length > 0) {
137
+ console.warn(
138
+ `plugin "${this.props.name}" requires the following config.WINDOW.events, --> ${missingEvents.join(', ')} <--`
139
+ )
140
+ }
126
141
  }
127
142
 
128
143
  defaultConfig() {
@@ -1,22 +1,22 @@
1
- import { ChannelsMap } from './channels/channels-map'
2
- import { DomElement } from './views/dom-element'
3
- import { DomElementTemplate } from './views/dom-element-template'
4
- import { ViewStreamElement } from './views/view-stream-element'
5
- import { ViewStreamSelector } from './views/view-stream-selector'
6
- import { ViewStream } from './views/view-stream'
7
- import { ViewStreamBroadcaster } from './views/view-stream-broadcaster'
8
- import { SpyneTrait } from './utils/spyne-trait'
9
- import { ViewStreamPayload } from './views/view-stream-payload'
10
- import { Channel } from './channels/channel'
11
- import { ChannelFetch } from './channels/channel-fetch-class'
12
- import { ChannelFetchUtil } from './utils/channel-fetch-util'
13
- import { ChannelPayload } from './channels/channel-payload-class'
14
- import { ChannelPayloadFilter } from './utils/channel-payload-filter'
15
- import { SpynePlugin } from './spyne-plugins'
16
- import { deepMerge } from './utils/deep-merge'
17
- import { safeClone } from './utils/safe-clone'
18
- import { SpyneAppProperties } from './utils/spyne-app-properties'
19
- import { SpyneApp } from './spyne-app'
1
+ import { ChannelsMap } from './channels/channels-map.js'
2
+ import { DomElement } from './views/dom-element.js'
3
+ import { DomElementTemplate } from './views/dom-element-template.js'
4
+ import { ViewStreamElement } from './views/view-stream-element.js'
5
+ import { ViewStreamSelector } from './views/view-stream-selector.js'
6
+ import { ViewStream } from './views/view-stream.js'
7
+ import { ViewStreamBroadcaster } from './views/view-stream-broadcaster.js'
8
+ import { SpyneTrait } from './utils/spyne-trait.js'
9
+ import { ViewStreamPayload } from './views/view-stream-payload.js'
10
+ import { Channel } from './channels/channel.js'
11
+ import { ChannelFetch } from './channels/channel-fetch-class.js'
12
+ import { ChannelFetchUtil } from './utils/channel-fetch-util.js'
13
+ import { ChannelPayload } from './channels/channel-payload-class.js'
14
+ import { ChannelPayloadFilter } from './utils/channel-payload-filter.js'
15
+ import { SpynePlugin } from './spyne-plugins.js'
16
+ import { deepMerge } from './utils/deep-merge.js'
17
+ import { safeClone } from './utils/safe-clone.js'
18
+ import { SpyneAppProperties } from './utils/spyne-app-properties.js'
19
+ import { SpyneApp } from './spyne-app.js'
20
20
 
21
21
  export {
22
22
  ViewStreamElement,
@@ -82,6 +82,8 @@ export class ChannelFetchUtil {
82
82
  }
83
83
  }
84
84
 
85
+ // console.log('SERVER OPTIONS ', { props, serverOptions })
86
+
85
87
  const response$ = from(window.fetch(url, serverOptions))
86
88
  .pipe(tap(tapLog), flatMap(r => from(r[responseType]())),
87
89
  map(mapWrapper(mapFn)),
@@ -14,6 +14,7 @@ import {
14
14
  where,
15
15
  defaultTo,
16
16
  mergeAll,
17
+ F,
17
18
  omit,
18
19
  flatten,
19
20
  any,
@@ -22,7 +23,7 @@ import {
22
23
  , map as rMap
23
24
  } from 'ramda'
24
25
 
25
- import { SpyneAppProperties } from './spyne-app-properties'
26
+ import { SpyneAppProperties } from './spyne-app-properties.js'
26
27
 
27
28
  const isNotArr = compose(not, is(Array))
28
29
  const isNotEmpty = compose(not, isEmpty)
@@ -31,6 +32,11 @@ const isNonEmptyArr = allPass([is(Array), isNotEmpty])
31
32
  const isObjectFn = compose(allPass([isNotArr, is(Object)]))
32
33
  const isNonEmptyObjectFn = compose(allPass([isNotEmpty, isNotArr, is(Object)]))
33
34
 
35
+ const isString = (val) => is(String, val)
36
+ const isBoolean = (val) => is(Boolean, val)
37
+ const isNumber = (val) => is(Number, val)
38
+ const isArrayFn = (val) => is(Array, val)
39
+
34
40
  export class ChannelPayloadFilter {
35
41
  /**
36
42
  * @module ChannelPayloadFilter
@@ -160,7 +166,18 @@ export class ChannelPayloadFilter {
160
166
  return str === compareStr
161
167
  }
162
168
  const checkToConvertToFn = (val, key, obj) => {
163
- const fnVal = is(String, val) === true ? createCurryComparator(val) : val
169
+ let fnVal = F
170
+ if (isString(val) || isBoolean(val) || isNumber(val)) {
171
+ fnVal = createCurryComparator(val)
172
+ } else if (typeof val === 'function') {
173
+ return val
174
+ } else if (isArrayFn(val) || isObjectFn(val)) {
175
+ console.warn(
176
+ `ChannelPayloadFilter: Property "${val}" is an array/object, which is not allowed. ` +
177
+ 'This property will always return false.'
178
+ )
179
+ return fnVal
180
+ }
164
181
  return fnVal
165
182
  }
166
183
  filterJson = rMap(checkToConvertToFn, filterJson)
@@ -1,4 +1,4 @@
1
- import { ViewStreamPayload } from '../../views/view-stream-payload'
1
+ import { ViewStreamPayload } from '../../views/view-stream-payload.js'
2
2
 
3
3
  export function baseStreamsMixins() {
4
4
  return {
@@ -1,4 +1,4 @@
1
- import { ViewStream } from '../views/view-stream'
1
+ import { ViewStream } from '../views/view-stream.js'
2
2
  import { curry } from 'ramda'
3
3
  export class RouteChannelUpdater {
4
4
  constructor(cxt) {
@@ -1,5 +1,5 @@
1
1
  import { clone, compose, fromPairs, is, path, toPairs } from 'ramda'
2
- import { SpyneAppProperties } from './spyne-app-properties'
2
+ import { SpyneAppProperties } from './spyne-app-properties.js'
3
3
 
4
4
  const getPropType = (prp) => {
5
5
  let type = typeof prp