diff --git a/docs/beginning-pyscript.md b/docs/beginning-pyscript.md
index cb292e7..64e1617 100644
--- a/docs/beginning-pyscript.md
+++ b/docs/beginning-pyscript.md
@@ -112,8 +112,8 @@ module in the document's `
` tag:
🦜 Polyglot - Piratical PyScript
-
-
+
+
@@ -163,8 +163,8 @@ In the end, our HTML should look like this:
🦜 Polyglot - Piratical PyScript
-
-
+
+
Polyglot 🦜 💬 🇬🇧 ➡️ 🏴☠️
diff --git a/docs/user-guide/builtins.md b/docs/user-guide/builtins.md
index 7025a31..9778230 100644
--- a/docs/user-guide/builtins.md
+++ b/docs/user-guide/builtins.md
@@ -372,6 +372,80 @@ The following code demonstrates a `pyscript.WebSocket` in action.
ws = WebSocket(url="ws://example.com/socket", onmessage=onmessage)
```
+### `pyscript.storage`
+
+The `pyscript.storage` API wraps the browser's built-in
+[IndexDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)
+persistent storage in a synchronous Pythonic API.
+
+!!! info
+
+ The storage API is persistent per user tab, page, or domain, in the same
+ way IndexedDB persists.
+
+ This API **is not** saving files in the interpreter's virtual file system
+ nor onto the user's hard drive.
+
+```python
+from pyscript import storage
+
+
+# Each store must have a meaningful name.
+store = await storage("my-storage-name")
+
+# store is a dictionary and can now be used as such.
+```
+
+The returned dictionary automatically loads the current state of the referenced
+IndexDB. All changes are automatically queued in the background.
+
+```python
+# This is a write operation.
+store["key"] = value
+
+# This is also a write operation (it changes the stored data).
+del store["key"]
+```
+
+Should you wish to be certain changes have been synchronized to the underlying
+IndexDB, just `await store.sync()`.
+
+Common types of value can be stored via this API: `bool`, `float`, `int`, `str`
+and `None`. In addition, data structures like `list`, `dict` and `tuple` can
+be stored.
+
+!!! warning
+
+ Because of the way the underlying data structure are stored in IndexDB,
+ a Python `tuple` will always be returned as a Python `list`.
+
+It is even possible to store arbitrary data via a `bytearray` or
+`memoryview` object. However, there is a limitation that **such values must be
+stored as a single key/value pair, and not as part of a nested data
+structure**.
+
+Sometimes you may need to modify the behaviour of the `dict` like object
+returned by `pyscript.storage`. To do this, create a new class that inherits
+from `pyscript.Storage`, then pass in your class to `pyscript.storage` as the
+`storage_class` argument:
+
+```python
+from pyscript import window, storage, Storage
+
+
+class MyStorage(Storage):
+
+ def __setitem__(self, key, value):
+ super().__setitem__(key, value)
+ window.console.log(key, value)
+ ...
+
+
+store = await storage("my-data-store", storage_class=MyStorage)
+
+# The store object is now an instance of MyStorage.
+```
+
### `pyscript.ffi.to_js`
A utility function to convert Python references into their JavaScript
diff --git a/docs/user-guide/editor.md b/docs/user-guide/editor.md
index 1765d55..1951fad 100644
--- a/docs/user-guide/editor.md
+++ b/docs/user-guide/editor.md
@@ -173,6 +173,58 @@ If a `setup` editor is present, that's the only PyEditor that needs a config.
Any subsequent related editor will reuse the config parsed and bootstrapped for
the `setup` editor.
+## Run via keyboard
+
+Depending on your operating system, a combination of either `Ctrl-Enter`,
+`Cmd-Enter` or `Shift-Enter` will execute the code in the editor (no need to
+move the mouse to click the run button).
+
+## Override run
+
+Sometimes you just need to override the way the editor runs code.
+
+The editor's `handleEvent` can be overridden to achieve this:
+
+```html title="Overriding execution via handleEvent."
+
+
+
+```
+
+This
+[live example](https://agiammarchi.pyscriptapps.com/pyeditor-iot-example/latest/)
+shows how the editor can be used to execute code via a USB serial connection to
+a connected MicroPython microcontroller.
+
+## Tab behavior
+
+We currently trap the `tab` key in a way that reflects what a regular code
+editor would do: the code is simply indented, rather than focus moving to
+another element.
+
+We are fully aware of the implications this might have around accessibility so
+we followed
+[this detailed advice from Codemirror's documentation](https://codemirror.net/examples/tab/)
+We have an *escape hatch* to move focus outside the editor. Press `esc` before
+`tab` to move focus to the next focusable element. Otherwise `tab` indents
+code.
+
+
## Still missing
The PyEditor is currently under active development and refinement, so features
diff --git a/docs/user-guide/first-steps.md b/docs/user-guide/first-steps.md
index 8690d96..95db655 100644
--- a/docs/user-guide/first-steps.md
+++ b/docs/user-guide/first-steps.md
@@ -20,9 +20,9 @@ CSS:
-
+
-
+
diff --git a/docs/user-guide/plugins.md b/docs/user-guide/plugins.md
index fbf256d..1b49f66 100644
--- a/docs/user-guide/plugins.md
+++ b/docs/user-guide/plugins.md
@@ -99,7 +99,7 @@ For example, this will work because all references are contained within the
registered function:
```js
-import { hooks } from "https://pyscript.net/releases/2024.6.1/core.js";
+import { hooks } from "https://pyscript.net/releases/2024.6.2/core.js";
hooks.worker.onReady.add(() => {
// NOT suggested, just an example!
@@ -113,7 +113,7 @@ hooks.worker.onReady.add(() => {
However, due to the outer reference to the variable `i`, this will fail:
```js
-import { hooks } from "https://pyscript.net/releases/2024.6.1/core.js";
+import { hooks } from "https://pyscript.net/releases/2024.6.2/core.js";
// NO NO NO NO NO! ☠️
let i = 0;
@@ -146,7 +146,7 @@ the page.
```js title="log.js - a plugin that simply logs to the console."
// import the hooks from PyScript first...
-import { hooks } from "https://pyscript.net/releases/2024.6.1/core.js";
+import { hooks } from "https://pyscript.net/releases/2024.6.2/core.js";
// The `hooks.main` attribute defines plugins that run on the main thread.
hooks.main.onReady.add((wrap, element) => {
@@ -196,8 +196,8 @@ hooks.worker.onAfterRun.add(() => {
-
-
+
+
+
PyWorker - mpy bootstrapping pyodide example
diff --git a/version.json b/version.json
index b73d389..f7ef6ba 100644
--- a/version.json
+++ b/version.json
@@ -1,3 +1,3 @@
{
- "version": "2024.6.1"
+ "version": "2024.6.2"
}