@kehto/shell 0.24.3 → 0.24.5
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 +23 -0
- package/dist/index.js +18 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,6 +27,13 @@ source `dc1d24153c759152b6ba31a6ec9bea967798f2df`.
|
|
|
27
27
|
|
|
28
28
|
The primary entry point is `createShellBridge()` — it owns the postMessage listener, the NAP-SHELL `shell.ready` / `shell.init` handshake, manifest verification, and every dispatch back into the runtime engine.
|
|
29
29
|
|
|
30
|
+
ACL persistence uses the browser's `localStorage` key `napplet:acl`. A failed
|
|
31
|
+
write is intentionally reported through `bridge.runtime.aclState.persist()` or
|
|
32
|
+
`clear()` as `false`; the runtime keeps its already-applied live state, while a
|
|
33
|
+
fresh bridge can still load the prior durable policy until the caller retries.
|
|
34
|
+
Only ACL persistence has this result contract: unrelated browser persistence
|
|
35
|
+
adapters retain their documented best-effort behavior.
|
|
36
|
+
|
|
30
37
|
Current draft behaviors this package enforces:
|
|
31
38
|
|
|
32
39
|
- The shell does not inject a host-provided nostr object into napplets — NIP-5D explicitly forbids napplet-visible signing. Napplets call `relay.publish` / `relay.publishEncrypted` and the shell mediates the signing flow internally (NIP-44 default, NIP-04 opt-in for encrypted envelopes).
|
|
@@ -297,3 +304,19 @@ for outer URL encoding, review, routing, and verified launcher behavior.
|
|
|
297
304
|
## GAMEPAD integration
|
|
298
305
|
|
|
299
306
|
This non-normative guidance defers to the living [NAP-GAMEPAD](https://github.com/napplet/naps/pull/108). Services export `createGamepadService` and `browserGamepadOptions`; shell exports `denyNappletControllerAccess`. Paja and the playground register one host reader and deny native gamepad/HID/USB paths before frame execution. Source-bound subscriptions receive immediate full snapshots; only the visible host's input owner gets live controls. Focus loss supplies neutral controls and timestamp zero; unsubscribe, window destruction, and service removal release polling. Non-browser or denied native readers report the proposal's unavailable reasons. See [Controller input](https://github.com/kehto/web/blob/main/docs/gamepad.md).
|
|
307
|
+
|
|
308
|
+
## UUID support on HTTP origins
|
|
309
|
+
|
|
310
|
+
Shell event injection, cache queries, and source-session registration use native
|
|
311
|
+
`crypto.randomUUID()` when available. On browsers that omit it (including
|
|
312
|
+
non-localhost plain HTTP origins), the shell generates UUID v4 identifiers from
|
|
313
|
+
16 `crypto.getRandomValues()` bytes. If both methods are unavailable, UUID
|
|
314
|
+
creation throws an explicit capability error. This internal host UUID helper
|
|
315
|
+
never falls back to weak randomness; other identifier generators are outside
|
|
316
|
+
its scope. It does not provide secure-context APIs such as `crypto.subtle` on
|
|
317
|
+
HTTP, so this change does not establish HTTP support for uploads or other domains.
|
|
318
|
+
|
|
319
|
+
This is a supported platform capability choice, not a deprecated caller API.
|
|
320
|
+
Both standard Web Crypto paths remain quiet. Source-bound identity and optional
|
|
321
|
+
shell readiness are unchanged (NAP-SHELL at `napplet/naps`
|
|
322
|
+
`1e1046bcadabbc552804f6d3354f565184f9fefb`).
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
// src/shell-bridge.ts
|
|
2
2
|
import { createRuntime } from "@kehto/runtime";
|
|
3
3
|
|
|
4
|
+
// src/random-uuid.ts
|
|
5
|
+
function randomUUID() {
|
|
6
|
+
const provider = globalThis.crypto;
|
|
7
|
+
if (typeof provider?.randomUUID === "function") return provider.randomUUID();
|
|
8
|
+
if (typeof provider?.getRandomValues !== "function") {
|
|
9
|
+
throw new Error("@kehto/shell requires crypto.randomUUID or crypto.getRandomValues for UUID generation");
|
|
10
|
+
}
|
|
11
|
+
const bytes = provider.getRandomValues(new Uint8Array(16));
|
|
12
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
13
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
14
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
15
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
4
18
|
// src/hooks-adapter.ts
|
|
5
19
|
function bytesToHex(bytes) {
|
|
6
20
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
@@ -66,7 +80,7 @@ function createCacheAdapter(shellHooks) {
|
|
|
66
80
|
async query(filters) {
|
|
67
81
|
const workerRelay = shellHooks.workerRelay.getWorkerRelay();
|
|
68
82
|
if (!workerRelay) return [];
|
|
69
|
-
const subId =
|
|
83
|
+
const subId = randomUUID();
|
|
70
84
|
return workerRelay.query(["REQ", subId, ...filters]);
|
|
71
85
|
},
|
|
72
86
|
store(event) {
|
|
@@ -113,7 +127,7 @@ function createCryptoAdapter(shellHooks) {
|
|
|
113
127
|
return shellHooks.crypto.verifyEvent(event);
|
|
114
128
|
},
|
|
115
129
|
randomUUID() {
|
|
116
|
-
return
|
|
130
|
+
return randomUUID();
|
|
117
131
|
},
|
|
118
132
|
randomBytes(length) {
|
|
119
133
|
const bytes = new Uint8Array(length);
|
|
@@ -125,10 +139,7 @@ function createCryptoAdapter(shellHooks) {
|
|
|
125
139
|
function createAclPersistence() {
|
|
126
140
|
return {
|
|
127
141
|
persist(data) {
|
|
128
|
-
|
|
129
|
-
localStorage.setItem("napplet:acl", data);
|
|
130
|
-
} catch {
|
|
131
|
-
}
|
|
142
|
+
localStorage.setItem("napplet:acl", data);
|
|
132
143
|
},
|
|
133
144
|
load() {
|
|
134
145
|
try {
|
|
@@ -1143,7 +1154,7 @@ function registerNip5dSessionIfNeeded({
|
|
|
1143
1154
|
dTag: identity.dTag,
|
|
1144
1155
|
aggregateHash: identity.aggregateHash,
|
|
1145
1156
|
registeredAt: Date.now(),
|
|
1146
|
-
instanceId:
|
|
1157
|
+
instanceId: randomUUID(),
|
|
1147
1158
|
provenance: "nip-5d"
|
|
1148
1159
|
};
|
|
1149
1160
|
runtime.sessionRegistry.register(windowId, entry);
|