@lessly/sdk-app 63.2.1 → 63.2.2

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.
@@ -42,6 +42,25 @@ out at all.
42
42
  the problem*, though — a failed `/me` is not a denial. See the state table in
43
43
  §2 for what each `state` means for a control.
44
44
 
45
+ The snapshot lives **in the client instance** until `invalidate()` or until the
46
+ client itself is recreated. There is no TTL and no background refresh: a client
47
+ made once holds the role it loaded once, for as long as it lives.
48
+
49
+ That matters because a module-level singleton `createLesslyApp` client survives
50
+ SPA navigation and bfcache back/forward. A "reload" that does not remount the
51
+ remote — a router push, a browser Back into a restored page — keeps the old
52
+ snapshot, and the UI can lag the real role by minutes while `GET
53
+ products/:id/me` would answer correctly if anyone asked it. After a role change,
54
+ call `app.access.invalidate()` and then `load()` again (or do a full page
55
+ reload); do not wait for the snapshot to expire, because it never does.
56
+
57
+ Before you measure staleness, compare the role the App's own `/me` request
58
+ returned — read it in the Network tab — with what the API says now. Never assume
59
+ the role from memory: the two disagree exactly in the case you are debugging.
60
+ And it is never the HTTP cache alone: the server sends no `Cache-Control` for
61
+ `/me` today, so the browser only revalidates via `ETag`. Staleness you see is
62
+ the in-memory snapshot.
63
+
45
64
  You can pass either a tool id or a generated method, which carries its own
46
65
  identity:
47
66
 
package/docs/rules.md CHANGED
@@ -506,4 +506,17 @@ through `isAccessDenied()` for the *words*, and MUST NOT reimplement the confirm
506
506
  flow to win the colour — it would forfeit the focus trap, busy state, confirm
507
507
  phrase and step-up. Tracked as platform #2915.
508
508
 
509
+ The snapshot has no TTL, so staleness is the App's to invalidate:
510
+
511
+ - The access snapshot lives in the client instance until `invalidate()` or until
512
+ the client is recreated — there is no expiry and no background refresh.
513
+ - A module-level singleton client survives SPA navigation and bfcache
514
+ back/forward, so a "reload" that does not remount the remote keeps the old
515
+ role. After a role change an App MUST call `app.access.invalidate()` and then
516
+ `load()` (or do a full page reload).
517
+ - Before measuring staleness, compare the role the App's own `/me` request
518
+ returned (Network tab) with what the API answers now — never assume it from
519
+ memory. The server sends no `Cache-Control` for `/me` today and the browser
520
+ only revalidates via `ETag`, so the HTTP cache alone is never the explanation.
521
+
509
522
  See `recipes/access.md` for the load-once pattern and the empty-state shape.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessly/sdk-app",
3
- "version": "63.2.1",
3
+ "version": "63.2.2",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "engines": {