@jseeio/jsee 0.3.7 → 0.3.9
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/.claude/settings.local.json +12 -0
- package/.eslintrc.js +38 -0
- package/AGENTS.md +38 -0
- package/CHANGELOG.md +86 -0
- package/CLAUDE.md +5 -0
- package/README.md +60 -42
- package/bin/jsee +1 -1
- package/dist/jsee.js +1 -1
- package/dist/jsee.runtime.js +1 -1
- package/jest-puppeteer.config.js +7 -5
- package/jest.unit.config.js +8 -0
- package/load/index.html +16 -4
- package/package.json +17 -13
- package/src/app.js +35 -11
- package/src/cli.js +591 -330
- package/src/constants.js +12 -0
- package/src/main.js +356 -183
- package/src/utils.js +748 -3
- package/src/worker.js +42 -18
- package/templates/bulma-app.vue +3 -2
- package/templates/bulma-input.vue +23 -18
- package/templates/bulma-output.vue +72 -7
- package/templates/common-inputs.js +2 -13
- package/templates/common-outputs.js +57 -2
- package/templates/file-picker-base.vue +169 -0
- package/templates/file-picker.vue +350 -0
- package/test/fixtures/lodash-like.js +15 -0
- package/test/fixtures/upload-sample.csv +3 -0
- package/test/test-basic.test.js +383 -17
- package/test/test-python.test.js +2 -5
- package/test/unit/cli-fetch.test.js +126 -0
- package/test/unit/utils.test.js +806 -0
- package/webpack.config.js +1 -0
package/jest-puppeteer.config.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
launch: {
|
|
3
3
|
dumpio: false, // dump browser errors to jest
|
|
4
|
-
headless: process.env.HEADLESS
|
|
4
|
+
headless: process.env.HEADLESS === 'false' ? false : 'new', // Use new headless mode by default
|
|
5
5
|
product: 'chrome',
|
|
6
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
7
|
+
},
|
|
8
|
+
server: {
|
|
9
|
+
command: 'npx http-server -p 8484 --silent',
|
|
10
|
+
port: 8484,
|
|
11
|
+
launchTimeout: 10000,
|
|
6
12
|
},
|
|
7
|
-
// server: {
|
|
8
|
-
// command: 'http-server',
|
|
9
|
-
// port: 8081,
|
|
10
|
-
// },
|
|
11
13
|
browserContext: 'default',
|
|
12
14
|
}
|
package/load/index.html
CHANGED
|
@@ -12,9 +12,16 @@
|
|
|
12
12
|
max-width: 1100px;
|
|
13
13
|
margin: auto;
|
|
14
14
|
}
|
|
15
|
+
#loader-tip {
|
|
16
|
+
max-width: 1100px;
|
|
17
|
+
margin: 8px auto 0;
|
|
18
|
+
font-size: 12px;
|
|
19
|
+
color: #666;
|
|
20
|
+
}
|
|
15
21
|
</style>
|
|
16
22
|
</head>
|
|
17
23
|
<body>
|
|
24
|
+
<div id="loader-tip">Tip: schema inputs can be prefilled via query params, including file URLs that now auto-load.</div>
|
|
18
25
|
<div id="jsee-container"></div>
|
|
19
26
|
<script src="/dist/jsee.js" type="text/javascript"></script>
|
|
20
27
|
<script>window.JSEE || document.write('<script src="https://cdn.jsdelivr.net/npm/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
@@ -30,10 +37,15 @@
|
|
|
30
37
|
schema = schemaStr.includes('/') ? schemaStr : '/apps/' + schemaStr + '/schema.json'
|
|
31
38
|
}
|
|
32
39
|
console.log('[Loader] Schema:', schemaStr, schema)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
try {
|
|
41
|
+
const env = new JSEE({
|
|
42
|
+
container: document.getElementById('jsee-container'),
|
|
43
|
+
schema: schema
|
|
44
|
+
})
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error('[Loader] Failed to initialize JSEE:', error)
|
|
47
|
+
document.getElementById('jsee-container').innerHTML = '<pre style="color:#f14668;padding:16px;border:1px solid #f14668;border-radius:6px;">Failed to initialize schema. Check browser console for details.</pre>'
|
|
48
|
+
}
|
|
37
49
|
}
|
|
38
50
|
</script>
|
|
39
51
|
</body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jseeio/jsee",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"description": "JavaScript Execution Environment",
|
|
5
5
|
"main": "dist/jsee.js",
|
|
6
6
|
"unpkg": "dist/jsee.js",
|
|
@@ -9,12 +9,15 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build-dev": "webpack --mode=development --progress --stats-children --env DEVELOPMENT",
|
|
11
11
|
"build": "webpack --mode=production --progress && webpack --mode=production --progress --env RUNTIME && npm test",
|
|
12
|
+
"watch-dev": "nodemon --watch . --ignore dist,.git --ext vue,js,css,html --exec 'npm run build-dev'",
|
|
12
13
|
"watch": "nodemon --watch . --ignore dist,.git --ext vue,js,css,html --exec 'npm run build-dev && npm run test:basic'",
|
|
13
14
|
"prepublishOnly": "npm run build",
|
|
14
|
-
"test": "npm run test:basic && npm run test:python",
|
|
15
|
+
"test": "npm run test:unit && npm run test:basic && npm run test:python",
|
|
16
|
+
"test:unit": "jest --config jest.unit.config.js",
|
|
15
17
|
"test:basic": "jest test/test-basic.test.js --detectOpenHandles",
|
|
16
18
|
"test:python": "jest test/test-python.test.js --detectOpenHandles",
|
|
17
|
-
"test-head": "HEADLESS=false npm test"
|
|
19
|
+
"test-head": "HEADLESS=false npm test",
|
|
20
|
+
"lint": "eslint src/ test/"
|
|
18
21
|
},
|
|
19
22
|
"bin": {
|
|
20
23
|
"jsee": "./bin/jsee"
|
|
@@ -32,18 +35,19 @@
|
|
|
32
35
|
"dependencies": {
|
|
33
36
|
"@mdi/font": "^6.5.95",
|
|
34
37
|
"bulma": "^0.9.3",
|
|
35
|
-
"csv-parse": "^
|
|
38
|
+
"csv-parse": "^5.6.0",
|
|
36
39
|
"dom-to-image": "^2.6.0",
|
|
37
|
-
"
|
|
38
|
-
"express": "^4.19.2",
|
|
40
|
+
"express": "^4.21.2",
|
|
39
41
|
"file-saver": "^2.0.2",
|
|
40
42
|
"filtrex": "^2.2.3",
|
|
41
43
|
"jsdoc-to-markdown": "^8.0.1",
|
|
44
|
+
"katex": "^0.16.22",
|
|
42
45
|
"minimist": "^1.2.8",
|
|
43
46
|
"notyf": "^3.10.0",
|
|
44
47
|
"showdown": "^1.9.1",
|
|
45
48
|
"showdown-katex": "^0.8.0",
|
|
46
49
|
"vue": "^3.2.47",
|
|
50
|
+
"vue-file-picker": "^0.0.2",
|
|
47
51
|
"vue-style-loader": "^4.1.3",
|
|
48
52
|
"vue3-json-viewer": "^2.2.2",
|
|
49
53
|
"vuex": "^4.0.2"
|
|
@@ -54,20 +58,20 @@
|
|
|
54
58
|
"@babel/preset-env": "^7.16.5",
|
|
55
59
|
"babel-loader": "^9.1.2",
|
|
56
60
|
"css-loader": "^6.7.3",
|
|
57
|
-
"
|
|
61
|
+
"eslint": "^8.57.1",
|
|
62
|
+
"expect-puppeteer": "^11.0.0",
|
|
58
63
|
"http-server": "^14.1.1",
|
|
59
|
-
"jest": "^29.
|
|
60
|
-
"jest-puppeteer": "^
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
+
"jest": "^29.7.0",
|
|
65
|
+
"jest-puppeteer": "^11.0.0",
|
|
66
|
+
"nodemon": "^3.1.10",
|
|
67
|
+
"puppeteer": "^24.10.2",
|
|
68
|
+
"sass": "^1.83.4",
|
|
64
69
|
"sass-loader": "^13.2.2",
|
|
65
70
|
"source-map-loader": "^4.0.1",
|
|
66
71
|
"style-loader": "^3.3.2",
|
|
67
72
|
"terser-webpack-plugin": "^5.3.7",
|
|
68
73
|
"uglify-es": "^3.3.9",
|
|
69
74
|
"vue-loader": "^17.0.1",
|
|
70
|
-
"vue-template-compiler": "^2.7.14",
|
|
71
75
|
"webpack": "^5.78.0",
|
|
72
76
|
"webpack-cli": "^5.0.1",
|
|
73
77
|
"worker-loader": "^3.0.8"
|
package/src/app.js
CHANGED
|
@@ -19,17 +19,34 @@ const components = {
|
|
|
19
19
|
|
|
20
20
|
const filtrex = require('filtrex')
|
|
21
21
|
const JsonViewer = require('vue3-json-viewer').default
|
|
22
|
+
const { sanitizeName, debounce } = require('./utils.js')
|
|
23
|
+
|
|
24
|
+
function setInputValue (input, value) {
|
|
25
|
+
if (input.type === 'file') {
|
|
26
|
+
// For file inputs, we need to set the url
|
|
27
|
+
input.url = value
|
|
28
|
+
input.file = null // Reset file object
|
|
29
|
+
} else {
|
|
30
|
+
// For other inputs, we can set the value directly
|
|
31
|
+
input.value = value
|
|
32
|
+
}
|
|
33
|
+
}
|
|
22
34
|
|
|
23
35
|
function resetInputs (inputs, example) {
|
|
24
36
|
inputs.forEach((input, index) => {
|
|
37
|
+
const inputName = input.name ? sanitizeName(input.name) : `input_${index}`
|
|
25
38
|
if (example && input.name && example[input.name]) {
|
|
26
|
-
// Object
|
|
27
|
-
input
|
|
28
|
-
} else if (example && example[
|
|
39
|
+
// Object (unsanitized)
|
|
40
|
+
setInputValue(input, example[input.name])
|
|
41
|
+
} else if (example && inputName && example[inputName]) {
|
|
42
|
+
// Object (sanitized)
|
|
43
|
+
setInputValue(input, example[inputName])
|
|
44
|
+
} else if (example && Array.isArray(example) && typeof example[index] !== 'undefined') {
|
|
29
45
|
// Array
|
|
30
|
-
input
|
|
46
|
+
setInputValue(input, example[index])
|
|
31
47
|
} else if (input.default) {
|
|
32
|
-
|
|
48
|
+
// Default value
|
|
49
|
+
setInputValue(input, input.default)
|
|
33
50
|
} else {
|
|
34
51
|
switch (input.type) {
|
|
35
52
|
case 'int':
|
|
@@ -101,7 +118,11 @@ function createVueApp (env, mountedCallback, logMain) {
|
|
|
101
118
|
return function DisplayConditionally (data) {
|
|
102
119
|
const inputObj = {}
|
|
103
120
|
data.inputs.filter(input => input.name).forEach(input => {
|
|
121
|
+
// Sanitize input name. This will allow to operate with human-readable names
|
|
122
|
+
// and use them as object keys. For example, 'Input 1' will be converted to 'input_1'
|
|
123
|
+
const inputNameSanitized = sanitizeName(input.name)
|
|
104
124
|
inputObj[input.name] = input.value
|
|
125
|
+
inputObj[inputNameSanitized] = input.value
|
|
105
126
|
})
|
|
106
127
|
return f(inputObj)
|
|
107
128
|
}
|
|
@@ -154,12 +175,14 @@ function createVueApp (env, mountedCallback, logMain) {
|
|
|
154
175
|
inputs: {
|
|
155
176
|
deep: true,
|
|
156
177
|
immediate: false,
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
178
|
+
// schema.reactive enables global re-run on any input change (debounced).
|
|
179
|
+
// Per-input reactivity uses the 'inchange' event from inputs with reactive: true.
|
|
180
|
+
handler: debounce(function (v) {
|
|
181
|
+
this.dataChanged = true
|
|
182
|
+
if (env.schema.reactive) {
|
|
183
|
+
this.run('reactive')
|
|
161
184
|
}
|
|
162
|
-
}
|
|
185
|
+
}, 300)
|
|
163
186
|
}
|
|
164
187
|
},
|
|
165
188
|
mounted () {
|
|
@@ -182,7 +205,8 @@ function createVueApp (env, mountedCallback, logMain) {
|
|
|
182
205
|
},
|
|
183
206
|
run (caller) {
|
|
184
207
|
this.clickRun = true
|
|
185
|
-
|
|
208
|
+
// Catch to prevent unhandled rejection from button/autorun clicks
|
|
209
|
+
env.run(caller).catch(err => console.error('Run error:', err))
|
|
186
210
|
setTimeout(() => {
|
|
187
211
|
this.clickRun = false
|
|
188
212
|
}, 150)
|