@braidlabs/sw 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -109,6 +109,64 @@ and cache a composed response (a page pierced against a registry that has since
|
|
|
109
109
|
the stale artifact this package exists to avoid). Composed pages carry
|
|
110
110
|
`x-braid-composed: offline` so a shell can say so rather than look merely slow.
|
|
111
111
|
|
|
112
|
+
## The gateway in the worker, for static hosting (requirements, not built)
|
|
113
|
+
|
|
114
|
+
Offline composition already runs the gateway's piercing in the worker. The open question is whether
|
|
115
|
+
the worker can be the gateway **while online**, for a shell on purely static hosting (a bucket, a
|
|
116
|
+
CDN, GitHub Pages) with no server in front of it. Nothing below is built. It records what an
|
|
117
|
+
implementation must satisfy, so the design starts from the constraints rather than discovering them.
|
|
118
|
+
|
|
119
|
+
**What it would do.** It would serve `/__braid/realm/:id/*` stubs, proxy `/__braid/frag/:id/*` and
|
|
120
|
+
`/__braid/doc/:id/*` to each fragment's origin, and pierce document navigations, all with the
|
|
121
|
+
gateway's own code. That is exactly what offline composition does now, but against the network.
|
|
122
|
+
|
|
123
|
+
### Requirements
|
|
124
|
+
|
|
125
|
+
1. **The first visit must work without a reload.** No worker is installed on a first visit, so the
|
|
126
|
+
design is:
|
|
127
|
+
- The static host serves the shell and realm stubs generated at build time. Stubs are
|
|
128
|
+
byte-stable per registry snapshot, so they can be plain files.
|
|
129
|
+
- The page registers the worker, and the worker calls `clients.claim()` for this mode. This is
|
|
130
|
+
a deliberate exception to the `claimClients: false` default above: there is no earlier worker
|
|
131
|
+
to swap out from under the page.
|
|
132
|
+
- Slots wait for `navigator.serviceWorker.ready`, with a timeout, before booting. From then on
|
|
133
|
+
the realm iframes' navigations and the namespace fetches are the worker's to answer.
|
|
134
|
+
- The first visit's first paint is not composed. Fragments boot client-side, which already works
|
|
135
|
+
without piercing. Every later navigation is composed by the worker.
|
|
136
|
+
2. **Fragment origins must send CORS headers.** The worker fetches them cross-origin. Documents and
|
|
137
|
+
assets need `Access-Control-Allow-Origin` naming the shell's origin, and module scripts need it
|
|
138
|
+
regardless.
|
|
139
|
+
3. **Authenticated fragments must be same-site with the shell** (subdomains of one registrable
|
|
140
|
+
domain). With credentials, the worker's cross-origin requests also need
|
|
141
|
+
`Access-Control-Allow-Credentials`. Across sites, third-party cookie blocking (Safari, Firefox,
|
|
142
|
+
and Chrome where enabled) drops the session. A fragment that needs login cookies from another
|
|
143
|
+
site cannot be composed this way, and the build should refuse its manifest rather than let it
|
|
144
|
+
fail at runtime.
|
|
145
|
+
4. **There must be a fallback where no worker can run.** Some private-browsing modes and enterprise
|
|
146
|
+
policies disable service workers. Without a worker, compat fragments have no namespace, so the
|
|
147
|
+
page must boot those slots as contract or untrusted fragments, or show their fallback content.
|
|
148
|
+
It must never leave them half-booted.
|
|
149
|
+
5. **What the server gateway enforces must stay enforced.** Today's server gateway strips
|
|
150
|
+
credentials (`forwardCredentials`), checks `access`, and decides redirects (`redirectOrigins`).
|
|
151
|
+
In the worker, all of that runs on the user's device, which makes it advisory: a user can
|
|
152
|
+
change it. Anything that must hold against the user stays on the fragment's own origin. The
|
|
153
|
+
docs must say so plainly, as the boundary docs do for trusted fragments.
|
|
154
|
+
6. **The registry must be pinned.** The worker loads one snapshot (`snapshotUrl`), verifies it as
|
|
155
|
+
the registry does, and composes only from it. Updating the snapshot follows the worker's
|
|
156
|
+
version discipline (see below), so configuration churn never becomes an unannounced change of
|
|
157
|
+
composition mid-session.
|
|
158
|
+
7. **The gateway core stays runtime-neutral.** No `node:` imports in the gateway, registry or
|
|
159
|
+
rewriter, which offline composition already depends on. A new dependency of the core that
|
|
160
|
+
breaks this breaks both.
|
|
161
|
+
|
|
162
|
+
### Open questions
|
|
163
|
+
|
|
164
|
+
- **Worker startup on every navigation.** A cold start can add tens of milliseconds on mobile.
|
|
165
|
+
Navigation preload can fetch the shell while the worker boots, but there is no server to ask for
|
|
166
|
+
the fragments early.
|
|
167
|
+
- **Which `x-braid-composed` value** a worker-composed online page should carry, so it can be told
|
|
168
|
+
apart from a server-composed one in telemetry.
|
|
169
|
+
|
|
112
170
|
## The worker is itself a skew vector
|
|
113
171
|
|
|
114
172
|
It is a long-lived deployment artifact that updates on its own schedule — a version boundary added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@braidlabs/sw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Braid service worker — skew-aware asset serving for composed pages: each fragment gets its own build-keyed cache partition, so a page already open keeps getting the chunks it was built against after a deploy lands. Ships as a handler to compose into an existing worker, and as a complete worker.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"micro-frontends",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@braidlabs/data": "^0.
|
|
29
|
-
"@braidlabs/gateway": "^0.
|
|
28
|
+
"@braidlabs/data": "^0.7.0",
|
|
29
|
+
"@braidlabs/gateway": "^0.7.0"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|