@@ -14,21 +14,18 @@ uses it under the hood.
1414!!! info
1515
1616 Sometimes you only need to `await` in the main thread the result of a call
17- to a method exposed in a worker.
17+ to a method exposed in a worker, where neither `window` nor `document` are
18+ either imported or ever needed in such worker.
1819
19- In such a limited case, and on the understanding that **code in the worker
20- will not be able to reach back into the main thread**, you should
21- use the [`sync_main_only` flag](../configuration/#sync_main_only) in your
22- configuration.
23-
24- While this eliminates the need for the Atomics related header configuration
25- (see below), the only possible use case is to **return a serialisable
20+ In these cases, you don't need any special header or *Service Worker*
21+ as long as any worker exposed utility **returns a serializable
2622 result from the method called on the worker**.
2723
2824## HTTP headers
2925
30- For Atomics to work ** you must ensure your web server enables the following
31- headers** (this is the default behaviour for
26+ For synchronous Atomics operations to work, those that enable features
27+ such as ` window ` and ` document ` from a worker, ** you must ensure your web server
28+ enables the following headers** (this is the default behavior for
3229[ pyscript.com] ( https://pyscript.com ) ):
3330
3431```
@@ -38,27 +35,104 @@ Cross-Origin-Embedder-Policy: require-corp
3835Cross-Origin-Resource-Policy: cross-origin
3936```
4037
41- If you are not able to configure your server's headers, use the
42- [ mini-coi] ( https://github.com/WebReflection/mini-coi#readme ) project to
43- achieve the same end.
44-
45- !!! Info
46-
47- The simplest way to use mini-coi is to place the
48- [mini-coi.js](https://raw.githubusercontent.com/WebReflection/mini-coi/main/mini-coi.js)
49- file in the root of your website (i.e. `/`), and reference it as the first
50- child tag in the `<head>` of your HTML documents:
51-
52- ```html
53- <html>
54- <head>
55- <script src="/mini-coi.js" scope="./"></script>
56- <!-- etc -->
57- </head>
58- <!-- etc -->
59- </html>
38+ If you need those features and you are not able to configure your server's headers,
39+ there are at least 2 options: use the
40+ [ mini-coi] ( https://github.com/WebReflection/mini-coi#readme ) project
41+ to enforce server side headers on each request or
42+ use the ` service-worker ` attribute.
43+
44+ ### Option 1: mini-coi
45+
46+ This is still a preferred option, mostly for performance reasons, so that
47+ * Atomics* ' synchronous operations can work at native speed.
48+
49+ The simplest way to use mini-coi is to copy the
50+ [ mini-coi.js] ( https://raw.githubusercontent.com/WebReflection/mini-coi/main/mini-coi.js )
51+ file content and save it in the root of your website (i.e. ` / ` ), and reference it
52+ as the first child tag in the ` <head> ` of your HTML documents:
53+
54+ ``` html
55+ <html >
56+ <head >
57+ <script src =" /mini-coi.js" ></script >
58+ <!-- etc -->
59+ </head >
60+ <!-- etc -->
61+ </html >
62+ ```
63+
64+ ### Option 2: service-worker attribute
65+
66+ Recently introduced, each ` <script type="m/py"> ` or ` <m/py-script> ` can have
67+ a ` service-worker ` attribute that must point to a locally served file, the
68+ same way ` mini-coi.js ` needs to be served, but there is more to it:
69+
70+ * you can chose ` mini-coi.js ` itself or * any other Service Worker* ,
71+ as long as it provides either the right headers to enable * Atomics*
72+ synchronous operations ir it enables
73+ [ sabayon polyfill events] ( https://github.com/WebReflection/sabayon?tab=readme-ov-file#service-worker )
74+ * you can copy and paste
75+ [ sabayon Service Worker] ( https://raw.githubusercontent.com/WebReflection/sabayon/main/dist/sw.js )
76+ into your local project and point at that in the attribute. This will
77+ not change the original behavior of your project, it will not interfere with
78+ all default or pre-defined headers your application use already but it will
79+ fallback to a (slower but working) synchronous operation that would enable
80+ both ` window ` and ` document ` access whenever that's needed in your worker logic
81+
82+ ``` html
83+ <html >
84+ <head >
85+ <!-- PyScript link and script -->
86+ </head >
87+ <body >
88+ <script type =" py" service-worker =" ./sw.js" worker >
89+ from pyscript import window, document
90+
91+ document .body .append (" Hello PyScript!" )
92+ </script >
93+ </body >
94+ </html >
95+ ```
96+
97+ !!! note
98+
99+ Using the *sabayon* fallback to enable *Atomics* synchronous operations
100+ should be the least solution to consider because it is inevitably
101+ slower than having native operations enabled by other means.
102+
103+ When that is still needed or desired, it is always better to reduce
104+ the amount of synchronous operations by caching references from the
105+ *main* thread.
106+
107+ ```python
108+ # ❌ THIS IS UNNECESSARILY SLOWER
109+ from pyscript import document
110+
111+ # add a data-test="not ideal attribute"
112+ document.body.dataset.test = "not ideal"
113+ # read a data-test attribute
114+ print(document.body.dataset.test)
115+
116+ # - - - - - - - - - - - - - - - - - - - - -
117+
118+ # ✔️ THIS IS FINE
119+ from pyscript import document
120+
121+ # if needed elsewhere, reach it once
122+ body = document.body
123+ dataset = body.dataset
124+
125+ # add a data-test="not ideal attribute"
126+ dataset.test = "not ideal"
127+ # read a data-test attribute
128+ print(dataset.test)
60129 ```
61130
131+ In latter example the amount of operations have been reduced
132+ from * 6* to just * 4* and the rule of thumb is:
133+ if you ever need a * DOM* reference more than once, cache it 👍
134+
135+
62136## Start working
63137
64138To start your code in a worker, simply ensure the ` <script> ` , ` <py-script> ` or
0 commit comments