spyne 0.20.2 → 0.20.4

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Spyne 0.20.1
2
+ * Spyne 0.20.4
3
3
  * https://spynejs.org
4
4
  *
5
5
  * @license Copyright 2017-2021, Frank Batista, Relevant Context, LLC. All rights reserved.
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  /*!
13
- * spynejs 0.20.1
13
+ * spynejs 0.20.4
14
14
  * https://spynejs.org
15
15
  * (c) 2017-present Frank Batista
16
16
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spyne",
3
- "version": "0.20.2",
3
+ "version": "0.20.4",
4
4
  "description": "Reactive Real-DOM Framework for Advanced Javascript applications",
5
5
  "sideEffects": true,
6
6
  "main": "./lib/spyne.esm.js",
@@ -19,7 +19,6 @@
19
19
  "report-coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
20
20
  "commit": "git-cz",
21
21
  "start": "webpack-dev-server --hot",
22
- "prepare": "husky",
23
22
  "build": "webpack --config webpack.config.js --mode production",
24
23
  "build:esm": "rollup --config rollup.config.js",
25
24
  "dev": "webpack --config webpack.config.js --mode development",
@@ -30,7 +29,8 @@
30
29
  "test:single": "karma start karma.conf.js --single-run",
31
30
  "watch:test": "npm test -- --auto-watch --no-single-run",
32
31
  "test:mocha": "mocha tests",
33
- "lint": "eslint 'src/spyne/**' --fix"
32
+ "lint": "eslint 'src/spyne/**' --fix",
33
+ "prepare": "husky"
34
34
  },
35
35
  "repository": {
36
36
  "type": "git",
@@ -50,10 +50,12 @@
50
50
  "@rollup/plugin-commonjs": "^28.0.2",
51
51
  "@rollup/plugin-json": "^6.1.0",
52
52
  "@rollup/plugin-node-resolve": "^16.0.0",
53
+ "@rollup/plugin-replace": "^6.0.2",
53
54
  "chai": "^4.3.9",
54
55
  "chai-dom": "^1.11.0",
55
56
  "clean-webpack-plugin": "^4.0.0",
56
57
  "css-loader": "^6.8.1",
58
+ "dotenv": "^16.4.7",
57
59
  "eslint": "^8.50.0",
58
60
  "eslint-config-semistandard": "^17.0.0",
59
61
  "eslint-config-standard": "^17.1.0",
@@ -67,6 +69,7 @@
67
69
  "karma-chrome-launcher": "^3.2.0",
68
70
  "karma-coverage": "^2.2.1",
69
71
  "karma-mocha": "^2.0.1",
72
+ "karma-rollup-preprocessor": "^7.0.8",
70
73
  "karma-webpack": "^5.0.1",
71
74
  "mocha": "^10.7.3",
72
75
  "rollup": "^2.79.2",
@@ -77,11 +80,7 @@
77
80
  "webpack-dev-server": "^5.1.0",
78
81
  "webpack-rxjs-externals": "^2.0.0"
79
82
  },
80
- "config": {
81
- "ghooks": {
82
- "pre-commit": "npm run test"
83
- }
84
- },
83
+ "config": {},
85
84
  "dependencies": {
86
85
  "dompurify": "^3.1.6",
87
86
  "ramda": "^0.30.1",
package/rollup.config.js CHANGED
@@ -12,7 +12,7 @@ export default {
12
12
  sourcemap: true
13
13
  },
14
14
  // If you want to keep certain libraries external, define them here:
15
- external: ['ramda', 'rxjs'],
15
+ external: ['ramda', 'rxjs', 'dompurify'],
16
16
  plugins: [
17
17
  // Allows Rollup to resolve packages from node_modules
18
18
  resolve(),
@@ -5,7 +5,7 @@ import { SpyneAppProperties } from './utils/spyne-app-properties'
5
5
  import { sanitizeHTMLConfigure } from './utils/sanitize-html'
6
6
 
7
7
  const _channels = new ChannelsMap()
8
- const version = '0.20.2'
8
+ const version = '0.20.4'
9
9
 
10
10
  class SpyneApplication {
11
11
  /**
@@ -42,7 +42,7 @@ class SpyneApplication {
42
42
  init(config = {}, testMode = false) {
43
43
  // this.channels = new ChannelsMap();
44
44
  /*!
45
- * Spyne 0.20.2
45
+ * Spyne 0.20.4
46
46
  * https://spynejs.org
47
47
  *
48
48
  * @license Copyright 2017-2021, Frank Batista, Relevant Context, LLC. All rights reserved.
@@ -78,15 +78,15 @@ export class SpyneUtilsChannelRoute {
78
78
  }
79
79
 
80
80
  static flattenConfigObject(obj) {
81
- const go = obj_ => chain(([k, v]) => {
82
- if (Object.prototype.toString.call(v) === '[object Object]') {
81
+ const go = (obj_) => chain(([k, v]) => {
82
+ if (typeof v === 'object' && v !== null && !Array.isArray(v)) {
83
83
  return map(([k_, v_]) => [`${k}.${k_}`, v_], go(v))
84
84
  } else {
85
85
  return [[k, v]]
86
86
  }
87
87
  }, toPairs(obj_))
88
88
 
89
- // console.log("FLATTEN: ",values(fromPairs(go(obj))));
89
+ // console.log("FLATTEN: ", values(fromPairs(go(obj))));
90
90
  return values(fromPairs(go(obj)))
91
91
  }
92
92
 
@@ -135,9 +135,10 @@ import { SpyneAppProperties } from '../utils/spyne-app-properties'
135
135
  */
136
136
 
137
137
  export class DomElementTemplate {
138
- constructor(template, data = {}) {
138
+ constructor(template, data = {}, opts = {}) {
139
139
  this.template = this.formatTemplate(template)
140
140
  this.isProxyData = data.__cms__isProxy === true
141
+ this.testMode = opts?.testMode
141
142
 
142
143
  const checkForArrayData = () => {
143
144
  if (is(Array, data) === true) {
@@ -226,7 +227,9 @@ export class DomElementTemplate {
226
227
  renderDocFrag() {
227
228
  let html = DomElementTemplate.replaceImgPath(this.finalArr.join(''))
228
229
  // html = sanitizeHTML(this.finalArr.join(''))
229
- html = sanitizeHTML(html)
230
+ if (this.testMode !== true) {
231
+ html = sanitizeHTML(html)
232
+ }
230
233
  const isTableSubTag = /^([^>]*?)(<){1}(\b)(thead|col|colgroup|tbody|td|tfoot|tr|th)(\b)([^\0]*)$/.test(html)
231
234
  const el = isTableSubTag ? html : document.createRange().createContextualFragment(html)
232
235
 
@@ -25,7 +25,7 @@ class DomElement {
25
25
  *
26
26
  */
27
27
 
28
- constructor(props = {}) {
28
+ constructor(props = {}, testMode = false) {
29
29
  const checkDefault = (dflt, val) => defaultTo(dflt)(val)
30
30
 
31
31
  props.tagName = checkDefault('div', props.tagName)
@@ -34,6 +34,7 @@ class DomElement {
34
34
  props.attrs = this.updateAttrs(props.attributes)
35
35
 
36
36
  props.fragment = document.createDocumentFragment()
37
+ this.testMode = testMode
37
38
  this.props = props
38
39
 
39
40
  this.addMixins()
@@ -77,7 +78,7 @@ class DomElement {
77
78
  const addTmpl = (template) => {
78
79
  let data = this.getProp('data')
79
80
  data = is(Object, data) ? data : {}
80
- const frag = new DomElementTemplate(template, data).renderDocFrag()
81
+ const frag = new DomElementTemplate(template, data, { testMode: this?.testMode }).renderDocFrag()
81
82
  const fragIsString = is(String, frag)
82
83
  fragIsString ? el.innerHTML = frag : el.appendChild(frag)
83
84
  return el
@@ -1,5 +1,7 @@
1
+ //const { expect, assert } = require('chai')
2
+ //const { ChannelFetch } = require('../../spyne/channels/channel-fetch-class')
1
3
  const { expect, assert } = require('chai')
2
- const { ChannelFetch } = require('../../spyne/channels/channel-fetch-class')
4
+ import { ChannelFetch } from '../../spyne/spyne';
3
5
 
4
6
  describe('should test ChannelFetch', () => {
5
7
  const mapFn = (p) => {
@@ -43,8 +45,13 @@ describe('should test ChannelFetch', () => {
43
45
  const noMapMethodAdded = ChannelFetch.validateMapMethod(props, channelName)
44
46
  // console.log('map methods not added and is valid ',{noMapMethodAdded})
45
47
  expect(noMapMethodAdded).to.be.true
48
+
49
+
50
+
51
+
46
52
  })
47
53
 
54
+
48
55
  it('should return false for map of wrong type', () => {
49
56
  const map = 4
50
57
  const props = {
@@ -1,10 +1,10 @@
1
1
  import { SpyneApp, Channel } from '../../spyne/spyne'
2
2
  import { ChannelPayload } from '../../spyne/channels/channel-payload-class'
3
3
  import { ChannelPayloadToTestFilters } from '../mocks/channel-payload-data'
4
- import { ChannelPayloadFilter } from '../../spyne/utils/channel-payload-filter'
4
+ //import { ChannelPayloadFilter } from '../../spyne/utils/channel-payload-filter'
5
5
  const { expect, assert } = require('chai')
6
6
  const MSFData = require('../mocks/msf-user-data.json')
7
- const MSFDataSmall = require('../mocks/msf-user-data-small.json')
7
+ //const MSFDataSmall = require('../mocks/msf-user-data-small.json')
8
8
  const R = require('ramda')
9
9
 
10
10
  describe('should test Channel Payload Class', () => {
@@ -6,8 +6,7 @@ import { ChannelPayloadRouteData, ChannelPayloadRouteDataRegexOverride } from '.
6
6
  import {
7
7
  SpyneConfigData,
8
8
  RouteDataForTests,
9
- routeConfigWithRegexOverride,
10
- windowLocationData
9
+ routeConfigWithRegexOverride
11
10
  } from '../mocks/utils-data'
12
11
  import { SpyneChannelRoute } from '../../spyne/channels/spyne-channel-route'
13
12
  const R = require('ramda')
@@ -1,13 +1,15 @@
1
- import { Channel, SpyneAppProperties } from '../../spyne/spyne'
1
+ import { Channel, SpyneAppProperties, SpyneApp } from '../../spyne/spyne'
2
+
2
3
  const { expect, assert } = require('chai')
3
- const { SpyneApp } = require('../../spyne/spyne-app')
4
4
 
5
5
  describe('should test channel instance', () => {
6
+
6
7
  const channelName = 'CHANNEL_MYTEST_CHANNEL'
7
- SpyneApp.registerChannel(new Channel(channelName))
8
8
 
9
9
  before(function() {
10
+ SpyneApp.init({debug:true});
10
11
 
12
+ SpyneApp.registerChannel(new Channel(channelName))
11
13
  })
12
14
 
13
15
  it('registered channel should exist', () => {
@@ -4,8 +4,7 @@ import { SpyneUtilsChannelRoute } from '../../spyne/utils/spyne-utils-channel-ro
4
4
  import { postProcessedRouteData, preProcessedRouteData, reduceProcessedRouteData, reducedRoutesArr, mainConfigPreProcessedData, mainConfigPostProcessedData } from '../mocks/routes-data'
5
5
  import {
6
6
  SpyneConfigData,
7
- RouteDataForTests,
8
- windowLocationData
7
+ RouteDataForTests
9
8
  } from '../mocks/utils-data'
10
9
  import { SpyneChannelRoute } from '../../spyne/channels/spyne-channel-route'
11
10
  import { path } from 'ramda'
@@ -16,7 +15,7 @@ const routeConfig = SpyneConfigData.channels.ROUTE
16
15
 
17
16
  describe('Route Utils', () => {
18
17
  it('flattenConfigObjects should return array of params', () => {
19
- const finalArr = ['pageId', '', 'imageNum', 'author', 'hemingway', 'author', 'hemingway', 'imageNum', 'pixels', 'photogNum', 'randomNum', '32', 'holographs|photos|digital|videos']
18
+ const finalArr = ['pageId', '', 'imageNum', 'author', 'hemingway', 'author', 'hemingway', 'imageNum', 'pixels', 'photogNum', 'randomNum', '32']
20
19
  const arr = SpyneUtilsChannelRoute.flattenConfigObject(routeConfig.routes)
21
20
  // return true;
22
21
  expect(arr).to.deep.equal(finalArr)
@@ -1,8 +1,7 @@
1
1
  // const assert = require('assert');
2
2
  import {
3
3
  SpyneConfigData,
4
- RouteDataForTests,
5
- windowLocationData
4
+ RouteDataForTests
6
5
  } from '../mocks/utils-data'
7
6
  chai.use(require('chai-dom'))
8
7
 
@@ -1,12 +1,20 @@
1
- import { expect } from 'chai'
2
- import pkg from '../../package.json' // Import package.json
1
+ import { expect } from 'chai';
2
+ import pkg from '../../package.json'; // Import package.json
3
+
4
+ const isPublic = process.env.IS_PUBLIC === true;
3
5
 
4
6
  describe('package.json export import statement', () => {
5
7
  it('should be set to "./lib/spyne.esm.js"', () => {
6
- const exports = pkg.exports['.']
7
- expect(pkg.main).to.equal('./lib/spyne.esm.js')
8
- expect(pkg.module).to.equal('./lib/spyne.esm.js')
9
- expect(exports.import).to.equal('./lib/spyne.esm.js')
10
- expect(exports.require).to.equal('./lib/spyne.esm.js')
11
- })
12
- })
8
+ const exports = pkg.exports['.'];
9
+ expect(pkg.main).to.equal('./lib/spyne.esm.js');
10
+ expect(pkg.module).to.equal('./lib/spyne.esm.js');
11
+ expect(exports.import).to.equal('./lib/spyne.esm.js');
12
+ expect(exports.require).to.equal('./lib/spyne.esm.js');
13
+ });
14
+ });
15
+
16
+ (isPublic ? describe : describe.skip)('license should be LGPL', () => {
17
+ it('should have LGPL as license', () => {
18
+ expect(pkg.license).to.equal('LGPL');
19
+ });
20
+ });
@@ -4,7 +4,7 @@ const { SpyneApp } = require('../spyne/spyne-app')
4
4
  describe('should run spyne app tests', () => {
5
5
  before(() => {
6
6
 
7
- // SpyneApp.init();
7
+ SpyneApp.init();
8
8
 
9
9
  })
10
10
 
@@ -1,7 +1,14 @@
1
- import { DomElementTemplate } from '../../spyne/views/dom-element-template'
1
+ import { DomElementTemplate } from '../../spyne/views/dom-element-template';
2
2
 
3
- describe('DomElementTemplate Proxy should not exist ', () => {
3
+ // Evaluate once at the top
4
+ const isPublic = process.env.IS_PUBLIC === true;
5
+
6
+ console.log("IS PUBLIC ",isPublic);
7
+
8
+
9
+ // If not public, skip this test suite altogether
10
+ (isPublic ? describe : describe.skip)('DomElementTemplate Proxy (Public Test)', () => {
4
11
  it('should not have a proxy method', () => {
5
- expect(DomElementTemplate.hasOwnProperty('formatTemplateForProxyData')).to.be.false
6
- })
7
- })
12
+ expect(DomElementTemplate.hasOwnProperty('formatTemplateForProxyData')).to.be.false;
13
+ });
14
+ });
@@ -20,7 +20,7 @@ describe('DomElTemplate', () => {
20
20
  it('DomElementTemplate show render data value', () => {
21
21
  const data = { cat:'meow' }
22
22
  const template = '<h1>The cat says {{cat}}'
23
- const domElTmpl = new DomElementTemplate(template, data)
23
+ const domElTmpl = new DomElementTemplate(template, data, {testMode:true})
24
24
  const render = domElTmpl.renderDocFrag()
25
25
  // console.log("RENDER IS ",render.firstElementChild);
26
26
  expect(render.firstElementChild.innerText).to.equal('The cat says meow')
@@ -33,7 +33,7 @@ describe('DomElTemplate', () => {
33
33
  }
34
34
  }
35
35
  const template = '<h1>The dog says {{#dog}}{{sound}}{{/dog}}</h1>'
36
- const domElTemplate = new DomElementTemplate(template, data)
36
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
37
37
  const render = domElTemplate.renderDocFrag()
38
38
  expect(render.firstElementChild.innerText).to.equal('The dog says woof')
39
39
  })
@@ -45,14 +45,14 @@ describe('DomElTemplate', () => {
45
45
  }
46
46
  }
47
47
  const template = '<article>{{#dog}}<h1>The dog says {{sound}}</h1>{{/dog}}</article>'
48
- const domElTemplate = new DomElementTemplate(template, data)
48
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
49
49
  const render = domElTemplate.renderDocFrag()
50
50
  expect(render.firstElementChild.innerText).to.equal('')
51
51
  })
52
52
  it('DomElementTemplate Template should render 0 as non-empty', () => {
53
53
  const data = { scriptNum:0, eventType:'scriptContent', tabName:'MyTab' }
54
54
  const template = '<button data-event-type="{{eventType}}" data-script-num="{{scriptNum}}" >{{scriptNum}}</button>'
55
- const domElTemplate = new DomElementTemplate(template, data)
55
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
56
56
  const render = domElTemplate.renderDocFrag()
57
57
  expect(render.firstElementChild.innerText).to.equal('0')
58
58
  })
@@ -63,7 +63,7 @@ describe('DomElTemplate', () => {
63
63
  }
64
64
  }
65
65
  const template = '<article><h1>The dog says {{test.sound}}</h1></article>'
66
- const domElTemplate = new DomElementTemplate(template, data)
66
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
67
67
  const render = domElTemplate.renderDocFrag()
68
68
  expect(render.firstElementChild.innerText).to.equal('The dog says ')
69
69
  })
@@ -74,7 +74,7 @@ describe('DomElTemplate', () => {
74
74
  }
75
75
  }
76
76
  const template = '<article><h1>The dog says {{asdf}}</h1></article>'
77
- const domElTemplate = new DomElementTemplate(template, data)
77
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
78
78
  const render = domElTemplate.renderDocFrag()
79
79
  expect(render.firstElementChild.innerText).to.equal('The dog says ')
80
80
  })
@@ -92,7 +92,7 @@ describe('DomElTemplate', () => {
92
92
  ]
93
93
  }
94
94
  const template = '<article>{{#animals}}<h1>The {{name}} says {{sound}}</h1>{{/animals}}</article>'
95
- const domElTemplate = new DomElementTemplate(template, data)
95
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
96
96
  const render = domElTemplate.renderDocFrag()
97
97
  const renderStr = render.firstElementChild.querySelectorAll('h1')[1].innerText
98
98
  expect(renderStr).to.equal('The cat says meow')
@@ -105,7 +105,7 @@ describe('DomElTemplate', () => {
105
105
  { name: 'john' }
106
106
  ]
107
107
  const template = '<ul>{{#}}<li>Welcome, {{name}}.</li>{{/}}</ul>'
108
- const domElTemplate = new DomElementTemplate(template, data)
108
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
109
109
  const render = domElTemplate.renderDocFrag()
110
110
  const lastItemTxt = render.firstElementChild.querySelectorAll('li')[2].innerText
111
111
  expect(lastItemTxt).to.equal('Welcome, john.')
@@ -119,7 +119,7 @@ describe('DomElTemplate', () => {
119
119
  ]
120
120
  const template = '<ul>{{#}}<li>Welcome, {{name}}. and hobbies are {{hobbies}} </li>{{/}}</ul>'
121
121
  // let template = "<ul>{{#}}<li>Welcome, {{name}}. <ol>{{#hobbies}}<li>{{.}}</li><{{/hobbies}}/ol></li>{{/}}</ul>";
122
- const domElTemplate = new DomElementTemplate(template, data)
122
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
123
123
  const render = domElTemplate.renderDocFrag()
124
124
 
125
125
  const lastItemTxt = render.firstElementChild.querySelectorAll('li')[2].innerText
@@ -136,7 +136,7 @@ describe('DomElTemplate', () => {
136
136
  ]
137
137
  const template = '<ul><li>Welcome, {{name}}. Your hobbies are {{#hobbies}}{{.}}, {{/hobbies}}and favorite foods are {{#favFoods}}<span>{{.}}, </span>{{/favFoods}} </li></ul>'
138
138
  data = data[0]
139
- const domElTemplate = new DomElementTemplate(template, data)
139
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
140
140
  const render = domElTemplate.renderDocFrag()
141
141
  const favFoodInnerText = render.firstElementChild.querySelectorAll('span')[0].innerText
142
142
  expect(favFoodInnerText).to.equal('hummus, ')
@@ -150,7 +150,7 @@ describe('DomElTemplate', () => {
150
150
  ]
151
151
  const template = '<ul><li>Welcome, {{name}}. Your hobbies are {{#hobbies}}{{.}}, {{/hobbies}}and your {{#details}}hair is {{hair}} and your eyes are {{eyes}} {{/details}}and favorite foods are {{#favFoods}}<span>{{.}}, </span>{{/favFoods}} </li></ul>'
152
152
  data = data[0]
153
- const domElTemplate = new DomElementTemplate(template, data)
153
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
154
154
  const render = domElTemplate.renderDocFrag()
155
155
  const favFoodInnerText = render.firstElementChild
156
156
 
@@ -168,7 +168,7 @@ describe('DomElTemplate', () => {
168
168
  }
169
169
  const template = '<ul>{{#users}}<li>Welcome, {{name}}. and details are {{details.age}} and degree is {{details.education.degree}} </li>{{/users}}</ul>'
170
170
  // let template = "<ul>{{#}}<li>Welcome, {{name}}. <ol>{{#hobbies}}<li>{{.}}</li><{{/hobbies}}/ol></li>{{/}}</ul>";
171
- const domElTemplate = new DomElementTemplate(template, data)
171
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
172
172
  const render = domElTemplate.renderDocFrag()
173
173
 
174
174
  // console.log("render nested array of objs ",render.firstElementChild);
@@ -188,7 +188,7 @@ describe('DomElTemplate', () => {
188
188
  data = data.users[0]
189
189
  const template = '<ul><li>Welcome, {{name}}. and age is {{details.age}} and graduated from {{details.education.school}} </li></ul>'
190
190
  // let template = "<ul>{{#}}<li>Welcome, {{name}}. <ol>{{#hobbies}}<li>{{.}}</li><{{/hobbies}}/ol></li>{{/}}</ul>";
191
- const domElTemplate = new DomElementTemplate(template, data)
191
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
192
192
  const render = domElTemplate.renderDocFrag()
193
193
 
194
194
  // console.log("render nested obj ",render.firstElementChild);
@@ -206,7 +206,7 @@ describe('DomElTemplate', () => {
206
206
 
207
207
  const template = '<li>{{article.1}}</li>'
208
208
  const data = { article }
209
- const domElTemplate = new DomElementTemplate(template, data)
209
+ const domElTemplate =new DomElementTemplate(template, data, {testMode:true})
210
210
 
211
211
  const result = domElTemplate.renderToString()
212
212
 
@@ -19,7 +19,7 @@ describe('DomElRendering', () => {
19
19
  it('DomElement Template show render data value', () => {
20
20
  const data = { cat:'meow' }
21
21
  const template = '<h1>The cat says {{cat}}'
22
- const domEl = new DomElement({ data, template })
22
+ const domEl = new DomElement({ data, template }, true)
23
23
  const render = domEl.render()
24
24
  expect(render.innerText).to.equal('The cat says meow')
25
25
  })
@@ -31,7 +31,7 @@ describe('DomElRendering', () => {
31
31
  }
32
32
  }
33
33
  const template = '<h1>The dog says {{#dog}}{{sound}}{{/dog}}'
34
- const domEl = new DomElement({ data, template })
34
+ const domEl = new DomElement({ data, template }, true)
35
35
  const render = domEl.render()
36
36
  expect(render.innerText).to.equal('The dog says woof')
37
37
  })
@@ -43,7 +43,7 @@ describe('DomElRendering', () => {
43
43
  }
44
44
  }
45
45
  const template = '<article>{{#dog}}<h1>The dog says {{sound}}</h1>{{/dog}}</article>'
46
- const domEl = new DomElement({ data, template })
46
+ const domEl = new DomElement({ data, template }, true)
47
47
  const render = domEl.render()
48
48
  expect(render.innerText).to.equal('')
49
49
  })
@@ -62,7 +62,7 @@ describe('DomElRendering', () => {
62
62
  ]
63
63
  }
64
64
  const template = '<article>{{#animals}}<h1>The {{name}} says {{sound}}</h1>{{/animals}}</article>'
65
- const domEl = new DomElement({ data, template })
65
+ const domEl = new DomElement({ data, template }, true)
66
66
  const render = domEl.render()
67
67
  const renderStr = render.querySelectorAll('h1')[1].innerText
68
68
  expect(renderStr).to.equal('The cat says meow')
package/webpack.config.js CHANGED
@@ -2,28 +2,16 @@
2
2
  const path = require('path');
3
3
  const webpack = require('webpack');
4
4
  const ESLintPlugin = require('eslint-webpack-plugin');
5
- const WebpackRxjsExternals = require('webpack-rxjs-externals');
6
5
  const pkg = require('./package.json');
7
6
 
8
- // We'll define a base config to share options:
7
+ // Shared base config for the UMD build:
9
8
  function baseConfig(mode) {
10
9
  return {
11
10
  mode,
12
11
  devtool: mode === 'production' ? false : 'inline-source-map',
13
- externals: [
14
- WebpackRxjsExternals(),
15
- {
16
- ramda: {
17
- commonjs: 'ramda',
18
- commonjs2: 'ramda',
19
- amd: 'ramda',
20
- root: 'R'
21
- }
22
- }
23
- ],
24
12
  module: {
25
13
  rules: [
26
- // Add Babel or other loaders here if needed
14
+ // Example if you need Babel:
27
15
  // {
28
16
  // test: /\.js$/,
29
17
  // exclude: /node_modules/,
@@ -36,7 +24,6 @@ function baseConfig(mode) {
36
24
  modules: [path.resolve(__dirname, 'node_modules'), 'node_modules']
37
25
  },
38
26
  plugins: [
39
- // Modern replacement for eslint-loader
40
27
  new ESLintPlugin({
41
28
  fix: true,
42
29
  extensions: ['js'],
@@ -46,30 +33,18 @@ function baseConfig(mode) {
46
33
  banner: `spynejs ${pkg.version}\nhttps://spynejs.org\n(c) 2017-present Frank Batista`,
47
34
  entryOnly: true
48
35
  })
49
- ]
36
+ ],
37
+ optimization: {
38
+ // Disabling module concatenation helps avoid the “Cannot read properties of undefined” error
39
+ // when analyzing external modules for scope hoisting:
40
+ concatenateModules: false
41
+ }
50
42
  };
51
43
  }
52
44
 
53
- // ESM Build:
54
- const esmConfig = {
55
- ...baseConfig(process.env.NODE_ENV || 'development'),
56
-
57
- entry: './src/spyne/spyne.js',
58
-
59
- // Enable module output
60
- experiments: {
61
- outputModule: true
62
- },
63
- output: {
64
- path: path.resolve(__dirname, 'lib'),
65
- filename: 'spyne.esm.js',
66
- library: {
67
- type: 'module'
68
- }
69
- }
70
- };
71
-
72
- // UMD Build:
45
+ ////////////////////////////////////////////////
46
+ // UMD Build Only (we rely on Rollup for ESM)
47
+ ////////////////////////////////////////////////
73
48
  const umdConfig = {
74
49
  ...baseConfig(process.env.NODE_ENV || 'development'),
75
50
 
@@ -81,8 +56,42 @@ const umdConfig = {
81
56
  library: 'spyne',
82
57
  libraryTarget: 'umd',
83
58
  umdNamedDefine: true
59
+ },
60
+
61
+ ///////////////////////////////////////////////////////////
62
+ // Externals for ramda, rxjs, dompurify, etc. in UMD build
63
+ ///////////////////////////////////////////////////////////
64
+ externals: {
65
+ // Ramda
66
+ ramda: {
67
+ commonjs: 'ramda',
68
+ commonjs2: 'ramda',
69
+ amd: 'ramda',
70
+ root: 'R'
71
+ },
72
+
73
+ // RxJS
74
+ rxjs: {
75
+ commonjs: 'rxjs',
76
+ commonjs2: 'rxjs',
77
+ amd: 'rxjs',
78
+ root: 'rxjs'
79
+ },
80
+ 'rxjs/operators': {
81
+ commonjs: ['rxjs', 'operators'],
82
+ commonjs2: ['rxjs', 'operators'],
83
+ amd: 'rxjs/operators',
84
+ root: ['rxjs', 'operators']
85
+ },
86
+
87
+ // DOMPurify
88
+ dompurify: {
89
+ commonjs: 'dompurify',
90
+ commonjs2: 'dompurify',
91
+ amd: 'dompurify',
92
+ root: 'DOMPurify'
93
+ }
84
94
  }
85
95
  };
86
96
 
87
- // Export both configs in an array
88
- module.exports = [esmConfig, umdConfig];
97
+ module.exports = umdConfig;