@@ -14,21 +14,18 @@ uses it under the hood.
14
14
!!! info
15
15
16
16
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.
18
19
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
26
22
result from the method called on the worker**.
27
23
28
24
## HTTP headers
29
25
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
32
29
[ pyscript.com] ( https://pyscript.com ) ):
33
30
34
31
```
@@ -38,27 +35,104 @@ Cross-Origin-Embedder-Policy: require-corp
38
35
Cross-Origin-Resource-Policy: cross-origin
39
36
```
40
37
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)
60
129
```
61
130
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
+
62
136
## Start working
63
137
64
138
To start your code in a worker, simply ensure the ` <script> ` , ` <py-script> ` or
0 commit comments