8000 Provide Visible Error if <py-env> paths is used in a local HTML file … · sarvjeetdev/pyscript@b767a78 · GitHub
[go: up one dir, main page]

Skip to content

Commit b767a78

Browse files
JeffersGlasspre-commit-ci[bot]fpliger
authored
Provide Visible Error if <py-env> paths is used in a local HTML file (pyscript#311)
* Add onscreen error when using py-env paths in local HTTP files without file server * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Remove redundant code, fix error handling, add 404 error * Lint and Format * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * manage errors loading files * use handleFetchError for handling fetch errors in env Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
1 parent 39774a8 commit b767a78

File tree

8 files changed

+181
-118
lines changed

8 files changed

+181
-118
lines changed

pyscriptjs/src/App.svelte

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
1-
<script lang="ts">
2-
import Tailwind from './Tailwind.svelte';
3-
</script>
4-
51
<style global>
62
.spinner::after {
7-
content: '';
8-
box-sizing: border-box;
9-
width: 40px;
10-
height: 40px;
11-
position: absolute;
12-
top: calc(40% - 20px);
13-
left: calc(50% - 20px);
14-
border-radius: 50%;
3+
content: '';
4+
box-sizing: border-box;
5+
width: 40px;
6+
height: 40px;
7+
position: absolute;
8+
top: calc(40% - 20px);
9+
left: calc(50% - 20px);
10+
border-radius: 50%;
1511
}
1612
1713
.spinner.smooth::after {
18-
border-top: 4px solid rgba(255, 255, 255, 1.0);
19-
border-left: 4px solid rgba(255, 255, 255, 1.0);
20-
border-right: 4px solid rgba(255, 255, 255, 0.0);
21-
animation: spinner .6s linear infinite;
14+
border-top: 4px solid rgba(255, 255, 255, 1);
15+
border-left: 4px solid rgba(255, 255, 255, 1);
16+
border-right: 4px solid rgba(255, 255, 255, 0);
17+
animation: spinner 0.6s linear infinite;
2218
}< B41A /div>
2319
@keyframes spinner {
24-
to {transform: rotate(360deg);}
20+
to {
21+
transform: rotate(360deg);
22+
}
2523
}
2624
2725
.label {
28-
text-align: center;
29-
width: 100%;
30-
display: block;
31-
color: rgba(255, 255, 255, 0.8);
32-
font-size: 0.8rem;
33-
margin-top: 6rem;
26+
text-align: center;
27+
width: 100%;
28+
display: block;
29+
color: rgba(255, 255, 255, 0.8);
30+
font-size: 0.8rem;
31+
margin-top: 6rem;
3432
}
35-
</style>
33+
</style>
34+
35+
<script lang="ts">
36+
import Tailwind from './Tailwind.svelte';
37+
</script>
3638

3739
<Tailwind />

pyscriptjs/src/components/pyconfig.ts

Lines changed: 79 additions & 74 deletions
< E377 /tr>
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
import * as jsyaml from 'js-yaml';
22
import { BaseEvalElement } from './base';
3-
import { initializers, loadedEnvironments, mode, postInitializers, pyodideLoaded, scriptsQueue, globalLoader, appConfig, Initializer } from '../stores';
3+
import {
4+
initializers,
5+
loadedEnvironments,
6+
mode,
7+
postInitializers,
8+
pyodideLoaded,
9+
scriptsQueue,
10+
globalLoader,
11+
appConfig,
12+
Initializer,
13+
} from '../stores';
414
import { loadInterpreter } from '../interpreter';
515
import type { PyScript } from './pyscript';
616

7-
817
const DEFAULT_RUNTIME = {
9-
src: "https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js",
10-
name: "pyodide-default",
11-
lang: "python"
12-
}
18+
src: 'https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js',
19+
name: 'pyodide-default',
20+
lang: 'python',
21+
};
1322

1423
export type Runtime = {
1524
src: string;
@@ -28,107 +37,103 @@ let appConfig_: AppConfig = {
2837
autoclose_loader: true,
2938
};
3039

31-
appConfig.subscribe( (value:AppConfig) => {
32-
if (value){
40+
appConfig.subscribe((value: AppConfig) => {
41+
if (value) {
3342
appConfig_ = value;
3443
}
35-
console.log("config set!")
44+
console.log('config set!');
3645
});
3746

3847
let initializers_: Initializer[];
39-
initializers.subscribe( (value:Initializer[]) => {
48+
initializers.subscribe((value: Initializer[]) => {
4049
initializers_ = value;
41-
console.log("initializers set")
50+
console.log('initializers set');
4251
});
4352

4453
let postInitializers_: Initializer[];
45-
postInitializers.subscribe( (value:Initializer[]) => {
54+
postInitializers.subscribe((value: Initializer[]) => {
4655
postInitializers_ = value;
47-
console.log("post initializers set")
56+
console.log('post initializers set');
4857
});
4958

5059
let scriptsQueue_: PyScript[];
51-
scriptsQueue.subscribe( (value: PyScript[]) => {
60+
scriptsQueue.subscribe((value: PyScript[]) => {
5261
scriptsQueue_ = value;
53-
console.log("post initializers set")
62+
console.log('post initializers set');
5463
});
5564

5665
let mode_: string;
57-
mode.subscribe( (value:string) => {
66+
mode.subscribe((value: string) => {
5867
mode_ = value;
59-
console.log("post initializers set")
68+
console.log('post initializers set');
6069
});
6170

62-
6371
let pyodideReadyPromise;
6472
let loader;
6573

66-
6774
globalLoader.subscribe(value => {
6875
loader = value;
6976
});
7077

71-
72-
export class PyodideRuntime extends Object{
78+
export class PyodideRuntime extends Object {
7379
src: string;
7480

75-
constructor(url:string) {
81+
constructor(url: string) {
7682
super();
7783
this.src = url;
7884
}
7985

80-
async initialize(){
81-
loader.log("Loading runtime...")
82-
pyodideReadyPromise = loadInterpreter(this.src);
83-
const pyodide = await pyodideReadyPromise;
84-
const newEnv = {
85-
id: 'a',
86-
promise: pyodideReadyPromise,
87-
runtime: pyodide,
88-
state: 'loading',
89-
};
90-
pyodideLoaded.set(pyodide);
91-
92-
// Inject the loader into the runtime namespace
93-
pyodide.globals.set("pyscript_loader", loader);
94-
95-
loader.log("Runtime created...")
96-
loadedEnvironments.update((value: any): any => {
97-
value[newEnv['id']] = newEnv;
98-
});
99-
100-
// now we call all initializers before we actually executed all page scripts
101-
loader.log("Initializing components...")
102-
for (const initializer of initializers_) {
103-
await initializer();
104-
}
105-
106-
// now we can actually execute the page scripts if we are in play mode
107-
loader.log("Initializing scripts...")
108-
if (mode_ == 'play') {
109-
for (const script of scriptsQueue_) {
110-
script.evaluate();
86+
async initialize() {
87+
loader.log('Loading runtime...');
88+
pyodideReadyPromise = loadInterpreter(this.src);
89+
const pyodide = await pyodideReadyPromise;
90+
const newEnv = {
91+
id: 'a',
92+
promise: pyodideReadyPromise,
93+
runtime: pyodide,
94+
state: 'loading',
95+
};
96+
pyodideLoaded.set(pyodide);
97+
98+
// Inject the loader into the runtime namespace
99+
pyodide.globals.set('pyscript_loader', loader);
100+
101+
loader.log('Runtime created...');
102+
loadedEnvironments.update((value: any): any => {
103+
value[newEnv['id']] = newEnv;
104+
});
105+
106+
// now we call all initializers before we actually executed all page scripts
107+
loader.log('Initializing components...');
108+
for (const initializer of initializers_) {
109+
await initializer();
111110
}
112-
scriptsQueue.set([]);
113-
}
114111

115-
// now we call all post initializers AFTER we actually executed all page scripts
116-
loader.log("Running post initializers...");
112+
// now we can actually execute the page scripts if we are in play mode
113+
loader.log('Initializing scripts...');
114+
if (mode_ == 'play') {
115+
for (const script of scriptsQueue_) {
116+
script.evaluate();
117+
}
118+
scriptsQueue.set([]);
119+
}
117120

118-
if (appConfig_ && appConfig_.autoclose_loader) {
119-
loader.close();
120-
console.log("------ loader closed ------");
121-
}
121+
// now we call all post initializers AFTER we actually executed all page scripts
122+
loader.log('Running post initializers...');
122123

123-
setTimeout(() => {
124-
for (const initializer of postInitializers_) {
125-
initializer();
124+
if (appConfig_ && appConfig_.autoclose_loader) {
125+
loader.close();
126+
console.log('------ loader closed ------');
126127
}
127-
}, 3000);
128+
129+
setTimeout(() => {
130+
for (const initializer of postInitializers_) {
131+
initializer();
132+
}
133+
}, 3000);
128134
}
129135
}
130136

131-
132137
export class PyConfig extends BaseEvalElement {
133138
shadow: ShadowRoot;
134139
wrapper: HTMLElement;
@@ -149,23 +154,23 @@ export class PyConfig extends BaseEvalElement {
149154
this.innerHTML = '';
150155

151156
const loadedValues = jsyaml.load(this.code);
152-
if (loadedValues === undefined){
157+
if (loadedValues === undefined) {
153158
this.values = {
154159
autoclose_loader: true,
155160
};
156-
}else{
161+
} else {
157162
this.values = Object.assign({}, ...loadedValues);
158163
}
159-
if (this.values.runtimes === undefined){
164+
if (this.values.runtimes === undefined) {
160165
this.values.runtimes = [DEFAULT_RUNTIME];
161166
}
162167
appConfig.set(this.values);
163-
console.log("config set", this.values);
168+
console.log('config set', this.values);
164169

165170
this.loadRuntimes();
166171
}
167172

168-
log(msg: string){
173+
log(msg: string) {
169174
const newLog = document.createElement('p');
170175
newLog.innerText = msg;
171176
this.details.appendChild(newLog);
@@ -175,10 +180,10 @@ export class PyConfig extends BaseEvalElement {
175180
this.remove();
176181
}
177182

178-
loadRuntimes(){
179-
console.log("Initializing runtimes...")
183+
loadRuntimes() {
184+
console.log('Initializing runtimes...');
180185
for (const runtime of this.values.runtimes) {
181-
const script = document.createElement("script"); // create a script DOM node
186+
const script = document.createElement('script'); // create a script DOM node
182187
const runtimeSpec = new PyodideRuntime(runtime.src);
183188
script.src = runtime.src; // set its src to the provided URL
184189
script.addEventListener('load', () => {

pyscriptjs/src/components/pyenv.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as jsyaml from 'js-yaml';
22

33
import { pyodideLoaded, addInitializer } from '../stores';
44
import { loadPackage, loadFromFile } from '../interpreter';
5+
import { handleFetchError } from '../utils';
56

67
// Premise used to connect to the first available pyodide interpreter
78
let pyodideReadyPromise;
@@ -62,7 +63,12 @@ export class PyEnv extends HTMLElement {
6263
async function loadPaths() {
6364
for (const singleFile of paths) {
6465
console.log(`loading ${singleFile}`);
65-
await loadFromFile(singleFile, runtime);
66+
try {
67+< 10166 div class="diff-text-inner"> await loadFromFile(singleFile, runtime);
68+
} catch (e) {
69+
//Should we still export full error contents to console?
70+
handleFetchError(e, singleFile);
71+
}
6672
}
6773
console.log('paths loaded');
6874
}

pyscriptjs/src/components/pyloader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class PyLoader extends BaseEvalElement {
2626
this.details = document.getElementById('pyscript-operation-details');
2727
}
2828

29-
log(msg: string){
29+
log(msg: string) {
3030
const newLog = document.createElement('p');
3131
newLog.innerText = msg;
3232
this.details.appendChild(newLog);

pyscriptjs/src/components/pyrepl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function getEditorTheme(el: BaseEvalElement): string {
4747
return initialTheme;
4848
}
4949

50-
return initialTheme = el.getAttribute('theme');
50+
return (initialTheme = el.getAttribute('theme'));
5151
}
5252

5353
export class PyRepl extends BaseEvalElement {

0 commit comments

Comments
 (0)
0