@kehto/shell 0.2.0 → 0.5.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 +18 -13
- package/dist/index.d.ts +336 -117
- package/dist/index.js +267 -69
- package/dist/index.js.map +1 -1
- package/package.json +10 -24
package/dist/index.js
CHANGED
|
@@ -12,24 +12,22 @@ function hexToBytes(hex) {
|
|
|
12
12
|
}
|
|
13
13
|
return bytes;
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
const sendToNapplet = (windowId, msg) => {
|
|
15
|
+
function createSendToNapplet(originRegistry2) {
|
|
16
|
+
return (windowId, msg) => {
|
|
18
17
|
const win = originRegistry2.getIframeWindow(windowId);
|
|
19
18
|
if (win) win.postMessage(msg, "*");
|
|
20
19
|
};
|
|
21
|
-
|
|
20
|
+
}
|
|
21
|
+
function createRelayPoolAdapter(shellHooks, originRegistry2) {
|
|
22
|
+
return {
|
|
22
23
|
subscribe(filters, callback, relayUrls) {
|
|
23
24
|
const pool = shellHooks.relayPool.getRelayPool();
|
|
24
25
|
if (!pool) return { unsubscribe() {
|
|
25
26
|
} };
|
|
26
27
|
const urls = relayUrls ?? shellHooks.relayPool.selectRelayTier(filters);
|
|
27
28
|
const sub = pool.subscription(urls, filters).subscribe((item) => {
|
|
28
|
-
if (item === "EOSE")
|
|
29
|
-
|
|
30
|
-
} else {
|
|
31
|
-
callback(item);
|
|
32
|
-
}
|
|
29
|
+
if (item === "EOSE") callback("EOSE");
|
|
30
|
+
else callback(item);
|
|
33
31
|
});
|
|
34
32
|
return { unsubscribe: () => sub.unsubscribe() };
|
|
35
33
|
},
|
|
@@ -48,7 +46,7 @@ function adaptHooks(shellHooks, deps) {
|
|
|
48
46
|
untrackSubscription(subKey) {
|
|
49
47
|
shellHooks.relayPool.untrackSubscription(subKey);
|
|
50
48
|
},
|
|
51
|
-
openScopedRelay(windowId, relayUrl, subId, filters,
|
|
49
|
+
openScopedRelay(windowId, relayUrl, subId, filters, _sendFn) {
|
|
52
50
|
const win = originRegistry2.getIframeWindow(windowId);
|
|
53
51
|
if (win) shellHooks.relayPool.openScopedRelay(windowId, relayUrl, subId, filters, win);
|
|
54
52
|
},
|
|
@@ -62,7 +60,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
62
60
|
return shellHooks.relayPool.getRelayPool() !== null;
|
|
63
61
|
}
|
|
64
62
|
};
|
|
65
|
-
|
|
63
|
+
}
|
|
64
|
+
function createCacheAdapter(shellHooks) {
|
|
65
|
+
return {
|
|
66
66
|
async query(filters) {
|
|
67
67
|
const workerRelay = shellHooks.workerRelay.getWorkerRelay();
|
|
68
68
|
if (!workerRelay) return [];
|
|
@@ -82,7 +82,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
82
82
|
return shellHooks.workerRelay.getWorkerRelay() !== null;
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
-
|
|
85
|
+
}
|
|
86
|
+
function createAuthAdapter(shellHooks) {
|
|
87
|
+
return {
|
|
86
88
|
getUserPubkey() {
|
|
87
89
|
return shellHooks.auth.getUserPubkey();
|
|
88
90
|
},
|
|
@@ -90,17 +92,23 @@ function adaptHooks(shellHooks, deps) {
|
|
|
90
92
|
return shellHooks.auth.getSigner();
|
|
91
93
|
}
|
|
92
94
|
};
|
|
93
|
-
|
|
95
|
+
}
|
|
96
|
+
function createConfigAdapter(shellHooks) {
|
|
97
|
+
return {
|
|
94
98
|
getNappUpdateBehavior() {
|
|
95
99
|
return shellHooks.config.getNappUpdateBehavior();
|
|
96
100
|
}
|
|
97
101
|
};
|
|
98
|
-
|
|
102
|
+
}
|
|
103
|
+
function createHotkeyAdapter(shellHooks) {
|
|
104
|
+
return {
|
|
99
105
|
executeHotkeyFromForward(event) {
|
|
100
106
|
shellHooks.hotkeys.executeHotkeyFromForward(event);
|
|
101
107
|
}
|
|
102
108
|
};
|
|
103
|
-
|
|
109
|
+
}
|
|
110
|
+
function createCryptoAdapter(shellHooks) {
|
|
111
|
+
return {
|
|
104
112
|
async verifyEvent(event) {
|
|
105
113
|
return shellHooks.crypto.verifyEvent(event);
|
|
106
114
|
},
|
|
@@ -113,7 +121,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
113
121
|
return bytes;
|
|
114
122
|
}
|
|
115
123
|
};
|
|
116
|
-
|
|
124
|
+
}
|
|
125
|
+
function createAclPersistence() {
|
|
126
|
+
return {
|
|
117
127
|
persist(data) {
|
|
118
128
|
try {
|
|
119
129
|
localStorage.setItem("napplet:acl", data);
|
|
@@ -128,7 +138,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
128
138
|
}
|
|
129
139
|
}
|
|
130
140
|
};
|
|
131
|
-
|
|
141
|
+
}
|
|
142
|
+
function createManifestPersistence() {
|
|
143
|
+
return {
|
|
132
144
|
persist(data) {
|
|
133
145
|
try {
|
|
134
146
|
localStorage.setItem("napplet:manifest-cache", data);
|
|
@@ -143,7 +155,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
143
155
|
}
|
|
144
156
|
}
|
|
145
157
|
};
|
|
146
|
-
|
|
158
|
+
}
|
|
159
|
+
function createStatePersistence() {
|
|
160
|
+
return {
|
|
147
161
|
get(scopedKey) {
|
|
148
162
|
try {
|
|
149
163
|
return localStorage.getItem(scopedKey);
|
|
@@ -204,12 +218,16 @@ function adaptHooks(shellHooks, deps) {
|
|
|
204
218
|
}
|
|
205
219
|
}
|
|
206
220
|
};
|
|
207
|
-
|
|
221
|
+
}
|
|
222
|
+
function createWindowManagerAdapter(shellHooks) {
|
|
223
|
+
return {
|
|
208
224
|
createWindow(options) {
|
|
209
225
|
return shellHooks.windowManager.createWindow(options);
|
|
210
226
|
}
|
|
211
227
|
};
|
|
212
|
-
|
|
228
|
+
}
|
|
229
|
+
function createRelayConfigAdapter(shellHooks) {
|
|
230
|
+
return {
|
|
213
231
|
addRelay(tier, url) {
|
|
214
232
|
shellHooks.relayConfig.addRelay(tier, url);
|
|
215
233
|
},
|
|
@@ -223,7 +241,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
223
241
|
return shellHooks.relayConfig.getNip66Suggestions();
|
|
224
242
|
}
|
|
225
243
|
};
|
|
226
|
-
|
|
244
|
+
}
|
|
245
|
+
function createShellSecretPersistence() {
|
|
246
|
+
return {
|
|
227
247
|
get() {
|
|
228
248
|
try {
|
|
229
249
|
const hex = localStorage.getItem("napplet-shell-secret");
|
|
@@ -240,7 +260,9 @@ function adaptHooks(shellHooks, deps) {
|
|
|
240
260
|
}
|
|
241
261
|
}
|
|
242
262
|
};
|
|
243
|
-
|
|
263
|
+
}
|
|
264
|
+
function createGuidPersistence() {
|
|
265
|
+
return {
|
|
244
266
|
get(windowId) {
|
|
245
267
|
try {
|
|
246
268
|
return localStorage.getItem(`napplet-guid:${windowId}`);
|
|
@@ -261,27 +283,32 @@ function adaptHooks(shellHooks, deps) {
|
|
|
261
283
|
}
|
|
262
284
|
}
|
|
263
285
|
};
|
|
264
|
-
|
|
286
|
+
}
|
|
287
|
+
function createDmAdapter(shellHooks) {
|
|
288
|
+
return shellHooks.dm ? {
|
|
265
289
|
sendDm(recipientPubkey, message) {
|
|
266
290
|
return shellHooks.dm.sendDm(recipientPubkey, message);
|
|
267
291
|
}
|
|
268
292
|
} : void 0;
|
|
293
|
+
}
|
|
294
|
+
function adaptHooks(shellHooks, deps) {
|
|
295
|
+
const { originRegistry: originRegistry2 } = deps;
|
|
269
296
|
return {
|
|
270
|
-
sendToNapplet,
|
|
271
|
-
relayPool,
|
|
272
|
-
cache:
|
|
273
|
-
auth,
|
|
274
|
-
config,
|
|
275
|
-
hotkeys,
|
|
276
|
-
crypto:
|
|
277
|
-
aclPersistence,
|
|
278
|
-
manifestPersistence,
|
|
279
|
-
statePersistence,
|
|
280
|
-
windowManager,
|
|
281
|
-
relayConfig,
|
|
282
|
-
dm,
|
|
283
|
-
shellSecretPersistence,
|
|
284
|
-
guidPersistence,
|
|
297
|
+
sendToNapplet: createSendToNapplet(originRegistry2),
|
|
298
|
+
relayPool: createRelayPoolAdapter(shellHooks, originRegistry2),
|
|
299
|
+
cache: createCacheAdapter(shellHooks),
|
|
300
|
+
auth: createAuthAdapter(shellHooks),
|
|
301
|
+
config: createConfigAdapter(shellHooks),
|
|
302
|
+
hotkeys: createHotkeyAdapter(shellHooks),
|
|
303
|
+
crypto: createCryptoAdapter(shellHooks),
|
|
304
|
+
aclPersistence: createAclPersistence(),
|
|
305
|
+
manifestPersistence: createManifestPersistence(),
|
|
306
|
+
statePersistence: createStatePersistence(),
|
|
307
|
+
windowManager: createWindowManagerAdapter(shellHooks),
|
|
308
|
+
relayConfig: createRelayConfigAdapter(shellHooks),
|
|
309
|
+
dm: createDmAdapter(shellHooks),
|
|
310
|
+
shellSecretPersistence: createShellSecretPersistence(),
|
|
311
|
+
guidPersistence: createGuidPersistence(),
|
|
285
312
|
onAclCheck: shellHooks.onAclCheck,
|
|
286
313
|
onHashMismatch: shellHooks.onHashMismatch,
|
|
287
314
|
services: shellHooks.services,
|
|
@@ -503,7 +530,8 @@ var CAP_BITS = {
|
|
|
503
530
|
"media:control": 1024,
|
|
504
531
|
"notify:send": 2048,
|
|
505
532
|
"notify:channel": 4096,
|
|
506
|
-
"theme:read": 8192
|
|
533
|
+
"theme:read": 8192,
|
|
534
|
+
"identity:decrypt": 65536
|
|
507
535
|
};
|
|
508
536
|
function capArrayToBitfield(caps) {
|
|
509
537
|
let bits = 0;
|
|
@@ -864,7 +892,7 @@ var audioManager = {
|
|
|
864
892
|
if (iframeWindow) {
|
|
865
893
|
const muteEvent = {
|
|
866
894
|
kind: 29e3,
|
|
867
|
-
//
|
|
895
|
+
// IFC_PEER — inlined numeric after Phase 24 DRIFT-01 shim removal
|
|
868
896
|
created_at: Math.floor(Date.now() / 1e3),
|
|
869
897
|
tags: [["t", "napplet:audio-muted"]],
|
|
870
898
|
content: JSON.stringify({ muted }),
|
|
@@ -916,21 +944,6 @@ var audioManager = {
|
|
|
916
944
|
}
|
|
917
945
|
};
|
|
918
946
|
|
|
919
|
-
// src/shell-init.ts
|
|
920
|
-
var CANONICAL_NUB_DOMAINS = [
|
|
921
|
-
"identity",
|
|
922
|
-
"storage",
|
|
923
|
-
"ifc",
|
|
924
|
-
"theme",
|
|
925
|
-
"keys",
|
|
926
|
-
"media",
|
|
927
|
-
"notify"
|
|
928
|
-
];
|
|
929
|
-
function buildShellCapabilities(hooks) {
|
|
930
|
-
const nubs = hooks.relayPool ? ["relay", ...CANONICAL_NUB_DOMAINS] : [...CANONICAL_NUB_DOMAINS];
|
|
931
|
-
return { nubs, sandbox: [] };
|
|
932
|
-
}
|
|
933
|
-
|
|
934
947
|
// src/keys-forwarder.ts
|
|
935
948
|
function createKeysForwarder(deps) {
|
|
936
949
|
const target = deps.target ?? (typeof window !== "undefined" ? window : new EventTarget());
|
|
@@ -961,6 +974,186 @@ function createKeysForwarder(deps) {
|
|
|
961
974
|
};
|
|
962
975
|
}
|
|
963
976
|
|
|
977
|
+
// src/connect-store.ts
|
|
978
|
+
var STORAGE_KEY3 = "napplet:connect";
|
|
979
|
+
function connectKey(dTag, aggregateHash) {
|
|
980
|
+
return `${dTag}:${aggregateHash}`;
|
|
981
|
+
}
|
|
982
|
+
var store2 = /* @__PURE__ */ new Map();
|
|
983
|
+
var connectStore = {
|
|
984
|
+
check(dTag, aggregateHash, origin) {
|
|
985
|
+
const entry = store2.get(connectKey(dTag, aggregateHash));
|
|
986
|
+
if (!entry) return false;
|
|
987
|
+
return entry.origins.includes(origin);
|
|
988
|
+
},
|
|
989
|
+
getOrigins(dTag, aggregateHash) {
|
|
990
|
+
const entry = store2.get(connectKey(dTag, aggregateHash));
|
|
991
|
+
return entry ? [...entry.origins] : [];
|
|
992
|
+
},
|
|
993
|
+
grant(dTag, aggregateHash, origins) {
|
|
994
|
+
const key = connectKey(dTag, aggregateHash);
|
|
995
|
+
const sorted = [...new Set(origins)].sort();
|
|
996
|
+
store2.set(key, { key, dTag, aggregateHash, origins: sorted, grantedAt: Date.now() });
|
|
997
|
+
connectStore.persist();
|
|
998
|
+
},
|
|
999
|
+
revoke(dTag, aggregateHash) {
|
|
1000
|
+
store2.delete(connectKey(dTag, aggregateHash));
|
|
1001
|
+
connectStore.persist();
|
|
1002
|
+
},
|
|
1003
|
+
getAllGrants() {
|
|
1004
|
+
return Array.from(store2.values()).map((e) => ({
|
|
1005
|
+
dTag: e.dTag,
|
|
1006
|
+
aggregateHash: e.aggregateHash,
|
|
1007
|
+
origins: [...e.origins]
|
|
1008
|
+
}));
|
|
1009
|
+
},
|
|
1010
|
+
persist() {
|
|
1011
|
+
try {
|
|
1012
|
+
const entries = Array.from(store2.entries()).map(([k, v]) => [k, {
|
|
1013
|
+
dTag: v.dTag,
|
|
1014
|
+
aggregateHash: v.aggregateHash,
|
|
1015
|
+
origins: v.origins,
|
|
1016
|
+
grantedAt: v.grantedAt
|
|
1017
|
+
}]);
|
|
1018
|
+
localStorage.setItem(STORAGE_KEY3, JSON.stringify(entries));
|
|
1019
|
+
} catch {
|
|
1020
|
+
}
|
|
1021
|
+
},
|
|
1022
|
+
load() {
|
|
1023
|
+
try {
|
|
1024
|
+
const raw = localStorage.getItem(STORAGE_KEY3);
|
|
1025
|
+
if (!raw) return;
|
|
1026
|
+
const entries = JSON.parse(raw);
|
|
1027
|
+
store2.clear();
|
|
1028
|
+
for (const [key, val] of entries) {
|
|
1029
|
+
if (!Array.isArray(val.origins)) continue;
|
|
1030
|
+
store2.set(key, {
|
|
1031
|
+
key,
|
|
1032
|
+
dTag: val.dTag,
|
|
1033
|
+
aggregateHash: val.aggregateHash,
|
|
1034
|
+
origins: [...val.origins],
|
|
1035
|
+
grantedAt: val.grantedAt ?? 0
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
} catch {
|
|
1039
|
+
store2.clear();
|
|
1040
|
+
}
|
|
1041
|
+
},
|
|
1042
|
+
clear() {
|
|
1043
|
+
store2.clear();
|
|
1044
|
+
try {
|
|
1045
|
+
localStorage.removeItem(STORAGE_KEY3);
|
|
1046
|
+
} catch {
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
function connectGrantKey(dTag, aggregateHash) {
|
|
1051
|
+
return `${dTag}:${aggregateHash}`;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
// src/shell-init.ts
|
|
1055
|
+
var CANONICAL_NUB_DOMAINS = [
|
|
1056
|
+
"identity",
|
|
1057
|
+
"storage",
|
|
1058
|
+
"ifc",
|
|
1059
|
+
"theme",
|
|
1060
|
+
"keys",
|
|
1061
|
+
"media",
|
|
1062
|
+
"notify",
|
|
1063
|
+
"config",
|
|
1064
|
+
"resource",
|
|
1065
|
+
"connect",
|
|
1066
|
+
"class",
|
|
1067
|
+
"cvm"
|
|
1068
|
+
];
|
|
1069
|
+
var SUPPORTED_IFC_PROTOCOLS = [
|
|
1070
|
+
"ifc:NAP-01",
|
|
1071
|
+
"ifc:NUB-01",
|
|
1072
|
+
"ifc:NUB-02",
|
|
1073
|
+
"ifc:NUB-03",
|
|
1074
|
+
"ifc:NUB-04",
|
|
1075
|
+
"ifc:NUB-05",
|
|
1076
|
+
"ifc:NUB-06"
|
|
1077
|
+
];
|
|
1078
|
+
function buildShellCapabilities(hooks) {
|
|
1079
|
+
const nubs = hooks.relayPool ? ["relay", ...CANONICAL_NUB_DOMAINS, ...SUPPORTED_IFC_PROTOCOLS] : [...CANONICAL_NUB_DOMAINS, ...SUPPORTED_IFC_PROTOCOLS];
|
|
1080
|
+
return { nubs, sandbox: [] };
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// src/shell-ready.ts
|
|
1084
|
+
function handleShellReady({
|
|
1085
|
+
hooks,
|
|
1086
|
+
origin,
|
|
1087
|
+
runtime,
|
|
1088
|
+
windowId
|
|
1089
|
+
}) {
|
|
1090
|
+
const capabilities = buildShellCapabilities(hooks);
|
|
1091
|
+
registerNip5dSessionIfNeeded({ hooks, origin, runtime, windowId });
|
|
1092
|
+
postShellInit(runtime, windowId, capabilities, Object.keys(hooks.services ?? {}));
|
|
1093
|
+
}
|
|
1094
|
+
function registerNip5dSessionIfNeeded({
|
|
1095
|
+
hooks,
|
|
1096
|
+
origin,
|
|
1097
|
+
runtime,
|
|
1098
|
+
windowId
|
|
1099
|
+
}) {
|
|
1100
|
+
if (runtime.sessionRegistry.getEntryByWindowId(windowId)) {
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
const identity = resolveNip5dIdentity(hooks, windowId);
|
|
1104
|
+
if (!identity) {
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const entry = {
|
|
1108
|
+
pubkey: "",
|
|
1109
|
+
windowId,
|
|
1110
|
+
origin,
|
|
1111
|
+
type: "nip5d",
|
|
1112
|
+
dTag: identity.dTag,
|
|
1113
|
+
aggregateHash: identity.aggregateHash,
|
|
1114
|
+
registeredAt: Date.now(),
|
|
1115
|
+
instanceId: crypto.randomUUID(),
|
|
1116
|
+
provenance: "nip-5d",
|
|
1117
|
+
class: identity.class
|
|
1118
|
+
};
|
|
1119
|
+
runtime.sessionRegistry.register(windowId, entry);
|
|
1120
|
+
}
|
|
1121
|
+
function resolveNip5dIdentity(hooks, windowId) {
|
|
1122
|
+
const hookIdentity = hooks.onNip5dIframeCreate?.(windowId);
|
|
1123
|
+
if (hookIdentity !== null && hookIdentity !== void 0) {
|
|
1124
|
+
return {
|
|
1125
|
+
dTag: hookIdentity.dTag,
|
|
1126
|
+
aggregateHash: hookIdentity.aggregateHash,
|
|
1127
|
+
class: hookIdentity.class
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
const win = originRegistry.getIframeWindow(windowId);
|
|
1131
|
+
if (!win) {
|
|
1132
|
+
return null;
|
|
1133
|
+
}
|
|
1134
|
+
const originIdentity = originRegistry.getIdentity(win);
|
|
1135
|
+
if (!originIdentity) {
|
|
1136
|
+
return null;
|
|
1137
|
+
}
|
|
1138
|
+
return {
|
|
1139
|
+
dTag: originIdentity.dTag,
|
|
1140
|
+
aggregateHash: originIdentity.aggregateHash,
|
|
1141
|
+
class: null
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
function postShellInit(runtime, windowId, capabilities, services) {
|
|
1145
|
+
const sessionEntry = runtime.sessionRegistry.getEntryByWindowId(windowId);
|
|
1146
|
+
const resolvedClass = sessionEntry?.class ?? null;
|
|
1147
|
+
const initMsg = {
|
|
1148
|
+
type: "shell.init",
|
|
1149
|
+
capabilities,
|
|
1150
|
+
services,
|
|
1151
|
+
class: resolvedClass
|
|
1152
|
+
};
|
|
1153
|
+
const win = originRegistry.getIframeWindow(windowId);
|
|
1154
|
+
if (win) win.postMessage(initMsg, "*");
|
|
1155
|
+
}
|
|
1156
|
+
|
|
964
1157
|
// src/shell-bridge.ts
|
|
965
1158
|
function createShellBridge(hooks) {
|
|
966
1159
|
const runtimeHooks = adaptHooks(hooks, {
|
|
@@ -971,6 +1164,14 @@ function createShellBridge(hooks) {
|
|
|
971
1164
|
nappKeyRegistry
|
|
972
1165
|
});
|
|
973
1166
|
const runtime = createRuntime(runtimeHooks);
|
|
1167
|
+
function broadcastToNapplets(envelope) {
|
|
1168
|
+
const windowIds = originRegistry.getAllWindowIds();
|
|
1169
|
+
for (const windowId of windowIds) {
|
|
1170
|
+
const win = originRegistry.getIframeWindow(windowId);
|
|
1171
|
+
if (!win) continue;
|
|
1172
|
+
win.postMessage(envelope, "*");
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
974
1175
|
let keysForwarder = null;
|
|
975
1176
|
if (typeof window !== "undefined") {
|
|
976
1177
|
try {
|
|
@@ -997,14 +1198,7 @@ function createShellBridge(hooks) {
|
|
|
997
1198
|
const msg = event.data;
|
|
998
1199
|
if (typeof msg !== "object" || msg === null || typeof msg.type !== "string") return;
|
|
999
1200
|
if (msg.type === "shell.ready") {
|
|
1000
|
-
|
|
1001
|
-
const initMsg = {
|
|
1002
|
-
type: "shell.init",
|
|
1003
|
-
capabilities,
|
|
1004
|
-
services: Object.keys(hooks.services ?? {})
|
|
1005
|
-
};
|
|
1006
|
-
const win = originRegistry.getIframeWindow(windowId);
|
|
1007
|
-
if (win) win.postMessage(initMsg, "*");
|
|
1201
|
+
handleShellReady({ hooks, origin: event.origin, runtime, windowId });
|
|
1008
1202
|
return;
|
|
1009
1203
|
}
|
|
1010
1204
|
runtime.handleMessage(windowId, msg);
|
|
@@ -1021,15 +1215,17 @@ function createShellBridge(hooks) {
|
|
|
1021
1215
|
},
|
|
1022
1216
|
publishTheme(theme) {
|
|
1023
1217
|
const envelope = { type: "theme.changed", theme };
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
}
|
|
1218
|
+
broadcastToNapplets(envelope);
|
|
1219
|
+
},
|
|
1220
|
+
publishIdentityChanged(pubkey) {
|
|
1221
|
+
const envelope = { type: "identity.changed", pubkey };
|
|
1222
|
+
broadcastToNapplets(envelope);
|
|
1030
1223
|
},
|
|
1031
1224
|
get runtime() {
|
|
1032
1225
|
return runtime;
|
|
1226
|
+
},
|
|
1227
|
+
get connectStore() {
|
|
1228
|
+
return connectStore;
|
|
1033
1229
|
}
|
|
1034
1230
|
};
|
|
1035
1231
|
}
|
|
@@ -1111,6 +1307,8 @@ export {
|
|
|
1111
1307
|
adaptHooks,
|
|
1112
1308
|
audioManager,
|
|
1113
1309
|
buildShellCapabilities,
|
|
1310
|
+
connectGrantKey,
|
|
1311
|
+
connectStore,
|
|
1114
1312
|
createEnforceGate,
|
|
1115
1313
|
createIdentityProxy,
|
|
1116
1314
|
createKeysForwarder,
|