Skip to content

Commit d3aebc3

Browse files
committed
shorter/better
1 parent 4fe9299 commit d3aebc3

File tree

11 files changed

+82
-60
lines changed

11 files changed

+82
-60
lines changed

docs/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/zip-CAMAhqMX.js

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/zip-CAMAhqMX.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

esm/interpreter/pyodide-patch.js

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,52 @@
11
export default () => {
2-
const { prototype } = Function;
32
const { apply, construct, defineProperty } = Reflect;
43

54
const notRegistered = value => value?.shared?.gcRegistered === false;
65

7-
const patch = args => {
8-
if (known) {
9-
for (let i = 0; i < args.length; i++)
10-
args[i] = toJS(args[i]);
11-
}
12-
};
13-
14-
const toJS = current => {
15-
if (known) {
16-
switch (typeof current) {
17-
case 'object':
18-
if (current === null) break;
19-
// falls through
20-
case 'function':
21-
if (notRegistered(current[pyproxy])) {
22-
return current.toJs(options);
23-
}
24-
}
25-
}
26-
return current;
27-
};
28-
29-
const options = { dict_converter: Object.fromEntries };
30-
316
const descriptor = {
327
configurable: true,
338
set(value) {
34-
delete this[pyproxy];
35-
this[pyproxy] = value;
9+
defineProperty(this, pyproxy, { value });
3610
if (notRegistered(value)) {
3711
const copy = this.copy();
3812
queueMicrotask(() => {
39-
this[pyproxy] = copy[pyproxy];
13+
defineProperty(this, pyproxy, { value: copy[pyproxy] });
4014
});
4115
}
4216
},
4317
};
4418

45-
let pyproxy, known = false;
19+
const intercept = (handler, name) => {
20+
const method = handler[name];
21+
defineProperty(handler, name, {
22+
value(target, key) {
23+
if (known) {
24+
if (key === pyproxy) {
25+
if (
26+
typeof target === 'function' &&
27+
notRegistered(target[pyproxy])
28+
) return target.toJs()[key];
29+
}
30+
else if (
31+
pyproxy in target &&
32+
name in target &&
33+
!(key in target) &&
34+
notRegistered(target[pyproxy]) &&
35+
typeof target === 'object'
36+
) return target[name](key);
37+
}
38+
return apply(method, this, arguments);
39+
}
40+
});
41+
};
4642

47-
defineProperty(prototype, 'apply', {
48-
value(context, args) {
49-
patch(args);
50-
return apply(this, toJS(context), args);
51-
}
52-
});
43+
const pyodidePatch = Symbol.for('pyodide-patch');
44+
const patched = new WeakSet;
5345

54-
defineProperty(prototype, 'call', {
55-
value(context, ...args) {
56-
patch(args);
57-
return apply(this, toJS(context), args);
58-
}
59-
});
46+
let pyproxy, known = false;
47+
48+
if (pyodidePatch in globalThis) return;
49+
globalThis[pyodidePatch] = true;
6050

6151
// minimalistic Symbol override that
6252
// won't affect performance or break expectations
@@ -78,11 +68,18 @@ export default () => {
7868
defineProperty(globalThis, 'Proxy', {
7969
value: new Proxy(Proxy, {
8070
construct(target, args, New) {
81-
const proxy = construct(target, args, New);
82-
if (known && typeof args[0] === 'function') {
83-
defineProperty(args[0], pyproxy, descriptor);
71+
if (known) {
72+
if (typeof args[0] === 'function')
73+
defineProperty(args[0], pyproxy, descriptor);
74+
const handler = args[1];
75+
if (handler?.get && !patched.has(handler)) {
76+
patched.add(handler);
77+
intercept(handler, 'get');
78+
// this is actually not used out there
79+
// override(handler, 'has');
80+
}
8481
}
85-
return proxy;
82+
return construct(target, args, New);
8683
},
8784
})
8885
});

esm/interpreter/pyodide.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createProgress, writeFile } from './_utils.js';
22
import { getFormat, loader, loadProgress, registerJSModule, run, runAsync, runEvent } from './_python.js';
33
import { stdio } from './_io.js';
44
import { IDBMapSync, isArray, fixedRelative } from '../utils.js';
5+
import patch from './pyodide-patch.js';
56

67
const type = 'pyodide';
78
const toJsOptions = { dict_converter: Object.fromEntries };
@@ -25,6 +26,7 @@ export default {
2526
async engine({ loadPyodide }, config, url, baseURL) {
2627
if (config.experimental_create_proxy === 'auto') {
2728
this.transform = (_, value) => value;
29+
patch();
2830
}
2931
progress('Loading Pyodide');
3032
let { packages, index_urls } = config;

esm/interpreters.js

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// The :RUNTIMES comment is a delimiter and no code should be written/changed after
33
// See rollup/build_interpreters.cjs to know more
44

5-
import patch from './interpreter/pyodide-patch.js';
6-
75
/** @type {Map<string, object>} */
86
export const registry = new Map();
97

@@ -27,20 +25,16 @@ export const interpreter = new Proxy(new Map(), {
2725
: interpreter.module(...rest);
2826
map.set(id, {
2927
url,
30-
module: () => import(/* webpackIgnore: true */url),
28+
module: import(/* webpackIgnore: true */url),
3129
engine: interpreter.engine.bind(interpreter),
3230
});
3331
}
3432
const { url, module, engine } = map.get(id);
35-
return async (config, baseURL) => {
36-
if (config.experimental_create_proxy === 'auto') {
37-
patch();
38-
}
39-
return module().then((module) => {
33+
return (config, baseURL) =>
34+
module.then((module) => {
4035
configs.set(id, config);
4136
return engine(module, config, url, baseURL);
4237
});
43-
};
4438
},
4539
});
4640
/* c8 ignore stop */

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"types": "./types/polyscript/esm/index.d.ts",
77
"scripts": {
88
"server": "npx static-handler --coi .",
9-
"build": "export ESLINT_USE_FLAT_CONFIG=false; npm run build:3rd-party && rm -rf dist && mkdir -p esm/python && node rollup/build_python.cjs && npm run rollup:xworker && npm run rollup:core && eslint esm/ && npm run rollup:integrations && npm run build:docs",
9+
"build": "export ESLINT_USE_FLAT_CONFIG=false; npm run build:3rd-party && rm -rf dist && mkdir -p esm/python && node rollup/build_python.cjs && npm run rollup:xworker && npm run rollup:core && npm run rollup:integrations && npm run build:docs",
1010
"build:3rd-party": "node rollup/3rd-party.cjs",
1111
"build:docs": "mv docs/coi.js ./; rm -f docs/*.{js,map}; cp dist/* docs/; rm -f docs/_template.js; mv coi.js docs/",
1212
"dev": "node dev.cjs",
@@ -96,6 +96,6 @@
9696
"to-json-callback": "^0.1.1"
9797
},
9898
"worker": {
99-
"blob": "sha256-+sGDLtv2hVsnU+g72b4LNukOBKJ6rACYVNp4kkAAKfQ="
99+
"blob": "sha256-F8Q1wRHhjlnJ/rfCwDH9kFnuwL3LgM3tYagFb9HtozQ="
100100
}
101101
}

test/create_proxy/config.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"experimental_create_proxy": "auto",
3+
"js_modules": {
4+
"main": {
5+
"https://unpkg.com/d3?module" : "d3",
6+
"https://unpkg.com/dc?module" : "dc",
7+
"https://unpkg.com/crossfilter2?module" : "crossfilter"
8+
}
9+
}
10+
}

test/create_proxy/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
</script>
3232
</head>
3333
<body>
34-
<script type="py" src="./main.py" config="./pyscript.toml"></script>
34+
<script type="py" src="./main.py" config="./config.json"></script>
3535
<div id="test"></div>
3636
<!-- here's a way to load data from a jsfiddle, to avoid CORS
3737
problems - see http://stackoverflow.com/a/22896088/676195

test/create_proxy/main.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import js as window
1+
try:
2+
from polyscript import xworker
3+
window = xworker.window
4+
except:
5+
import js as window
6+
27
from polyscript.js_modules import d3, dc
38
from polyscript.js_modules.crossfilter import default as crossfilter
49

0 commit comments

Comments
 (0)