@kehto/shell 0.16.4 → 0.16.6

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/dist/index.js CHANGED
@@ -1025,7 +1025,6 @@ function buildShellCapabilities(hooks) {
1025
1025
  if (hooks.webrtc?.isAvailable()) domains.push("webrtc");
1026
1026
  if (hooks.dm) domains.push("dm");
1027
1027
  const sandbox = [];
1028
- domains.push(...sandbox);
1029
1028
  const protocols = {};
1030
1029
  for (const entry of NAP_INC_PROTOCOLS) {
1031
1030
  const [domain, protocol] = entry.split(":");
@@ -1275,18 +1274,777 @@ function injectNappletNamespacePrelude(html, options) {
1275
1274
  }
1276
1275
  function nappletNamespacePrelude(domains) {
1277
1276
  const target = window;
1277
+ const allowed = new Set(domains);
1278
+ const requestTimeoutMs = 3e4;
1279
+ function id() {
1280
+ if (target.crypto?.randomUUID) return target.crypto.randomUUID();
1281
+ return `napplet-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1282
+ }
1283
+ function post(message) {
1284
+ target.parent.postMessage(message, "*");
1285
+ }
1286
+ function listen(listener) {
1287
+ target.addEventListener("message", listener);
1288
+ return () => target.removeEventListener("message", listener);
1289
+ }
1290
+ function isParentMessage(event) {
1291
+ return event.source === target.parent;
1292
+ }
1293
+ function request(message, resultType, map, options = {}) {
1294
+ const requestId = message.id ?? id();
1295
+ const outbound = { ...message, id: requestId };
1296
+ return new Promise((resolve, reject) => {
1297
+ const off = listen((event) => {
1298
+ if (!isParentMessage(event)) return;
1299
+ const incoming = event.data;
1300
+ if (typeof incoming !== "object" || incoming === null) return;
1301
+ const msg = incoming;
1302
+ if (msg.type !== resultType && msg.type !== `${message.type}.error`) return;
1303
+ if (msg.id !== requestId) return;
1304
+ off();
1305
+ clearTimeout(timer);
1306
+ const error = typeof msg.error === "string" ? msg.error : "";
1307
+ if (error && options.rejectOnError !== false) {
1308
+ reject(new Error(error));
1309
+ return;
1310
+ }
1311
+ try {
1312
+ resolve(map(msg));
1313
+ } catch (err) {
1314
+ reject(err);
1315
+ }
1316
+ });
1317
+ const timer = setTimeout(() => {
1318
+ off();
1319
+ reject(new Error(`${message.type} timed out`));
1320
+ }, requestTimeoutMs);
1321
+ post(outbound);
1322
+ });
1323
+ }
1324
+ function fire(message) {
1325
+ post(message);
1326
+ }
1327
+ function resultOrError(msg) {
1328
+ return msg;
1329
+ }
1330
+ function withoutEnvelope(msg) {
1331
+ const { type: _type, id: _id, ...result } = msg;
1332
+ return result;
1333
+ }
1334
+ function fieldOrThrow(msg, field, fallback) {
1335
+ if (Object.prototype.hasOwnProperty.call(msg, field)) return msg[field];
1336
+ throw new Error(typeof msg.error === "string" ? msg.error : fallback);
1337
+ }
1338
+ function voidResult(msg, fallback) {
1339
+ if (typeof msg.error === "string" && msg.error) throw new Error(msg.error);
1340
+ if (msg.ok === false) throw new Error(fallback);
1341
+ }
1342
+ function subscriptionHandle(close) {
1343
+ let closed = false;
1344
+ return {
1345
+ close() {
1346
+ if (closed) return;
1347
+ closed = true;
1348
+ close();
1349
+ }
1350
+ };
1351
+ }
1352
+ function domainEventHandle(eventType, callback, select = (message) => message.event) {
1353
+ const off = listen((event) => {
1354
+ if (!isParentMessage(event)) return;
1355
+ const msg = event.data;
1356
+ if (typeof msg === "object" && msg !== null && msg.type === eventType) callback(select(msg));
1357
+ });
1358
+ return subscriptionHandle(off);
1359
+ }
1360
+ function makeRelay() {
1361
+ return {
1362
+ subscribe(filters, onEvent, onEose, options) {
1363
+ const subId = id();
1364
+ const off = listen((event) => {
1365
+ if (!isParentMessage(event)) return;
1366
+ const msg = event.data;
1367
+ if (typeof msg !== "object" || msg === null || msg.subId !== subId) return;
1368
+ if (msg.type === "relay.event") onEvent(msg.result);
1369
+ else if (msg.type === "relay.eose") onEose();
1370
+ else if (msg.type === "relay.closed") off();
1371
+ });
1372
+ fire({
1373
+ type: "relay.subscribe",
1374
+ id: id(),
1375
+ subId,
1376
+ filters: Array.isArray(filters) ? filters : [filters],
1377
+ ...options?.relay ? { relay: options.relay } : {}
1378
+ });
1379
+ return subscriptionHandle(() => {
1380
+ fire({ type: "relay.close", id: id(), subId });
1381
+ off();
1382
+ });
1383
+ },
1384
+ publish(template) {
1385
+ return request(
1386
+ { type: "relay.publish", event: template },
1387
+ "relay.publish.result",
1388
+ (msg) => {
1389
+ if (!msg.event) throw new Error("relay.publish.result missing event");
1390
+ return msg.event;
1391
+ }
1392
+ );
1393
+ },
1394
+ publishEncrypted(template, recipient, encryption = "nip44") {
1395
+ return request(
1396
+ { type: "relay.publishEncrypted", event: template, recipient, encryption },
1397
+ "relay.publishEncrypted.result",
1398
+ (msg) => {
1399
+ if (!msg.event) throw new Error("relay.publishEncrypted.result missing event");
1400
+ return msg.event;
1401
+ }
1402
+ );
1403
+ },
1404
+ query(filters) {
1405
+ return request(
1406
+ { type: "relay.query", filters: Array.isArray(filters) ? filters : [filters] },
1407
+ "relay.query.result",
1408
+ (msg) => Array.isArray(msg.events) ? msg.events : []
1409
+ );
1410
+ }
1411
+ };
1412
+ }
1413
+ function makeInc() {
1414
+ return {
1415
+ emit(topic, _extraTags, content) {
1416
+ let payload = content;
1417
+ if (typeof content === "string" && content.length > 0) {
1418
+ try {
1419
+ payload = JSON.parse(content);
1420
+ } catch {
1421
+ payload = content;
1422
+ }
1423
+ }
1424
+ fire({ type: "inc.emit", topic, ...payload === void 0 || payload === "" ? {} : { payload } });
1425
+ },
1426
+ on(topic, callback) {
1427
+ const off = listen((event) => {
1428
+ if (!isParentMessage(event)) return;
1429
+ const msg = event.data;
1430
+ if (typeof msg !== "object" || msg === null || msg.type !== "inc.event" || msg.topic !== topic) return;
1431
+ callback(msg.payload ?? {}, {
1432
+ id: "",
1433
+ pubkey: typeof msg.sender === "string" ? msg.sender : "",
1434
+ created_at: Math.floor(Date.now() / 1e3),
1435
+ kind: 0,
1436
+ tags: [["t", topic]],
1437
+ content: typeof msg.payload === "string" ? msg.payload : JSON.stringify(msg.payload ?? {}),
1438
+ sig: ""
1439
+ });
1440
+ });
1441
+ fire({ type: "inc.subscribe", id: id(), topic });
1442
+ return subscriptionHandle(() => {
1443
+ fire({ type: "inc.unsubscribe", topic });
1444
+ off();
1445
+ });
1446
+ }
1447
+ };
1448
+ }
1449
+ function makeStorage() {
1450
+ const makeScope = (scope) => ({
1451
+ getItem(key) {
1452
+ return request(
1453
+ { type: "storage.get", key, ...scope ? { scope } : {} },
1454
+ "storage.get.result",
1455
+ (msg) => msg.value ?? null
1456
+ );
1457
+ },
1458
+ setItem(key, value) {
1459
+ return request(
1460
+ { type: "storage.set", key, value, ...scope ? { scope } : {} },
1461
+ "storage.set.result",
1462
+ () => void 0
1463
+ );
1464
+ },
1465
+ removeItem(key) {
1466
+ return request(
1467
+ { type: "storage.remove", key, ...scope ? { scope } : {} },
1468
+ "storage.remove.result",
1469
+ () => void 0
1470
+ );
1471
+ },
1472
+ keys() {
1473
+ return request(
1474
+ { type: "storage.keys", ...scope ? { scope } : {} },
1475
+ "storage.keys.result",
1476
+ (msg) => Array.isArray(msg.keys) ? msg.keys : []
1477
+ );
1478
+ }
1479
+ });
1480
+ return { ...makeScope(), instance: makeScope("instance") };
1481
+ }
1482
+ function makeIdentity() {
1483
+ const read = (type, field, fallback) => request(
1484
+ { type },
1485
+ `${type}.result`,
1486
+ (msg) => Object.prototype.hasOwnProperty.call(msg, field) ? msg[field] : fallback,
1487
+ { rejectOnError: type !== "identity.getPublicKey" }
1488
+ );
1489
+ return {
1490
+ getPublicKey: () => read("identity.getPublicKey", "pubkey", ""),
1491
+ onChanged(handler) {
1492
+ const off = listen((event) => {
1493
+ if (!isParentMessage(event)) return;
1494
+ const msg = event.data;
1495
+ if (typeof msg !== "object" || msg === null || msg.type !== "identity.changed") return;
1496
+ if (typeof msg.pubkey === "string") handler(msg.pubkey);
1497
+ });
1498
+ return subscriptionHandle(off);
1499
+ },
1500
+ getRelays: () => read("identity.getRelays", "relays", {}),
1501
+ getProfile: () => read("identity.getProfile", "profile", null),
1502
+ getFollows: () => read("identity.getFollows", "pubkeys", []),
1503
+ getList: (listType) => request(
1504
+ { type: "identity.getList", listType },
1505
+ "identity.getList.result",
1506
+ (msg) => Array.isArray(msg.entries) ? msg.entries : []
1507
+ ),
1508
+ getZaps: () => read("identity.getZaps", "zaps", []),
1509
+ getMutes: () => read("identity.getMutes", "pubkeys", []),
1510
+ getBlocked: () => read("identity.getBlocked", "pubkeys", []),
1511
+ getBadges: () => read("identity.getBadges", "badges", [])
1512
+ };
1513
+ }
1514
+ function makeTheme() {
1515
+ return {
1516
+ get: () => request({ type: "theme.get" }, "theme.get.result", (msg) => msg.theme),
1517
+ onChanged(handler) {
1518
+ const off = listen((event) => {
1519
+ if (!isParentMessage(event)) return;
1520
+ const msg = event.data;
1521
+ if (typeof msg === "object" && msg !== null && msg.type === "theme.changed") handler(msg.theme);
1522
+ });
1523
+ return subscriptionHandle(off);
1524
+ }
1525
+ };
1526
+ }
1527
+ function makeKeys() {
1528
+ return {
1529
+ forward: (event = {}) => fire({
1530
+ type: "keys.forward",
1531
+ key: typeof event.key === "string" ? event.key : "",
1532
+ code: typeof event.code === "string" ? event.code : "",
1533
+ ctrl: Boolean(event.ctrl ?? event.ctrlKey),
1534
+ alt: Boolean(event.alt ?? event.altKey),
1535
+ shift: Boolean(event.shift ?? event.shiftKey),
1536
+ meta: Boolean(event.meta ?? event.metaKey)
1537
+ }),
1538
+ registerAction: (action) => request(
1539
+ { type: "keys.registerAction", action },
1540
+ "keys.registerAction.result",
1541
+ resultOrError
1542
+ ),
1543
+ unregisterAction: (actionId) => fire({ type: "keys.unregisterAction", actionId }),
1544
+ onAction(actionId, callback) {
1545
+ const off = listen((event) => {
1546
+ if (!isParentMessage(event)) return;
1547
+ const msg = event.data;
1548
+ if (typeof msg === "object" && msg !== null && msg.type === "keys.action" && msg.actionId === actionId) callback();
1549
+ });
1550
+ return subscriptionHandle(off);
1551
+ }
1552
+ };
1553
+ }
1554
+ function makeMedia() {
1555
+ const on = (type, sessionId, callback) => {
1556
+ const off = listen((event) => {
1557
+ if (!isParentMessage(event)) return;
1558
+ const msg = event.data;
1559
+ if (typeof msg === "object" && msg !== null && msg.type === type && msg.sessionId === sessionId) callback(msg);
1560
+ });
1561
+ return subscriptionHandle(off);
1562
+ };
1563
+ return {
1564
+ createSession: (options) => request(
1565
+ { type: "media.session.create", ...options && typeof options === "object" ? options : {} },
1566
+ "media.session.create.result",
1567
+ withoutEnvelope,
1568
+ { rejectOnError: false }
1569
+ ),
1570
+ updateSession: (sessionId, metadata) => fire({ type: "media.session.update", sessionId, metadata }),
1571
+ destroySession: (sessionId) => fire({ type: "media.session.destroy", sessionId }),
1572
+ reportState: (sessionId, state) => fire({ type: "media.state", sessionId, ...state && typeof state === "object" ? state : {} }),
1573
+ reportCapabilities: (sessionId, actions) => fire({ type: "media.capabilities", sessionId, actions }),
1574
+ sendCommand: (sessionId, action, value) => fire({ type: "media.command", sessionId, action, ...value === void 0 ? {} : { value } }),
1575
+ onCommand: (sessionId, callback) => on("media.command", sessionId, (msg) => callback(msg.action, msg.value)),
1576
+ onState: (sessionId, callback) => on("media.state", sessionId, (msg) => callback({
1577
+ status: msg.status,
1578
+ position: msg.position,
1579
+ duration: msg.duration,
1580
+ volume: msg.volume
1581
+ })),
1582
+ onCapabilities: (sessionId, callback) => on("media.capabilities", sessionId, (msg) => callback(msg.actions)),
1583
+ onControls: (sessionId, callback) => on("media.controls", sessionId, (msg) => callback(msg.controls))
1584
+ };
1585
+ }
1586
+ function makeNotify() {
1587
+ const on = (type, callback) => {
1588
+ const off = listen((event) => {
1589
+ if (!isParentMessage(event)) return;
1590
+ const msg = event.data;
1591
+ if (typeof msg === "object" && msg !== null && msg.type === type) callback(msg);
1592
+ });
1593
+ return subscriptionHandle(off);
1594
+ };
1595
+ return {
1596
+ send: (notification) => request(
1597
+ { type: "notify.send", ...notification },
1598
+ "notify.send.result",
1599
+ (msg) => ({ notificationId: fieldOrThrow(msg, "notificationId", "notify.send.result missing notificationId") })
1600
+ ),
1601
+ dismiss: (notificationId) => fire({ type: "notify.dismiss", notificationId }),
1602
+ badge: (count) => fire({ type: "notify.badge", count }),
1603
+ registerChannel: (channel) => fire({ type: "notify.channel.register", ...channel }),
1604
+ requestPermission: (channel) => request(
1605
+ { type: "notify.permission.request", ...channel ? { channel } : {} },
1606
+ "notify.permission.result",
1607
+ (msg) => ({ granted: msg.granted })
1608
+ ),
1609
+ onAction: (callback) => on("notify.action", (msg) => callback(msg.notificationId, msg.actionId)),
1610
+ onClicked: (callback) => on("notify.clicked", (msg) => callback(msg.notificationId)),
1611
+ onDismissed: (callback) => on("notify.dismissed", (msg) => callback(msg.notificationId, msg.reason)),
1612
+ onControls: (callback) => on("notify.controls", (msg) => callback(msg.controls))
1613
+ };
1614
+ }
1615
+ function makeConfig() {
1616
+ let schema = null;
1617
+ return {
1618
+ registerSchema: (nextSchema, version2) => request(
1619
+ { type: "config.registerSchema", schema: nextSchema, ...version2 === void 0 ? {} : { version: version2 } },
1620
+ "config.registerSchema.result",
1621
+ (msg) => {
1622
+ if (!msg.error) schema = nextSchema;
1623
+ return void 0;
1624
+ }
1625
+ ),
1626
+ get: () => request({ type: "config.get" }, "config.values", (msg) => msg.values ?? {}),
1627
+ subscribe(callback) {
1628
+ const off = listen((event) => {
1629
+ if (!isParentMessage(event)) return;
1630
+ const msg = event.data;
1631
+ if (typeof msg === "object" && msg !== null && msg.type === "config.values") callback(msg.values ?? {});
1632
+ });
1633
+ fire({ type: "config.subscribe" });
1634
+ return subscriptionHandle(() => {
1635
+ fire({ type: "config.unsubscribe" });
1636
+ off();
1637
+ });
1638
+ },
1639
+ openSettings: (options) => fire({ type: "config.openSettings", ...options && typeof options === "object" ? options : {} }),
1640
+ onSchemaError(callback) {
1641
+ const off = listen((event) => {
1642
+ if (!isParentMessage(event)) return;
1643
+ const msg = event.data;
1644
+ if (typeof msg === "object" && msg !== null && msg.type === "config.schemaError") callback(msg);
1645
+ });
1646
+ return off;
1647
+ },
1648
+ get schema() {
1649
+ return schema;
1650
+ }
1651
+ };
1652
+ }
1653
+ function makeResource() {
1654
+ const objectUrls = /* @__PURE__ */ new Set();
1655
+ const bytes = (url) => request({ type: "resource.bytes", url }, "resource.bytes.result", (msg) => msg.blob);
1656
+ return {
1657
+ info: () => request({ type: "resource.info" }, "resource.info.result", (msg) => msg.info),
1658
+ bytes,
1659
+ bytesMany: (urls) => request({ type: "resource.bytesMany", urls }, "resource.bytesMany.result", (msg) => Array.isArray(msg.items) ? msg.items : []),
1660
+ bytesAsObjectURL(url) {
1661
+ let objectUrl = "";
1662
+ const handle = {
1663
+ get url() {
1664
+ return objectUrl;
1665
+ },
1666
+ revoke() {
1667
+ if (objectUrl) {
1668
+ URL.revokeObjectURL(objectUrl);
1669
+ objectUrls.delete(objectUrl);
1670
+ objectUrl = "";
1671
+ }
1672
+ }
1673
+ };
1674
+ void bytes(url).then((blob) => {
1675
+ objectUrl = URL.createObjectURL(blob);
1676
+ objectUrls.add(objectUrl);
1677
+ });
1678
+ return handle;
1679
+ },
1680
+ hydrateResourceCache: () => void 0,
1681
+ revokeAllObjectURLs() {
1682
+ for (const url of objectUrls) URL.revokeObjectURL(url);
1683
+ objectUrls.clear();
1684
+ }
1685
+ };
1686
+ }
1687
+ function makeCvm() {
1688
+ const req = (type, payload, map) => request(
1689
+ { type, ...payload },
1690
+ `${type}.result`,
1691
+ map
1692
+ );
1693
+ const cvmRequest = (server, message, options) => req(
1694
+ "cvm.request",
1695
+ { server, message, ...options === void 0 ? {} : { options } },
1696
+ (msg) => fieldOrThrow(msg, "message", "cvm.request.result missing message")
1697
+ );
1698
+ const mcpCall = async (server, method, params, options) => {
1699
+ const reply = await cvmRequest(server, {
1700
+ jsonrpc: "2.0",
1701
+ id: id(),
1702
+ method,
1703
+ ...params === void 0 ? {} : { params }
1704
+ }, options);
1705
+ if (reply.error !== void 0) {
1706
+ const error = reply.error;
1707
+ throw new Error(typeof error === "object" && error !== null && typeof error.message === "string" ? `${method}: ${error.message}` : `${method} failed`);
1708
+ }
1709
+ return reply.result;
1710
+ };
1711
+ return {
1712
+ discover: (query) => req("cvm.discover", query === void 0 ? {} : { query }, (msg) => Array.isArray(msg.servers) ? msg.servers : []),
1713
+ request: cvmRequest,
1714
+ listTools: async (server, options) => {
1715
+ const result = await mcpCall(server, "tools/list", void 0, options);
1716
+ return result?.tools ?? [];
1717
+ },
1718
+ callTool: (server, name, args, options) => mcpCall(
1719
+ server,
1720
+ "tools/call",
1721
+ { name, ...args === void 0 ? {} : { arguments: args } },
1722
+ options
1723
+ ),
1724
+ listResources: async (server, options) => {
1725
+ const result = await mcpCall(server, "resources/list", void 0, options);
1726
+ return result?.resources ?? [];
1727
+ },
1728
+ readResource: async (server, uri, options) => {
1729
+ const result = await mcpCall(server, "resources/read", { uri }, options);
1730
+ const first = result?.contents?.[0];
1731
+ if (!first) throw new Error(`resources/read returned no contents for ${uri}`);
1732
+ return first;
1733
+ },
1734
+ close: (server) => req("cvm.close", { server }, (msg) => voidResult(msg, "cvm close failed")),
1735
+ onEvent(callback) {
1736
+ const off = listen((event) => {
1737
+ if (!isParentMessage(event)) return;
1738
+ const msg = event.data;
1739
+ if (typeof msg === "object" && msg !== null && msg.type === "cvm.event" && msg.server !== void 0 && msg.message !== void 0) {
1740
+ callback(msg.server, msg.message);
1741
+ }
1742
+ });
1743
+ return subscriptionHandle(off);
1744
+ }
1745
+ };
1746
+ }
1747
+ function makeOutbox() {
1748
+ const req = (type, payload, resultType = `${type}.result`) => request(
1749
+ { type, ...payload },
1750
+ resultType,
1751
+ resultOrError,
1752
+ { rejectOnError: false }
1753
+ );
1754
+ return {
1755
+ getEvent: (eventId, options) => req("outbox.getEvent", { eventId, ...options ? { options } : {} }),
1756
+ query: (filters, options) => req("outbox.query", { filters: Array.isArray(filters) ? filters : [filters], ...options ? { options } : {} }),
1757
+ subscribe(filters, options) {
1758
+ const subId = id();
1759
+ const handlers = { event: /* @__PURE__ */ new Set(), closed: /* @__PURE__ */ new Set() };
1760
+ const off = listen((event) => {
1761
+ if (!isParentMessage(event)) return;
1762
+ const msg = event.data;
1763
+ if (typeof msg !== "object" || msg === null || msg.subId !== subId) return;
1764
+ if (msg.type === "outbox.event") for (const handler of handlers.event) handler(msg.result);
1765
+ if (msg.type === "outbox.closed") {
1766
+ for (const handler of handlers.closed) handler(msg.reason);
1767
+ off();
1768
+ }
1769
+ });
1770
+ fire({ type: "outbox.subscribe", id: id(), subId, filters: Array.isArray(filters) ? filters : [filters], ...options ? { options } : {} });
1771
+ return {
1772
+ on(event, handler) {
1773
+ handlers[event].add(handler);
1774
+ return { close: () => handlers[event].delete(handler) };
1775
+ },
1776
+ close() {
1777
+ fire({ type: "outbox.close", id: id(), subId });
1778
+ off();
1779
+ handlers.event.clear();
1780
+ handlers.closed.clear();
1781
+ }
1782
+ };
1783
+ },
1784
+ publish: (event, options) => req("outbox.publish", { event, ...options ? { options } : {} }),
1785
+ resolveRelays: (targetValue) => req("outbox.resolveRelays", { target: targetValue }).then((msg) => msg.plan ?? msg)
1786
+ };
1787
+ }
1788
+ function makeUpload() {
1789
+ return {
1790
+ info: () => request({ type: "upload.info" }, "upload.info.result", (msg) => fieldOrThrow(msg, "info", "upload info unavailable")),
1791
+ upload: (requestPayload) => request({ type: "upload.upload", request: requestPayload }, "upload.upload.result", (msg) => fieldOrThrow(msg, "result", "upload failed")),
1792
+ status: (uploadId) => request({ type: "upload.status", uploadId }, "upload.status.result", (msg) => fieldOrThrow(msg, "status", "upload status unavailable")),
1793
+ onStatus(callback) {
1794
+ const off = listen((event) => {
1795
+ if (!isParentMessage(event)) return;
1796
+ const msg = event.data;
1797
+ if (typeof msg === "object" && msg !== null && msg.type === "upload.status.changed" && msg.status !== void 0) callback(msg.status);
1798
+ });
1799
+ return subscriptionHandle(off);
1800
+ }
1801
+ };
1802
+ }
1803
+ function makeIntent() {
1804
+ const invoke = (requestPayload) => request(
1805
+ { type: "intent.invoke", request: requestPayload },
1806
+ "intent.invoke.result",
1807
+ (msg) => fieldOrThrow(msg, "result", "intent.invoke.result missing result")
1808
+ );
1809
+ return {
1810
+ invoke,
1811
+ open: (archetype, payload, opts) => invoke({
1812
+ archetype,
1813
+ action: "open",
1814
+ payload,
1815
+ ...opts && typeof opts === "object" ? opts : {}
1816
+ }),
1817
+ available: (archetype) => request(
1818
+ { type: "intent.available", archetype },
1819
+ "intent.available.result",
1820
+ (msg) => fieldOrThrow(msg, "availability", "intent.available.result missing availability")
1821
+ ),
1822
+ handlers: () => request(
1823
+ { type: "intent.handlers" },
1824
+ "intent.handlers.result",
1825
+ (msg) => fieldOrThrow(msg, "handlers", "intent.handlers.result missing handlers")
1826
+ ),
1827
+ onChanged: (callback) => domainEventHandle(
1828
+ "intent.changed",
1829
+ callback,
1830
+ (msg) => msg.availability
1831
+ )
1832
+ };
1833
+ }
1834
+ function makeWebrtc() {
1835
+ return {
1836
+ open: (requestPayload) => request(
1837
+ { type: "webrtc.open", request: requestPayload },
1838
+ "webrtc.open.result",
1839
+ (msg) => ({ session: fieldOrThrow(msg, "session", "webrtc.open.result missing session") })
1840
+ ),
1841
+ send: (sessionId, payload) => request(
1842
+ { type: "webrtc.send", sessionId, payload },
1843
+ "webrtc.send.result",
1844
+ (msg) => voidResult(msg, "webrtc send failed")
1845
+ ),
1846
+ close: (sessionId, reason) => request(
1847
+ { type: "webrtc.close", sessionId, ...reason ? { reason } : {} },
1848
+ "webrtc.close.result",
1849
+ (msg) => voidResult(msg, "webrtc close failed")
1850
+ ),
1851
+ onEvent: (callback) => domainEventHandle("webrtc.event", callback)
1852
+ };
1853
+ }
1854
+ function makeBle() {
1855
+ const req = (action, payload, map) => request(
1856
+ { type: `ble.${action}`, ...payload },
1857
+ `ble.${action}.result`,
1858
+ map
1859
+ );
1860
+ return {
1861
+ open: (requestPayload) => req("open", { request: requestPayload }, (msg) => ({ session: fieldOrThrow(msg, "session", "ble.open.result missing session") })),
1862
+ services: (sessionId) => req("services", { sessionId }, (msg) => fieldOrThrow(msg, "services", "ble.services.result missing services")),
1863
+ read: (sessionId, targetValue) => req("read", { sessionId, target: targetValue }, (msg) => fieldOrThrow(msg, "data", "ble.read.result missing data")),
1864
+ write: (sessionId, targetValue, data, options) => req(
1865
+ "write",
1866
+ { sessionId, target: targetValue, data, ...options ? { options } : {} },
1867
+ (msg) => voidResult(msg, "ble write failed")
1868
+ ),
1869
+ subscribe: (sessionId, targetValue) => req("subscribe", { sessionId, target: targetValue }, (msg) => voidResult(msg, "ble subscribe failed")),
1870
+ unsubscribe: (sessionId, targetValue) => req("unsubscribe", { sessionId, target: targetValue }, (msg) => voidResult(msg, "ble unsubscribe failed")),
1871
+ close: (sessionId, reason) => req("close", { sessionId, ...reason ? { reason } : {} }, (msg) => voidResult(msg, "ble close failed")),
1872
+ onEvent: (callback) => domainEventHandle("ble.event", callback)
1873
+ };
1874
+ }
1875
+ function makeSerial() {
1876
+ return {
1877
+ open: (requestPayload) => request(
1878
+ { type: "serial.open", request: requestPayload },
1879
+ "serial.open.result",
1880
+ (msg) => ({ session: fieldOrThrow(msg, "session", "serial.open.result missing session") })
1881
+ ),
1882
+ write: (sessionId, data) => request(
1883
+ { type: "serial.write", sessionId, data: Array.from(data) },
1884
+ "serial.write.result",
1885
+ (msg) => voidResult(msg, "serial write failed")
1886
+ ),
1887
+ close: (sessionId, reason) => request(
1888
+ { type: "serial.close", sessionId, ...reason === void 0 ? {} : { reason } },
1889
+ "serial.close.result",
1890
+ (msg) => voidResult(msg, "serial close failed")
1891
+ ),
1892
+ onEvent: (callback) => domainEventHandle("serial.event", callback)
1893
+ };
1894
+ }
1895
+ function makeLink() {
1896
+ return {
1897
+ open: (url, options) => request(
1898
+ { type: "link.open", url, ...options ? { options } : {} },
1899
+ "link.open.result",
1900
+ resultOrError,
1901
+ { rejectOnError: false }
1902
+ )
1903
+ };
1904
+ }
1905
+ function makeCount() {
1906
+ return {
1907
+ query: (filters, options) => request(
1908
+ { type: "count.query", filters: Array.isArray(filters) ? filters : [filters], ...options ? { options } : {} },
1909
+ "count.query.result",
1910
+ resultOrError,
1911
+ { rejectOnError: false }
1912
+ )
1913
+ };
1914
+ }
1915
+ function makeLists() {
1916
+ const req = (type, payload) => request({ type, ...payload }, `${type}.result`, resultOrError, { rejectOnError: false });
1917
+ return {
1918
+ supported: () => req("lists.supported", {}),
1919
+ add: (list, items, options) => req("lists.add", { list, items, ...options ? { options } : {} }),
1920
+ remove: (list, items, options) => req("lists.remove", { list, items, ...options ? { options } : {} })
1921
+ };
1922
+ }
1923
+ function makeCommon() {
1924
+ const req = (type, payload) => request({ type, ...payload }, `${type}.result`, withoutEnvelope, { rejectOnError: false });
1925
+ return {
1926
+ encodeNip19: (input) => req("common.encodeNip19", { input }),
1927
+ decodeNip19: (value) => req("common.decodeNip19", { value }),
1928
+ getProfile: (targetValue) => req("common.getProfile", { target: targetValue }),
1929
+ follows: () => req("common.follows", {}),
1930
+ follow: (...pubkeys) => req("common.follow", { pubkeys }),
1931
+ unfollow: (...pubkeys) => req("common.unfollow", { pubkeys }),
1932
+ react: (targetEventId, reaction, customEmojiHref) => req("common.react", {
1933
+ targetEventId,
1934
+ reaction,
1935
+ ...customEmojiHref === void 0 ? {} : { customEmojiHref }
1936
+ }),
1937
+ report: (targetValue, reason, text) => req("common.report", {
1938
+ target: targetValue,
1939
+ reason,
1940
+ text
1941
+ })
1942
+ };
1943
+ }
1944
+ function makeDm() {
1945
+ const req = (type, payload) => request({ type, ...payload }, `${type}.result`, withoutEnvelope, { rejectOnError: false });
1946
+ return {
1947
+ status: () => req("dm.status", {}),
1948
+ conversations: (query) => req("dm.conversations", query ?? {}),
1949
+ messages: (query) => req("dm.messages", query ?? {}),
1950
+ send: (requestPayload) => req("dm.send", requestPayload ?? {}),
1951
+ subscribe: (requestPayload) => req("dm.subscribe", requestPayload ?? {}),
1952
+ unsubscribe: (subscriptionId) => req("dm.unsubscribe", { subscriptionId }),
1953
+ onMessage(callback) {
1954
+ const off = listen((event) => {
1955
+ if (!isParentMessage(event)) return;
1956
+ const msg = event.data;
1957
+ if (typeof msg === "object" && msg !== null && msg.type === "dm.message" && typeof msg.subscriptionId === "string") {
1958
+ callback(msg.message, msg.subscriptionId);
1959
+ }
1960
+ });
1961
+ return subscriptionHandle(off);
1962
+ }
1963
+ };
1964
+ }
1965
+ function makeDomain(domain, existing) {
1966
+ if (existing && typeof existing === "object" && Object.keys(existing).length > 0) return existing;
1967
+ switch (domain) {
1968
+ case "relay":
1969
+ return makeRelay();
1970
+ case "inc":
1971
+ return makeInc();
1972
+ case "storage":
1973
+ return makeStorage();
1974
+ case "keys":
1975
+ return makeKeys();
1976
+ case "media":
1977
+ return makeMedia();
1978
+ case "notify":
1979
+ return makeNotify();
1980
+ case "identity":
1981
+ return makeIdentity();
1982
+ case "theme":
1983
+ return makeTheme();
1984
+ case "config":
1985
+ return makeConfig();
1986
+ case "resource":
1987
+ return makeResource();
1988
+ case "cvm":
1989
+ return makeCvm();
1990
+ case "outbox":
1991
+ return makeOutbox();
1992
+ case "upload":
1993
+ return makeUpload();
1994
+ case "intent":
1995
+ return makeIntent();
1996
+ case "webrtc":
1997
+ return makeWebrtc();
1998
+ case "ble":
1999
+ return makeBle();
2000
+ case "link":
2001
+ return makeLink();
2002
+ case "count":
2003
+ return makeCount();
2004
+ case "lists":
2005
+ return makeLists();
2006
+ case "common":
2007
+ return makeCommon();
2008
+ case "serial":
2009
+ return makeSerial();
2010
+ case "dm":
2011
+ return makeDm();
2012
+ default:
2013
+ return {};
2014
+ }
2015
+ }
2016
+ function guardNappletNamespace(namespace) {
2017
+ return new Proxy(namespace, {
2018
+ set(obj, prop, value) {
2019
+ if (typeof prop !== "string" || !allowed.has(prop)) return true;
2020
+ obj[prop] = makeDomain(prop, value);
2021
+ return true;
2022
+ },
2023
+ defineProperty(obj, prop, descriptor) {
2024
+ if (typeof prop !== "string" || !allowed.has(prop)) return true;
2025
+ return Reflect.defineProperty(obj, prop, {
2026
+ ...descriptor,
2027
+ value: makeDomain(prop, descriptor.value)
2028
+ });
2029
+ }
2030
+ });
2031
+ }
1278
2032
  function buildNappletNamespace(value) {
1279
2033
  const candidate = typeof value === "object" && value !== null ? value : {};
1280
2034
  const next = {};
1281
2035
  for (const domain of domains) {
2036
+ if (!allowed.has(domain)) continue;
1282
2037
  Object.defineProperty(next, domain, {
1283
- value: Object.prototype.hasOwnProperty.call(candidate, domain) ? candidate[domain] : {},
2038
+ value: makeDomain(
2039
+ domain,
2040
+ Object.prototype.hasOwnProperty.call(candidate, domain) ? candidate[domain] : void 0
2041
+ ),
1284
2042
  enumerable: true,
1285
2043
  configurable: true,
1286
2044
  writable: true
1287
2045
  });
1288
2046
  }
1289
- return next;
2047
+ return guardNappletNamespace(next);
1290
2048
  }
1291
2049
  let root = buildNappletNamespace(target.napplet);
1292
2050
  Object.defineProperty(target, "napplet", {