Skip to content

Commit f2e5aa6

Browse files
committed
Using Pyodide lockFileURL + packages when a cache exists
1 parent f8ffc38 commit f2e5aa6

File tree

6 files changed

+129
-87
lines changed

6 files changed

+129
-87
lines changed

docs/index.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

esm/interpreter/pyodide.js

+40-8
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ import { create } from 'gc-hook';
33
import { RUNNING_IN_WORKER, createProgress, writeFile } from './_utils.js';
44
import { getFormat, loader, loadProgress, registerJSModule, run, runAsync, runEvent } from './_python.js';
55
import { stdio } from './_io.js';
6-
import { isArray } from '../utils.js';
6+
import { IDBMapSync, isArray } from '../utils.js';
77

88
const type = 'pyodide';
99
const toJsOptions = { dict_converter: Object.fromEntries };
1010

11+
const { stringify } = JSON;
12+
13+
// REQUIRES INTEGRATION TEST
1114
/* c8 ignore start */
1215
let overrideFunction = false;
1316
const overrideMethod = method => (...args) => {
@@ -75,10 +78,7 @@ const applyOverride = () => {
7578
};
7679

7780
const progress = createProgress('py');
78-
/* c8 ignore stop */
7981

80-
// REQUIRES INTEGRATION TEST
81-
/* c8 ignore start */
8282
export default {
8383
type,
8484
module: (version = '0.26.2') =>
@@ -88,15 +88,43 @@ export default {
8888
if (!RUNNING_IN_WORKER && config.experimental_create_proxy === 'auto')
8989
applyOverride();
9090
progress('Loading Pyodide');
91-
const { stderr, stdout, get } = stdio();
91+
let { packages } = config;
92+
progress('Loading Storage');
9293
const indexURL = url.slice(0, url.lastIndexOf('/'));
94+
// each pyodide version shares its own cache
95+
const storage = new IDBMapSync(indexURL);
96+
const options = { indexURL };
97+
const save = config.packages_cache !== 'never';
98+
await storage.sync();
99+
// packages_cache = 'never' means: erase the whole DB
100+
if (!save) storage.clear();
101+
// otherwise check if cache is known
102+
else if (packages) {
103+
// packages are uniquely stored as JSON key
104+
const key = stringify(packages);
105+
if (storage.has(key)) {
106+
const blob = new Blob(
107+
[storage.get(key)],
108+
{ type: 'application/json' },
109+
);
110+
// this should be used to bootstrap loadPyodide
111+
options.lockFileURL = URL.createObjectURL(blob);
112+
// no need to use micropip manually here
113+
options.packages = packages;
114+
packages = null;
115+
}
116+
}
117+
progress('Loaded Storage');
118+
const { stderr, stdout, get } = stdio();
93119
const interpreter = await get(
94-
loadPyodide({ stderr, stdout, indexURL }),
120+
loadPyodide({ stderr, stdout, ...options }),
95121
);
96122
const py_imports = importPackages.bind(interpreter);
97123
loader.set(interpreter, py_imports);
98124
await loadProgress(this, progress, interpreter, config, baseURL);
99-
if (config.packages) await py_imports(config.packages);
125+
// if cache wasn't know, import and freeze it for the next time
126+
if (packages) await py_imports(packages, storage, save);
127+
await storage.close();
100128
progress('Loaded Pyodide');
101129
return interpreter;
102130
},
@@ -130,7 +158,7 @@ function transform(value) {
130158
}
131159

132160
// exposed utility to import packages via polyscript.lazy_py_modules
133-
async function importPackages(packages) {
161+
async function importPackages(packages, storage, save = false) {
134162
// temporary patch/fix console.log which is used
135163
// not only by Pyodide but by micropip too and there's
136164
// no way to intercept those calls otherwise
@@ -146,6 +174,10 @@ async function importPackages(packages) {
146174
const micropip = this.pyimport('micropip');
147175
await micropip.install(packages, { keep_going: true });
148176
console.log = log;
177+
if (save && (storage instanceof IDBMapSync)) {
178+
const frozen = micropip.freeze();
179+
storage.set(stringify(packages), frozen);
180+
}
149181
micropip.destroy();
150182
}
151183
/* c8 ignore stop */

package-lock.json

+72-72
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)