@jseeio/jsee 0.2.4 → 0.2.8
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 +7 -39
- 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 +61 -26
- package/package.json +13 -3
- package/src/app.js +14 -1
- package/templates/bulma-app.vue +76 -7
- 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/webpack.config.js +3 -1
- package/404.html +0 -22
- package/dist/worker_bundle.js +0 -1
|
@@ -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) {
|
|
@@ -89,7 +97,8 @@ function getParamNames (func) {
|
|
|
89
97
|
|
|
90
98
|
function getInputs (model) {
|
|
91
99
|
if (model.code) {
|
|
92
|
-
const params = getParamNames(model.code)
|
|
100
|
+
const params = getParamNames(model.code).filter(p => !['(', ')', '#', '{', '}'].some(c => p.includes(c)))
|
|
101
|
+
log('Trying to infer inputs from params:', params)
|
|
93
102
|
return params.map(p => ({
|
|
94
103
|
'name': p,
|
|
95
104
|
'type': 'string'
|
|
@@ -103,28 +112,48 @@ function getFunctionContainer (target) {
|
|
|
103
112
|
}
|
|
104
113
|
|
|
105
114
|
export default class JSEE {
|
|
106
|
-
constructor (params,
|
|
107
|
-
|
|
108
|
-
if
|
|
115
|
+
constructor (params, alt1, alt2) {
|
|
116
|
+
|
|
117
|
+
// Check if JSEE was initialized with args rather than with a params object
|
|
118
|
+
if (('model' in params) || (typeof params === 'string') || (typeof params === 'function') || !(typeof alt === 'undefined')) {
|
|
109
119
|
params = {
|
|
110
120
|
'schema': params,
|
|
111
|
-
'container':
|
|
121
|
+
'container': alt1,
|
|
122
|
+
'verbose': alt2
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
125
|
|
|
126
|
+
// Set global verbose flag
|
|
115
127
|
verbose = !(params.verbose === false)
|
|
116
128
|
|
|
117
|
-
|
|
129
|
+
// Previous naming
|
|
118
130
|
params.schema = params.schema || params.config
|
|
131
|
+
|
|
132
|
+
log('Initializing JSEE with parameters: ', params)
|
|
119
133
|
this.params = params
|
|
120
134
|
this.__version__ = VERSION
|
|
121
135
|
|
|
122
136
|
// Get schema then initialize a new environment
|
|
123
|
-
|
|
124
|
-
|
|
137
|
+
switch (typeof params.schema) {
|
|
138
|
+
case 'object':
|
|
125
139
|
log('Received schema as object')
|
|
140
|
+
if (typeof params.schema.model === 'function') {
|
|
141
|
+
params.schema.model = {
|
|
142
|
+
code: params.schema.model
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
this.init(params.schema)
|
|
146
|
+
break
|
|
147
|
+
case 'function':
|
|
148
|
+
log('Received schema as function')
|
|
149
|
+
params.schema = {
|
|
150
|
+
model: {
|
|
151
|
+
code: params.schema,
|
|
152
|
+
}
|
|
153
|
+
}
|
|
126
154
|
this.init(params.schema)
|
|
127
|
-
|
|
155
|
+
break
|
|
156
|
+
case 'string':
|
|
128
157
|
log('Received schema as string')
|
|
129
158
|
this.schemaUrl = params.schema.indexOf('json') ? params.schema : params.schema + '.json'
|
|
130
159
|
fetch(this.schemaUrl)
|
|
@@ -136,7 +165,10 @@ export default class JSEE {
|
|
|
136
165
|
.catch((err) => {
|
|
137
166
|
console.error(err)
|
|
138
167
|
})
|
|
139
|
-
|
|
168
|
+
break
|
|
169
|
+
default:
|
|
170
|
+
log('No schema provided')
|
|
171
|
+
notyf.error('No schema provided')
|
|
140
172
|
}
|
|
141
173
|
}
|
|
142
174
|
|
|
@@ -170,12 +202,6 @@ export default class JSEE {
|
|
|
170
202
|
log('Loaded code from:', url)
|
|
171
203
|
resolve(res)
|
|
172
204
|
})
|
|
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
205
|
} else if (!(typeof schema.model.code === 'undefined')) {
|
|
180
206
|
log('Code is: schema.model.code')
|
|
181
207
|
resolve(schema.model.code)
|
|
@@ -222,13 +248,17 @@ export default class JSEE {
|
|
|
222
248
|
|
|
223
249
|
// Infer model type
|
|
224
250
|
if (typeof schema.model.type === 'undefined') {
|
|
225
|
-
schema.model.type =
|
|
251
|
+
schema.model.type = getModelType(schema.model)
|
|
226
252
|
}
|
|
227
253
|
|
|
228
254
|
// Update model name if absent
|
|
229
|
-
if (
|
|
230
|
-
schema.model.
|
|
231
|
-
|
|
255
|
+
if (typeof schema.model.name === 'undefined'){
|
|
256
|
+
if ((schema.model.url) && (schema.model.url.includes('.js'))) {
|
|
257
|
+
schema.model.name = schema.model.url.split('/').pop().split('.')[0]
|
|
258
|
+
log('Use model name from url: ', schema.model.name)
|
|
259
|
+
} else if (schema.model.code) {
|
|
260
|
+
schema.model.name = getName(schema.model.code)
|
|
261
|
+
}
|
|
232
262
|
}
|
|
233
263
|
|
|
234
264
|
// At this point we have all code in model.code or api
|
|
@@ -372,11 +402,16 @@ export default class JSEE {
|
|
|
372
402
|
|
|
373
403
|
if (this.schema.model.worker) {
|
|
374
404
|
// Worker: Initialize worker with the model
|
|
375
|
-
|
|
376
|
-
|
|
405
|
+
// 2 -> 1
|
|
406
|
+
if (typeof this.schema.model.code === 'function') {
|
|
377
407
|
log('Convert code in schema to string for WebWorker')
|
|
378
408
|
this.schema.model.code = this.schema.model.code.toString()
|
|
379
409
|
}
|
|
410
|
+
// Wrap anonymous functions
|
|
411
|
+
if (!this.schema.model.name) {
|
|
412
|
+
this.schema.model.code = `function anon () { return (${this.schema.model.code})(...arguments) }`
|
|
413
|
+
this.schema.model.name = 'anon'
|
|
414
|
+
}
|
|
380
415
|
this.worker.postMessage(this.schema.model)
|
|
381
416
|
} else {
|
|
382
417
|
// Main: Initialize model in main window
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jseeio/jsee",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/jsee.js",
|
|
6
|
+
"unpkg": "dist/jsee.js",
|
|
7
|
+
"jsdelivr": "dist/jsee.js",
|
|
6
8
|
"private": false,
|
|
7
9
|
"scripts": {
|
|
8
|
-
"build-dev": "webpack --mode=development --progress --stats-children",
|
|
9
|
-
"build": "webpack --mode=production --progress &&
|
|
10
|
+
"build-dev": "webpack --mode=development --progress --stats-children --env DEVELOPMENT",
|
|
11
|
+
"build": "webpack --mode=production --progress && webpack --mode=production --progress --env RUNTIME",
|
|
10
12
|
"watch": "nodemon --watch . --ignore dist --ext vue,js,css,html --exec 'npm run build-dev && npm test'",
|
|
11
13
|
"prepublishOnly": "npm run build && npm test",
|
|
12
14
|
"test": "jest test.js --detectOpenHandles",
|
|
@@ -14,6 +16,14 @@
|
|
|
14
16
|
},
|
|
15
17
|
"author": "Anton Zemlyansky",
|
|
16
18
|
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/jseeio/jsee"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://jsee.org",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/jseeio/jsee/issues"
|
|
26
|
+
},
|
|
17
27
|
"dependencies": {
|
|
18
28
|
"@mdi/font": "^6.5.95",
|
|
19
29
|
"bulma": "^0.9.3",
|
package/src/app.js
CHANGED
|
@@ -75,6 +75,11 @@ function createVueApp (env, mountedCallback, logMain) {
|
|
|
75
75
|
dataInit.outputs = []
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
// Flag that shows if data was changed from initial conditions
|
|
79
|
+
dataInit.dataChanged = false
|
|
80
|
+
// Flag for autorun feedback
|
|
81
|
+
dataInit.clickRun = false
|
|
82
|
+
|
|
78
83
|
function len(s) {
|
|
79
84
|
return s.length;
|
|
80
85
|
}
|
|
@@ -144,8 +149,9 @@ function createVueApp (env, mountedCallback, logMain) {
|
|
|
144
149
|
deep: true,
|
|
145
150
|
immediate: false,
|
|
146
151
|
handler (v) {
|
|
152
|
+
this.dataChanged = true // Used in the reset button
|
|
147
153
|
if (this.model.autorun) {
|
|
148
|
-
|
|
154
|
+
this.run()
|
|
149
155
|
}
|
|
150
156
|
}
|
|
151
157
|
}
|
|
@@ -160,9 +166,16 @@ function createVueApp (env, mountedCallback, logMain) {
|
|
|
160
166
|
},
|
|
161
167
|
reset () {
|
|
162
168
|
resetInputs(this.inputs)
|
|
169
|
+
this.$nextTick(() => {
|
|
170
|
+
this.dataChanged = false
|
|
171
|
+
})
|
|
163
172
|
},
|
|
164
173
|
run () {
|
|
174
|
+
this.clickRun = true
|
|
165
175
|
env.run()
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
this.clickRun = false
|
|
178
|
+
}, 150)
|
|
166
179
|
},
|
|
167
180
|
notify (msg) {
|
|
168
181
|
env.notify(msg)
|
package/templates/bulma-app.vue
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
justify-content: center;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
|
|
29
30
|
.card-header {
|
|
30
31
|
box-shadow: none;
|
|
31
32
|
border-bottom: 1px solid #ececec;
|
|
@@ -50,6 +51,73 @@
|
|
|
50
51
|
background-color: whitesmoke;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
|
|
55
|
+
.card-footer {
|
|
56
|
+
/* background: linear-gradient(62deg, rgba(0,171,209,1) 0%, rgba(0,209,178,1) 100%); */
|
|
57
|
+
background: linear-gradient(90deg, #4395d0 0%, #00d1b2 100%);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.card-footer.reset {
|
|
61
|
+
background: linear-gradient(90deg, #ff577f 0%, #4395d0 50%, #00d1b2 100%);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.card-footer .button {
|
|
65
|
+
background: none;
|
|
66
|
+
padding: .75rem 1.5rem;
|
|
67
|
+
border: none !important;
|
|
68
|
+
border-radius: .25rem !important;
|
|
69
|
+
font-size: 14px;
|
|
70
|
+
font-weight: 400;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.reset-button {
|
|
74
|
+
justify-content: left;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.reset-button:hover {
|
|
78
|
+
background-color: transparent !important;
|
|
79
|
+
background: linear-gradient(90deg, #ff3a56 0%, #fff0 80%);
|
|
80
|
+
box-shadow: -5px 0px 5px -2px #fd4c7e30;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.card-footer .run-button {
|
|
84
|
+
border-left: 1px dashed white;
|
|
85
|
+
justify-content: right;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.card-footer .run-button:hover,{
|
|
89
|
+
background-color: transparent !important;
|
|
90
|
+
background: linear-gradient(270deg, #02dbb2 0%, #fff0 80%);
|
|
91
|
+
box-shadow: 5px 0px 5px -2px #48ffd43b;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.card-footer .run-button.running .run-icon {
|
|
95
|
+
color: #016c5c !important;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.field {
|
|
99
|
+
margin-bottom: 5px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.input, .textarea, .select select {
|
|
103
|
+
border-color: #e8e8e8;
|
|
104
|
+
border-top-left-radius: 0;
|
|
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
|
+
|
|
53
121
|
}
|
|
54
122
|
</style>
|
|
55
123
|
<template>
|
|
@@ -73,21 +141,22 @@
|
|
|
73
141
|
<pre v-if="$parent.model.debug">{{ $parent.inputs }}</pre>
|
|
74
142
|
<!-- <button class="button is-primary" id="run"><span>▸</span> Run</button> -->
|
|
75
143
|
</div>
|
|
76
|
-
<footer class="card-footer">
|
|
144
|
+
<footer class="card-footer" v-bind:class="{ reset: $parent.dataChanged }">
|
|
77
145
|
<button
|
|
78
146
|
v-on:click="$parent.reset()"
|
|
79
|
-
v-if="$parent.inputs && $parent.inputs.length > 0"
|
|
80
|
-
class="button icon card-footer-item is-danger is-small"
|
|
147
|
+
v-if="$parent.inputs && $parent.inputs.length > 0 && $parent.dataChanged"
|
|
148
|
+
class="button reset-button icon card-footer-item is-danger is-small"
|
|
81
149
|
>
|
|
82
|
-
<span class="has-text-danger-dark">✕</span>
|
|
150
|
+
<span class="rest-icon has-text-danger-dark">✕</span>
|
|
83
151
|
<span> Reset</span>
|
|
84
152
|
</button>
|
|
85
153
|
<button
|
|
86
154
|
v-on:click="$parent.run()"
|
|
87
|
-
class="button icon card-footer-item is-primary is-small"
|
|
155
|
+
class="button run-button icon card-footer-item is-primary is-small"
|
|
156
|
+
v-bind:class="{ running: $parent.clickRun }"
|
|
88
157
|
>
|
|
89
|
-
<span
|
|
90
|
-
<span
|
|
158
|
+
<span> Run </span>
|
|
159
|
+
<span class="run-icon has-text-primary-dark">▸</span>
|
|
91
160
|
</button>
|
|
92
161
|
</footer>
|
|
93
162
|
</div>
|
|
@@ -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/webpack.config.js
CHANGED
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>
|
package/dist/worker_bundle.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(()=>{var __webpack_modules__={555:()=>{eval("function getModelFuncJS(schema, target, log=console.log) {\n switch (schema.model.type) {\n case 'class':\n log('Init class')\n const modelClass = new target()\n return (...a) => {\n return modelClass[this.schema.model.method || 'predict'](...a)\n }\n case 'async-init':\n log('Function with async init')\n return target().then((m) => {\n log('Async init resolved: ', m)\n this.modelFunc = m\n })\n default:\n log('Init function')\n return target\n }\n}\n\n\n//# sourceURL=webpack://@jseeio/jsee/./src/utils.js?")},736:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval("/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(555);\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_utils_js__WEBPACK_IMPORTED_MODULE_0__);\n\n\nconsole.log('!!!', _utils_js__WEBPACK_IMPORTED_MODULE_0__.getModelFuncJS)\n\nfunction log () {\n const args = Array.prototype.slice.call(arguments);\n args.unshift('[Worker]')\n console.log(args)\n postMessage({_status: 'log', _log: args})\n}\n\nfunction initTF (model) {\n throw new Error('Tensorflow in worker (not implemented)')\n}\n\nfunction initPython (model) {\n throw new Error('Python in worker (not implemented)')\n}\n\nfunction initJS (model) {\n this.container = model.container\n\n if (model.code) {\n log('Load code as a string')\n // https://github.com/altbdoor/blob-worker/blob/master/blobWorker.js\n importScripts(URL.createObjectURL(new Blob([model.code], { type: 'text/javascript' })))\n } else if (model.url) {\n log('Load script from URL:', model.url)\n importScripts(model.url)\n } else {\n log('No script provided')\n }\n\n this.modelFunc = (0,_utils_js__WEBPACK_IMPORTED_MODULE_0__.getModelFuncJS)(model, this[model.name], log)\n console.log('>>>', this.modelFunc)\n postMessage({_status: 'loaded'})\n}\n\nonmessage = function (e) {\n\n var data = e.data\n log('Received message of type:', typeof data)\n\n if ((typeof data === 'object') && ((data.url) || (data.code))) {\n /*\n INIT MESSAGE\n */\n let model = data\n log('Init...')\n\n switch (model.type) {\n case 'tf':\n initTF(model)\n break\n case 'py':\n initPython(model)\n break\n case 'function':\n case 'class':\n case 'async-init':\n case 'async-function':\n initJS.call(this, model)\n break\n }\n } else {\n /*\n :w\n CALL MESSAGE\n */\n var res\n if (typeof this.modelFunc === 'string') {\n // Python model:\n log('Calling Python model')\n /*\n const keys = Object.keys(data)\n for (let key of keys) {\n self[key] = data[key];\n }\n self.pyodide.runPythonAsync(this.model, () => {})\n .then((res) => {\n console.log('[Worker] Py results: ', typeof res, res)\n\t postMessage(res)\n })\n .catch((err) => {\n // self.postMessage({error : err.message});\n })\n */\n } else {\n // JavaScript model\n log('Calling JavaScript model')\n if (this.container === 'args') {\n log('Applying inputs as arguments')\n res = this.modelFunc.apply(null, data)\n } else {\n // JS object or array\n log('Applying inputs as object/array')\n res = this.modelFunc(data, log)\n }\n // Return promise value or just regular value\n // Promise.resolve handles both cases\n Promise.resolve(res).then(r => { postMessage(r) })\n }\n }\n}\n\n\n//# sourceURL=webpack://@jseeio/jsee/./src/worker.js?")}},__webpack_module_cache__={};function __webpack_require__(e){var n=__webpack_module_cache__[e];if(void 0!==n)return n.exports;var o=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e](o,o.exports,__webpack_require__),o.exports}__webpack_require__.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(n,{a:n}),n},__webpack_require__.d=(e,n)=>{for(var o in n)__webpack_require__.o(n,o)&&!__webpack_require__.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:n[o]})},__webpack_require__.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var __webpack_exports__=__webpack_require__(736)})();
|