@jseeio/jsee 0.2.6 → 0.2.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.
- package/CHANGELOG.md +4 -18
- package/README.md +53 -28
- package/dist/jsee.js +1 -1
- package/dist/jsee.runtime.js +1 -1
- package/{load.html → load/index.html} +12 -7
- package/main.js +59 -25
- package/package.json +1 -1
- package/templates/bulma-app.vue +20 -2
- package/templates/bulma-output.vue +1 -7
- package/test/minimal1.html +13 -0
- package/test/minimal2.html +15 -0
- package/test/minimal3.html +10 -0
- package/test/minimal4.html +22 -0
- package/test/sumw.schema.json +0 -2
- package/test.js +43 -4
- package/404.html +0 -22
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
6
6
|
<title>JSEE Schema Loader</title>
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: sans-serif;
|
|
10
|
+
}
|
|
11
|
+
#jsee-container {
|
|
12
|
+
max-width: 1100px;
|
|
13
|
+
margin: auto;
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
7
16
|
</head>
|
|
8
17
|
<body>
|
|
9
18
|
<div id="jsee-container"></div>
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
</
|
|
13
|
-
<script src="dist/jsee.js" type="text/javascript"></script>
|
|
19
|
+
<script src="/dist/jsee.js" type="text/javascript"></script>
|
|
20
|
+
<script>window.JSEE || document.write('<script src="https://cdn.jsdelivr.net/npm/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
21
|
+
<script>window.JSEE || document.write('<script src="https://unpkg.com/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
14
22
|
<script>
|
|
15
23
|
var params = new URLSearchParams(window.location.search)
|
|
16
24
|
var schemaStr = params.get('s')
|
|
@@ -26,9 +34,6 @@
|
|
|
26
34
|
container: document.getElementById('jsee-container'),
|
|
27
35
|
schema: schema
|
|
28
36
|
})
|
|
29
|
-
} else {
|
|
30
|
-
document.getElementById('port-container').style.display = 'none'
|
|
31
|
-
document.getElementById('txt-container').style.display = 'block'
|
|
32
37
|
}
|
|
33
38
|
</script>
|
|
34
39
|
</body>
|
package/main.js
CHANGED
|
@@ -48,9 +48,17 @@ function isObject (item) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function getName (code) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
switch (typeof code) {
|
|
52
|
+
case 'function':
|
|
53
|
+
return code.name
|
|
54
|
+
case 'string':
|
|
55
|
+
const words = code.split(' ')
|
|
56
|
+
const functionIndex = words.findIndex((word) => word == 'function')
|
|
57
|
+
const name = words[functionIndex + 1]
|
|
58
|
+
return name.includes('(') ? undefined : name
|
|
59
|
+
default:
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
// Return input value
|
|
@@ -66,7 +74,7 @@ function getValue (input) {
|
|
|
66
74
|
}
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
function
|
|
77
|
+
function getModelType (model) {
|
|
70
78
|
if (model.code && typeof model.code === 'string' && model.code.split(' ').map(v => v.trim()).includes('def')) {
|
|
71
79
|
return 'py'
|
|
72
80
|
} else if (model.url) {
|
|
@@ -103,28 +111,48 @@ function getFunctionContainer (target) {
|
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
export default class JSEE {
|
|
106
|
-
constructor (params,
|
|
107
|
-
|
|
108
|
-
if
|
|
114
|
+
constructor (params, alt1, alt2) {
|
|
115
|
+
|
|
116
|
+
// Check if JSEE was initialized with args rather than with a params object
|
|
117
|
+
if (('model' in params) || (typeof params === 'string') || (typeof params === 'function') || !(typeof alt === 'undefined')) {
|
|
109
118
|
params = {
|
|
110
119
|
'schema': params,
|
|
111
|
-
'container':
|
|
120
|
+
'container': alt1,
|
|
121
|
+
'verbose': alt2
|
|
112
122
|
}
|
|
113
123
|
}
|
|
114
124
|
|
|
125
|
+
// Set global verbose flag
|
|
115
126
|
verbose = !(params.verbose === false)
|
|
116
127
|
|
|
117
|
-
|
|
128
|
+
// Previous naming
|
|
118
129
|
params.schema = params.schema || params.config
|
|
130
|
+
|
|
131
|
+
log('Initializing JSEE with parameters: ', params)
|
|
119
132
|
this.params = params
|
|
120
133
|
this.__version__ = VERSION
|
|
121
134
|
|
|
122
135
|
// Get schema then initialize a new environment
|
|
123
|
-
|
|
124
|
-
|
|
136
|
+
switch (typeof params.schema) {
|
|
137
|
+
case 'object':
|
|
125
138
|
log('Received schema as object')
|
|
139
|
+
if (typeof params.schema.model === 'function') {
|
|
140
|
+
params.schema.model = {
|
|
141
|
+
code: params.schema.model
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
this.init(params.schema)
|
|
145
|
+
break
|
|
146
|
+
case 'function':
|
|
147
|
+
log('Received schema as function')
|
|
148
|
+
params.schema = {
|
|
149
|
+
model: {
|
|
150
|
+
code: params.schema,
|
|
151
|
+
}
|
|
152
|
+
}
|
|
126
153
|
this.init(params.schema)
|
|
127
|
-
|
|
154
|
+
break
|
|
155
|
+
case 'string':
|
|
128
156
|
log('Received schema as string')
|
|
129
157
|
this.schemaUrl = params.schema.indexOf('json') ? params.schema : params.schema + '.json'
|
|
130
158
|
fetch(this.schemaUrl)
|
|
@@ -136,7 +164,10 @@ export default class JSEE {
|
|
|
136
164
|
.catch((err) => {
|
|
137
165
|
console.error(err)
|
|
138
166
|
})
|
|
139
|
-
|
|
167
|
+
break
|
|
168
|
+
default:
|
|
169
|
+
log('No schema provided')
|
|
170
|
+
notyf.error('No schema provided')
|
|
140
171
|
}
|
|
141
172
|
}
|
|
142
173
|
|
|
@@ -170,12 +201,6 @@ export default class JSEE {
|
|
|
170
201
|
log('Loaded code from:', url)
|
|
171
202
|
resolve(res)
|
|
172
203
|
})
|
|
173
|
-
} else if (typeof schema === 'function') {
|
|
174
|
-
log('Code is: schema')
|
|
175
|
-
resolve(schema)
|
|
176
|
-
} else if (typeof schema.model === 'function') {
|
|
177
|
-
log('Code is: schema.model')
|
|
178
|
-
resolve(schema.model)
|
|
179
204
|
} else if (!(typeof schema.model.code === 'undefined')) {
|
|
180
205
|
log('Code is: schema.model.code')
|
|
181
206
|
resolve(schema.model.code)
|
|
@@ -222,13 +247,17 @@ export default class JSEE {
|
|
|
222
247
|
|
|
223
248
|
// Infer model type
|
|
224
249
|
if (typeof schema.model.type === 'undefined') {
|
|
225
|
-
schema.model.type =
|
|
250
|
+
schema.model.type = getModelType(schema.model)
|
|
226
251
|
}
|
|
227
252
|
|
|
228
253
|
// Update model name if absent
|
|
229
|
-
if (
|
|
230
|
-
schema.model.
|
|
231
|
-
|
|
254
|
+
if (typeof schema.model.name === 'undefined'){
|
|
255
|
+
if ((schema.model.url) && (schema.model.url.includes('.js'))) {
|
|
256
|
+
schema.model.name = schema.model.url.split('/').pop().split('.')[0]
|
|
257
|
+
log('Use model name from url: ', schema.model.name)
|
|
258
|
+
} else if (schema.model.code) {
|
|
259
|
+
schema.model.name = getName(schema.model.code)
|
|
260
|
+
}
|
|
232
261
|
}
|
|
233
262
|
|
|
234
263
|
// At this point we have all code in model.code or api
|
|
@@ -372,11 +401,16 @@ export default class JSEE {
|
|
|
372
401
|
|
|
373
402
|
if (this.schema.model.worker) {
|
|
374
403
|
// Worker: Initialize worker with the model
|
|
375
|
-
|
|
376
|
-
|
|
404
|
+
// 2 -> 1
|
|
405
|
+
if (typeof this.schema.model.code === 'function') {
|
|
377
406
|
log('Convert code in schema to string for WebWorker')
|
|
378
407
|
this.schema.model.code = this.schema.model.code.toString()
|
|
379
408
|
}
|
|
409
|
+
// Wrap anonymous functions
|
|
410
|
+
if (!this.schema.model.name) {
|
|
411
|
+
this.schema.model.code = `function anon () { return (${this.schema.model.code})(...arguments) }`
|
|
412
|
+
this.schema.model.name = 'anon'
|
|
413
|
+
}
|
|
380
414
|
this.worker.postMessage(this.schema.model)
|
|
381
415
|
} else {
|
|
382
416
|
// Main: Initialize model in main window
|
package/package.json
CHANGED
package/templates/bulma-app.vue
CHANGED
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
background: none;
|
|
66
66
|
padding: .75rem 1.5rem;
|
|
67
67
|
border: none !important;
|
|
68
|
+
border-radius: .25rem !important;
|
|
68
69
|
font-size: 14px;
|
|
69
70
|
font-weight: 400;
|
|
70
|
-
border-radius: 0;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
.reset-button {
|
|
@@ -76,7 +76,8 @@
|
|
|
76
76
|
|
|
77
77
|
.reset-button:hover {
|
|
78
78
|
background-color: transparent !important;
|
|
79
|
-
background: linear-gradient(90deg, #ff3a56 0%, #fff0 80%)
|
|
79
|
+
background: linear-gradient(90deg, #ff3a56 0%, #fff0 80%);
|
|
80
|
+
box-shadow: -5px 0px 5px -2px #fd4c7e30;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
.card-footer .run-button {
|
|
@@ -87,6 +88,7 @@
|
|
|
87
88
|
.card-footer .run-button:hover,{
|
|
88
89
|
background-color: transparent !important;
|
|
89
90
|
background: linear-gradient(270deg, #02dbb2 0%, #fff0 80%);
|
|
91
|
+
box-shadow: 5px 0px 5px -2px #48ffd43b;
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
.card-footer .run-button.running .run-icon {
|
|
@@ -99,7 +101,23 @@
|
|
|
99
101
|
|
|
100
102
|
.input, .textarea, .select select {
|
|
101
103
|
border-color: #e8e8e8;
|
|
104
|
+
border-top-left-radius: 0;
|
|
102
105
|
}
|
|
106
|
+
|
|
107
|
+
.input:focus, .textarea:focus, .select select:focus, .is-focused.input, .is-focused.textarea, .select select.is-focused, .input:active, .textarea:active, .select select:active, .is-active.input, .is-active.textarea, .select select.is-active {
|
|
108
|
+
border-color: #7ab8e6;
|
|
109
|
+
box-shadow: 0 0 0 0.125em rgba(72, 139, 199, 0.25);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#inputs .field > label:first-child {
|
|
113
|
+
background: #f2f2f2;
|
|
114
|
+
padding: 1px 5px;
|
|
115
|
+
margin-top: 2px;
|
|
116
|
+
display: inline-block;
|
|
117
|
+
border-top-left-radius: 5px;
|
|
118
|
+
border-top-right-radius: 5px;
|
|
119
|
+
}
|
|
120
|
+
|
|
103
121
|
}
|
|
104
122
|
</style>
|
|
105
123
|
<template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="card mb-5" v-if="output.value">
|
|
2
|
+
<div class="card mb-5" v-if="!(typeof output.value === 'undefined')">
|
|
3
3
|
<header class="card-header">
|
|
4
4
|
<p class="card-header-title is-size-6" v-if="output.name">
|
|
5
5
|
{{ output.name }}
|
|
@@ -23,12 +23,6 @@
|
|
|
23
23
|
<pre>{{ output.value }}</pre>
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
26
|
-
<!--
|
|
27
|
-
<footer class="card-footer" v-if="output.filename">
|
|
28
|
-
<a v-on:click="save()" class="card-footer-item">Save</a>
|
|
29
|
-
<a v-on:click="copy()" class="card-footer-item">Copy</a>
|
|
30
|
-
</footer>
|
|
31
|
-
-->
|
|
32
26
|
</div>
|
|
33
27
|
</template>
|
|
34
28
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!-- Minimal example -->
|
|
2
|
+
<html>
|
|
3
|
+
<div id="jsee-container">
|
|
4
|
+
<script src="/dist/jsee.js"></script>
|
|
5
|
+
<script>window.JSEE || document.write('<script src="https://cdn.jsdelivr.net/npm/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
6
|
+
<script>window.JSEE || document.write('<script src="https://unpkg.com/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
7
|
+
<script>
|
|
8
|
+
function mul (a, b) {
|
|
9
|
+
return a * b
|
|
10
|
+
}
|
|
11
|
+
new JSEE(mul, '#jsee-container')
|
|
12
|
+
</script>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!-- Minimal example -->
|
|
2
|
+
<html>
|
|
3
|
+
<div id="jsee-container">
|
|
4
|
+
<script src="/dist/jsee.js"></script>
|
|
5
|
+
<script>window.JSEE || document.write('<script src="https://cdn.jsdelivr.net/npm/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
6
|
+
<script>window.JSEE || document.write('<script src="https://unpkg.com/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
7
|
+
<script>
|
|
8
|
+
function mul (a, b) {
|
|
9
|
+
return a * b
|
|
10
|
+
}
|
|
11
|
+
new JSEE({
|
|
12
|
+
model: mul
|
|
13
|
+
}, '#jsee-container')
|
|
14
|
+
</script>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<!-- Minimal example -->
|
|
2
|
+
<html>
|
|
3
|
+
<div id="jsee-container">
|
|
4
|
+
<script src="/dist/jsee.js"></script>
|
|
5
|
+
<script>window.JSEE || document.write('<script src="https://cdn.jsdelivr.net/npm/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
6
|
+
<script>window.JSEE || document.write('<script src="https://unpkg.com/@jseeio/jsee@latest/dist/jsee.runtime.js">\x3C/script>')</script>
|
|
7
|
+
<script>
|
|
8
|
+
new JSEE(function (a, b) { return a * b }, '#jsee-container')
|
|
9
|
+
</script>
|
|
10
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<div id="jsee-container">
|
|
3
|
+
<script src="/dist/jsee.js"></script>
|
|
4
|
+
<script>
|
|
5
|
+
new JSEE({
|
|
6
|
+
schema: {
|
|
7
|
+
"model": {
|
|
8
|
+
"name": "div",
|
|
9
|
+
"code": "function div (a) { ruturn a / 2 }"
|
|
10
|
+
},
|
|
11
|
+
"inputs": [
|
|
12
|
+
{
|
|
13
|
+
"name": "a",
|
|
14
|
+
"type": "int",
|
|
15
|
+
"value": 0
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
container: '#jsee-container'
|
|
20
|
+
})
|
|
21
|
+
</script>
|
|
22
|
+
</html>
|
package/test/sumw.schema.json
CHANGED
package/test.js
CHANGED
|
@@ -3,9 +3,9 @@ require('expect-puppeteer')
|
|
|
3
3
|
page.setDefaultTimeout(1000)
|
|
4
4
|
|
|
5
5
|
const port = 8080
|
|
6
|
-
const urlSchema = (name) => `http://localhost:${port}/load
|
|
6
|
+
const urlSchema = (name) => `http://localhost:${port}/load/?s=/test/${name}.schema.json`
|
|
7
7
|
const urlHTML = (name) => `http://localhost:${port}/test/${name}.html`
|
|
8
|
-
const urlQuery = (schema) => `http://localhost:${port}/load
|
|
8
|
+
const urlQuery = (schema) => `http://localhost:${port}/load/?s=${JSON.stringify(schema)}`
|
|
9
9
|
|
|
10
10
|
describe('Initial test', () => {
|
|
11
11
|
beforeAll(async () => {
|
|
@@ -44,13 +44,13 @@ describe('Initial test (worker)', () => {
|
|
|
44
44
|
})
|
|
45
45
|
})
|
|
46
46
|
|
|
47
|
-
describe('
|
|
47
|
+
describe('Minimal examples', () => {
|
|
48
48
|
const schema = {
|
|
49
49
|
'model': {
|
|
50
50
|
'code': 'function (a, b) { return a / b }', // TODO: check '+'
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
test('
|
|
53
|
+
test('Code only (text) (main window)', async () => {
|
|
54
54
|
schema.model.worker = false
|
|
55
55
|
await page.goto(urlQuery(schema))
|
|
56
56
|
await expect(page).toFill('#a', '100')
|
|
@@ -58,6 +58,27 @@ describe('Some edge cases', () => {
|
|
|
58
58
|
await expect(page).toClick('button', { text: 'Run' })
|
|
59
59
|
await expect(page).toMatch('25')
|
|
60
60
|
})
|
|
61
|
+
test('Code instead of schema (function)', async () => {
|
|
62
|
+
await page.goto(urlHTML('minimal1'))
|
|
63
|
+
await expect(page).toFill('#a', '100')
|
|
64
|
+
await expect(page).toFill('#b', '4')
|
|
65
|
+
await expect(page).toClick('button', { text: 'Run' })
|
|
66
|
+
await expect(page).toMatch('400')
|
|
67
|
+
})
|
|
68
|
+
test('Code instead of model (function)', async () => {
|
|
69
|
+
await page.goto(urlHTML('minimal2'))
|
|
70
|
+
await expect(page).toFill('#a', '100')
|
|
71
|
+
await expect(page).toFill('#b', '4')
|
|
72
|
+
await expect(page).toClick('button', { text: 'Run' })
|
|
73
|
+
await expect(page).toMatch('400')
|
|
74
|
+
})
|
|
75
|
+
test('Code instead of schema (anonymous function)', async () => {
|
|
76
|
+
await page.goto(urlHTML('minimal3'))
|
|
77
|
+
await expect(page).toFill('#a', '100')
|
|
78
|
+
await expect(page).toFill('#b', '4')
|
|
79
|
+
await expect(page).toClick('button', { text: 'Run' })
|
|
80
|
+
await expect(page).toMatch('400')
|
|
81
|
+
})
|
|
61
82
|
})
|
|
62
83
|
|
|
63
84
|
describe('Load code directly', () => {
|
|
@@ -119,3 +140,21 @@ describe('Classes', () => {
|
|
|
119
140
|
await expect(page).toMatch('200')
|
|
120
141
|
})
|
|
121
142
|
})
|
|
143
|
+
|
|
144
|
+
describe('Some edge cases', () => {
|
|
145
|
+
test('Result is zero', async () => {
|
|
146
|
+
const schema = {
|
|
147
|
+
'model': {
|
|
148
|
+
'code': 'function mul (a, b) { return a * b }',
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
schema.model.worker = false
|
|
152
|
+
await page.goto(urlQuery(schema))
|
|
153
|
+
await expect(page).toFill('#a', '0')
|
|
154
|
+
await expect(page).toFill('#b', '0')
|
|
155
|
+
await expect(page).toClick('button', { text: 'Run' })
|
|
156
|
+
await expect(page).toMatch('Copy')
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
|
package/404.html
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<title>Port</title>
|
|
6
|
-
<script type="text/javascript">
|
|
7
|
-
var segmentCount = 1;
|
|
8
|
-
|
|
9
|
-
var l = window.location;
|
|
10
|
-
l.replace(
|
|
11
|
-
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
|
|
12
|
-
l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?s=' +
|
|
13
|
-
l.pathname.slice(1).split('/').slice(segmentCount).join('').replace(/&/g, '~and~') +
|
|
14
|
-
(l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') +
|
|
15
|
-
l.hash
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
</script>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
</body>
|
|
22
|
-
</html>
|