@jscad/core 2.5.2 → 2.5.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jscad/core",
3
- "version": "2.5.2",
3
+ "version": "2.5.5",
4
4
  "description": "Core functionality for JSCAD Applications",
5
5
  "repository": "https://github.com/jscad/OpenJSCAD.org",
6
6
  "main": "src/index.js",
@@ -34,10 +34,10 @@
34
34
  ],
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "@jscad/array-utils": "2.1.1",
38
- "@jscad/io": "2.2.2",
39
- "@jscad/io-utils": "2.0.12",
40
- "@jscad/modeling": "2.7.1",
37
+ "@jscad/array-utils": "2.1.2",
38
+ "@jscad/io": "2.2.5",
39
+ "@jscad/io-utils": "2.0.14",
40
+ "@jscad/modeling": "2.8.0",
41
41
  "json5": "2.2.0",
42
42
  "strip-bom": "4.0.0"
43
43
  },
@@ -52,5 +52,5 @@
52
52
  "url": "https://opencollective.com/openjscad",
53
53
  "logo": "https://opencollective.com/openjscad/logo.txt"
54
54
  },
55
- "gitHead": "c8ac21281a7acf5a5575b940c18353c598ffa1a4"
55
+ "gitHead": "92fb9c75eb070fca5f5ee8c2bab6614b1f54514e"
56
56
  }
@@ -24,7 +24,6 @@ const applyParameterDefinitions = require('../parameters/applyParameterDefinitio
24
24
  * And transfering data back & forth is both complex (see transferables) and costly (time)
25
25
  **/
26
26
  const rebuildSolids = (data, callback) => {
27
- console.log('rebuildSolids',data)
28
27
  const defaults = {
29
28
  mainPath: '',
30
29
  apiMainPath: '@jscad/modeling',
@@ -47,7 +46,6 @@ const rebuildSolids = (data, callback) => {
47
46
  parameterDefaults: designData.parameterValues,
48
47
  parameterDefinitions: designData.parameterDefinitions
49
48
  })
50
- // console.warn(`loadDesignData`, new Date() - start)
51
49
  // make sure parameters are correct by applying parameter definitions
52
50
  // this might be redundant with ui-side logic, but it makes sure this core piece works regardless of ui
53
51
  parameterValues = applyParameterDefinitions(parameterValues, designData.parameterDefinitions)
@@ -59,7 +57,6 @@ const rebuildSolids = (data, callback) => {
59
57
  serialize
60
58
  }
61
59
  const solidsData = instanciateDesign(designData.rootModule, parameterValues, options)
62
- // console.warn(`instanciateDesign`, new Date() - start)
63
60
 
64
61
  // send back solids & any other metadata
65
62
  callback(null, {
@@ -7,10 +7,9 @@ const makeWebRequire = require('../code-loading/webRequire')
7
7
 
8
8
  const rebuildSolids = (data) => {
9
9
  const defaults = {
10
- apiMainPath: '@jscad/modeling',
11
- serialize: false
10
+ apiMainPath: '@jscad/modeling'
12
11
  }
13
- let { apiMainPath, serialize, mainPath, parameterValues, useFakeFs } = Object.assign({}, defaults, data)
12
+ let { apiMainPath, mainPath, parameterValues, useFakeFs } = Object.assign({}, defaults, data)
14
13
  // we need to update the source for our module
15
14
  let requireFn = require
16
15
 
@@ -11,7 +11,7 @@ const serializeSolids = (solids) => {
11
11
  // imcomplete support for transfering objects via web workers
12
12
 
13
13
  // NOTE: JSON.stringify was used at some point, but was removed because it was no longer needed
14
- // for postMessage JavaScript engines now use an optimized structured clone alg.
14
+ // for postMessage JavaScript engines now use an optimized structured clone alg.
15
15
  // which should be at least as fast as JSON.stringify
16
16
  solids = solids.map((object) => {
17
17
  // apply the transforms before serializing
@@ -23,5 +23,4 @@ const serializeSolids = (solids) => {
23
23
  return solids
24
24
  }
25
25
 
26
-
27
26
  module.exports = serializeSolids
@@ -1,4 +1,3 @@
1
- // loading
2
1
  const { registerAllExtensions } = require('../io/registerExtensions')
3
2
 
4
3
  const transformSources = require('./transformSources')
@@ -16,27 +15,6 @@ const getAllParameterDefintionsAndValues = require('../parameters/getParameterDe
16
15
  * @param {Object} parameterValuesOverride - the values to use to override the defaults for the current design
17
16
  */
18
17
  const loadDesign = (mainPath, apiMainPath, filesAndFolders, parameterValuesOverride) => {
19
- // console.log('***** loadDesign',mainPath)
20
- // the root script is the main entry point in a design
21
- // ie either the only file if there is only one
22
- // OR the file in the 'main' entry of package.js, index.js, main.js or <folderName>.js
23
-
24
- /*
25
- - if the script is a common.js file already
26
- > load as it is
27
- - if we have real require() access (CLI, desktop)
28
- use standard require() to load the rootScript
29
- - if we do NOT have real require() access (web)
30
- use fake require() to load the rootScript
31
- - if the script is NOT a common.js file (implicit imports)
32
- > add explicit api imports to the rootScript's source
33
- > add explicit exports ie module.exports {main, getParameterDefinitions}
34
- - if we have real require() access (CLI, desktop)
35
- use standard require() to load the rootScript
36
- - if we do NOT have real require() access (web)
37
- use fake require() to load the rootScript
38
- */
39
-
40
18
  // transform the source if passed non-javascript content, i.e. stl
41
19
  filesAndFolders = transformSources({ apiMainPath }, filesAndFolders)
42
20
 
@@ -52,8 +30,6 @@ const loadDesign = (mainPath, apiMainPath, filesAndFolders, parameterValuesOverr
52
30
  }
53
31
  ]
54
32
  }
55
- // console.log('filesAndFolders',filesAndFolders)
56
-
57
33
  const fakeFs = makeFakeFs(filesAndFolders)
58
34
 
59
35
  const webRequire = makeWebRequire(filesAndFolders, { apiMainPath })
@@ -64,8 +40,6 @@ const loadDesign = (mainPath, apiMainPath, filesAndFolders, parameterValuesOverr
64
40
  // find the root module
65
41
  let rootModule = webRequire(filesAndFolders[0].fullPath)
66
42
 
67
- // console.log('***** rootModule',rootModule)
68
-
69
43
  rootModule = normalizeDesignModule(rootModule)
70
44
 
71
45
  // rootModule SHOULD contain a main() entry and optionally a getParameterDefinitions entry
@@ -13,7 +13,6 @@ const makeFakeFs = (filesAndFolders) => {
13
13
  }
14
14
  }
15
15
  return undefined
16
- // return filesAndFolders
17
16
  }
18
17
 
19
18
  const statSync = (path) => {
@@ -27,16 +26,13 @@ const makeFakeFs = (filesAndFolders) => {
27
26
  statSync,
28
27
  existsSync: (path) => {
29
28
  const entry = findMatch(path)
30
- // console.log('does ', path, 'exist ?', entry !== undefined)
31
29
  return entry !== undefined
32
30
  },
33
31
  readdirSync: (path) => {
34
32
  const entry = findMatch(path)
35
33
  return entry.children.map((x) => x.name)
36
- // filesAndFolders
37
34
  },
38
35
  readDir: (path, callback) => {
39
- // console.log('readDir', path, callback)
40
36
  const entry = findMatch(path)
41
37
  callback(null, entry)
42
38
  },
@@ -48,7 +44,6 @@ const makeFakeFs = (filesAndFolders) => {
48
44
  if (!statSync(path).isFile()) {
49
45
  callback(new Error(`${entry} is not a file, cannot read`))
50
46
  } else {
51
- // console.log('readFile', path, entry)
52
47
  callback(null, entry.source)
53
48
  }
54
49
  },
@@ -60,7 +55,6 @@ const makeFakeFs = (filesAndFolders) => {
60
55
  if (!statSync(path).isFile()) {
61
56
  throw new Error(`${entry} is not a file, cannot read`)
62
57
  } else {
63
- // console.log('readFile sync', path, entry)
64
58
  return entry.source
65
59
  }
66
60
  }
@@ -4,7 +4,8 @@
4
4
  */
5
5
  const modulifySource = (source, apiMainPath) => {
6
6
  const getParamsString = source.includes('getParameterDefinitions')
7
- ? 'module.exports.getParameterDefinitions = getParameterDefinitions' : ''
7
+ ? 'module.exports.getParameterDefinitions = getParameterDefinitions'
8
+ : ''
8
9
  const updatedSource = `
9
10
  const {geom2, geom3, path2, pol2, poly3} = require('${apiMainPath}').geometries
10
11
 
@@ -3,17 +3,17 @@
3
3
  */
4
4
  const normalizeDesignModule = (rootModule) => {
5
5
  if (!rootModule) {
6
- throw new Error('no root module found')
6
+ throw new Error('no root module found, please check the project structure')
7
7
  }
8
8
  if (typeof (rootModule) === 'function') {
9
- console.warn('please use named exports for the main() function')
9
+ console.warn('please refactor the exports, assigning main() as a property, i.e. module.exports = { main }')
10
10
  rootModule = { main: rootModule }
11
11
  }
12
12
  if (!rootModule.main) {
13
- throw new Error('no main() function, check the exports')
13
+ throw new Error('no main() function found, please check the module.exports')
14
14
  }
15
- if (!(typeof (rootModule.main) === 'function')) {
16
- throw new Error('main is not a function, check the exports')
15
+ if (typeof (rootModule.main) !== 'function') {
16
+ throw new Error('main is not a function, please check the module.exports')
17
17
  }
18
18
  return rootModule
19
19
  }
@@ -1,19 +1,9 @@
1
1
  const { deserializers } = require('@jscad/io')
2
2
 
3
- const isCommonJsModule = require('./isCommonJsModule')
4
- const modulifySource = require('./modulifySource')
5
-
6
- const passThroughTransform = (options, entry) => entry
7
-
8
- /* function to turn old style jscad code with implicit imports
9
- into code with explicit exports/imports */
10
- // FIXME wouldn't a javascript error be better then 'hacking' the users code?
11
- const modulifyTransform = (options, entry) => {
12
- const { apiMainPath } = options
13
- const isFileCommonJs = isCommonJsModule(entry.source)
14
- const source = !isFileCommonJs ? modulifySource(entry.source, apiMainPath) : entry.source
15
- return Object.assign({}, entry, { source })
16
- }
3
+ /*
4
+ * Transform the entry into a ready-to-use module.
5
+ */
6
+ const modulifyTransform = (options, entry) => Object.assign({}, entry, { source: entry.source })
17
7
 
18
8
  /*
19
9
  * Create a new entry for a script (JSCAD) from the given entry and source
@@ -32,8 +22,6 @@ const createJscadEntry = (entry, source) => {
32
22
  * Transforms are NOT applied to projects.
33
23
  */
34
24
  const transformSources = (options, filesAndFolders) => {
35
- // console.log('***** transformSources', options, filesAndFolders)
36
-
37
25
  if (filesAndFolders && filesAndFolders.length > 1) return filesAndFolders // skip projects
38
26
 
39
27
  const codeTransforms = {
@@ -72,6 +72,7 @@ const makeWebRequire = (filesAndFolders, options) => {
72
72
  // console.log('*****\n',filesAndFolders,'\n*****')
73
73
 
74
74
  const extensions = {}
75
+ const moduleCache = {}
75
76
 
76
77
  /* Require (obtain) the exports for the given require path, relative to the given current path.
77
78
  * The logic is based on the original NODE require() function.
@@ -105,11 +106,12 @@ const makeWebRequire = (filesAndFolders, options) => {
105
106
  if (entry.children) return null // directory
106
107
 
107
108
  if (extensions[baseExt]) {
109
+ if (moduleCache[requirePath]) return moduleCache[requirePath]
108
110
  // evaluate the content
109
111
  const matchingModule = {
110
112
  exports: {},
111
113
  _compile: (content, fileName) => {
112
- const moduleMakerFunction = new Function('require', 'module', content)
114
+ const moduleMakerFunction = new Function('require', 'module', content) // eslint-disable-line no-new-func
113
115
  moduleMakerFunction(_require.bind(null, entry.fullPath), matchingModule)
114
116
 
115
117
  const paramDefFromSource = content.includes('@jscad-params') ? getParameterDefinitionsFromSource(content, fileName) : []
@@ -121,7 +123,8 @@ const makeWebRequire = (filesAndFolders, options) => {
121
123
  }
122
124
  }
123
125
  extensions[baseExt](matchingModule, entry.fullPath)
124
- return matchingModule.exports
126
+ moduleCache[requirePath] = matchingModule.exports
127
+ return moduleCache[requirePath]
125
128
  }
126
129
  return null
127
130
  }
@@ -13,10 +13,14 @@ test('webRequire: should support require, from a single file', (t) => {
13
13
 
14
14
  let requireFn = makeWebRequire(singleFileJs, { apiMainPath })
15
15
  let designRootModule = requireFn(singleFileJs[0].fullPath)
16
+ const designRootModule2 = requireFn(singleFileJs[0].fullPath)
16
17
 
17
18
  t.true('main' in designRootModule)
18
19
  t.true(designRootModule.main instanceof Function)
19
20
 
21
+ t.is(designRootModule, designRootModule2)
22
+ t.deepEqual(designRootModule, designRootModule2)
23
+
20
24
  // NOTE: 'jscad' must be registered as an extension
21
25
  const fakeFs = makeFakeFs(singleFileJscad)
22
26
  requireFn = makeWebRequire(singleFileJscad, { apiMainPath })
@@ -32,7 +36,6 @@ test('webRequire: should support require, from a directory with index.js', (t) =
32
36
 
33
37
  const requireFn = makeWebRequire(directoryWithIndexJs, { apiMainPath })
34
38
  const designRootModule = requireFn('/project')
35
-
36
39
  t.true('main' in designRootModule)
37
40
  t.true(designRootModule.main instanceof Function)
38
41
  })
@@ -224,5 +224,5 @@ test('multiline error', (t) => {
224
224
  test('single line /* ...*/ ok', (t) => {
225
225
  t.deepEqual(getParameterDefinitionsFromSource(`function main({//@jscad-params
226
226
  /* group */
227
- width=14})`), [{type:'group', caption:'group', name:'_group_1'},...sampleParams2])
227
+ width=14})`), [{ type: 'group', caption: 'group', name: '_group_1' }, ...sampleParams2])
228
228
  })
@@ -13,14 +13,6 @@ const getParameterValuesFromUIControls = (paramControls, parameterDefinitions, o
13
13
  switch (control.paramType) {
14
14
  case 'choice':
15
15
  value = control.options[control.selectedIndex].value
16
- /* console.log('choice', control, control.paramName)
17
- // we try to match values against captions, then parse as numbers if applicable, then fallback to original value
18
- const valueIndex = !definition ? -1 : definition.captions.indexOf(value)
19
- const valueInDefinition = valueIndex > -1
20
- // const valueInDefintionCaptionsAndValue = valueInDefinition && definition.values.length >= valueIndex
21
- value = definition.values.length > 0 && isNumber(definition.values[0]) ? parseFloat(value) : value
22
- value = definition.values.length > 0 && typeof value === 'boolean' ? !!value : value
23
- console.log('foo', value) */
24
16
  break
25
17
  case 'float':
26
18
  case 'number':
@@ -63,7 +55,6 @@ const getParameterValuesFromUIControls = (paramControls, parameterDefinitions, o
63
55
  }
64
56
  }
65
57
  parameterValues[control.paramName] = value
66
- // console.log(control.paramName+":"+parameterValues[control.paramName])
67
58
  }
68
59
  return parameterValues
69
60
  }
@@ -30,8 +30,6 @@ const binaryMimetypes = {
30
30
  * @returns {Promise} new promise to read and convert the file
31
31
  */
32
32
  const readFileAsync = (file, fileMeta) => {
33
- // console.log('readFileAsync',file,fileMeta)
34
-
35
33
  const fullPath = file.fullPath ? file.fullPath : fileMeta.fullPath ? fileMeta.fullPath : ''
36
34
  const ext = getFileExtensionFromString(file.name)
37
35
  const mimetype = file.mimetype
@@ -43,7 +41,7 @@ const readFileAsync = (file, fileMeta) => {
43
41
  const result = event.target.result
44
42
  if (result.byteLength) {
45
43
  resolve({ name: file.name, ext, fullPath, mimetype, source: result })
46
- } else if (typeof(result) === 'string') {
44
+ } else if (typeof result === 'string') {
47
45
  resolve({ name: file.name, ext, fullPath, mimetype, source: result })
48
46
  }
49
47
  }
@@ -87,7 +85,6 @@ const isEmpty = (x) => x !== null && x !== undefined // skip empty items
87
85
  * @returns {Promise} one promise to resolve them all
88
86
  */
89
87
  const processEntries = (items) => {
90
- // console.log('processEntries',items)
91
88
  const results = pseudoArraytoArray(items.filter(isEmpty))
92
89
  .filter(isEmpty) // skip empty items
93
90
  .reduce((result, item) => {
@@ -117,7 +114,6 @@ const processEntries = (items) => {
117
114
  * @returns {Promise} new promise to read and process the file
118
115
  */
119
116
  const processFile = (fileItem) => {
120
- // console.log('processFile',fileItem)
121
117
  const promiseFile = new Promise((resolve, reject) => {
122
118
  fileItem.file(
123
119
  (fileData) => {
@@ -138,7 +134,6 @@ const processFile = (fileItem) => {
138
134
  * @returns {Promise} new promise to read and process the directory
139
135
  */
140
136
  const processDirectory = (directory) => {
141
- // console.log('processDirectory',directory)
142
137
  const promiseDirectory = new Promise((resolve, reject) => {
143
138
  if (directory.entries) {
144
139
  directory.entries.length ? processEntries(directory.entries).then(resolve) : resolve([])