space-data-module-sdk 0.6.0 → 0.6.1
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 +15 -2
- package/package.json +1 -1
- package/schemas/orbpro/BaseTypes.fbs +7 -0
- package/schemas/orbpro/CatalogQueryBase.fbs +8 -0
- package/schemas/orbpro/CatalogQueryRequest.fbs +14 -0
- package/schemas/orbpro/CatalogQueryResult.fbs +17 -0
- package/schemas/orbpro/EntityMetadata.fbs +53 -0
- package/schemas/orbpro/EntityStandardsLink.fbs +18 -0
- package/schemas/orbpro/Plugin.fbs +8 -0
- package/schemas/orbpro/Propagator.fbs +89 -0
- package/schemas/orbpro/StandardsRecordIndex.fbs +15 -0
- package/src/generated/orbpro/entity/entity-kind.js +15 -0
- package/src/generated/orbpro/entity/entity-kind.ts +15 -0
- package/src/generated/orbpro/entity/entity-metadata.js +322 -0
- package/src/generated/orbpro/entity/entity-metadata.ts +426 -0
- package/src/generated/orbpro/entity/entity-standards-link.js +143 -0
- package/src/generated/orbpro/entity/entity-standards-link.ts +183 -0
- package/src/generated/orbpro/entity/standards-record-index.js +115 -0
- package/src/generated/orbpro/entity/standards-record-index.ts +147 -0
- package/src/generated/orbpro/entity.js +10 -0
- package/src/generated/orbpro/entity.ts +5 -0
- package/src/generated/orbpro/plugin/raw-data-payload.js +79 -0
- package/src/generated/orbpro/plugin/raw-data-payload.ts +92 -0
- package/src/generated/orbpro/plugin.js +4 -0
- package/src/generated/orbpro/plugin.ts +5 -0
- package/src/generated/orbpro/propagator/propagator-describe-sources-batch-request.js +79 -0
- package/src/generated/orbpro/propagator/propagator-describe-sources-batch-request.ts +95 -0
- package/src/generated/orbpro/propagator/propagator-describe-sources-batch-result.js +70 -0
- package/src/generated/orbpro/propagator/propagator-describe-sources-batch-result.ts +78 -0
- package/src/generated/orbpro/propagator/propagator-sample-trajectory-states-request.js +97 -0
- package/src/generated/orbpro/propagator/propagator-sample-trajectory-states-request.ts +117 -0
- package/src/generated/orbpro/propagator/propagator-sample-trajectory-states-result.js +140 -0
- package/src/generated/orbpro/propagator/propagator-sample-trajectory-states-result.ts +175 -0
- package/src/generated/orbpro/propagator/propagator-source-description.js +208 -0
- package/src/generated/orbpro/propagator/propagator-source-description.ts +257 -0
- package/src/generated/orbpro/propagator/propagator-source-kind.js +8 -0
- package/src/generated/orbpro/propagator/propagator-source-kind.ts +8 -0
- package/src/generated/orbpro/propagator/reference-frame.js +12 -0
- package/src/generated/orbpro/propagator/reference-frame.ts +12 -0
- package/src/generated/orbpro/propagator/state-flags.js +13 -0
- package/src/generated/orbpro/propagator/state-flags.ts +13 -0
- package/src/generated/orbpro/propagator/state-vector.js +55 -0
- package/src/generated/orbpro/propagator/state-vector.ts +61 -0
- package/src/generated/orbpro/propagator.js +20 -0
- package/src/generated/orbpro/propagator.ts +13 -0
- package/src/generated/orbpro/query/catalog-query-kind.js +10 -0
- package/src/generated/orbpro/query/catalog-query-kind.ts +10 -0
- package/src/generated/orbpro/query/catalog-query-request.js +89 -0
- package/src/generated/orbpro/query/catalog-query-request.ts +105 -0
- package/src/generated/orbpro/query/catalog-query-result.js +145 -0
- package/src/generated/orbpro/query/catalog-query-result.ts +179 -0
- package/src/generated/orbpro/query.js +8 -0
- package/src/generated/orbpro/query.ts +4 -0
- package/src/generated/orbpro/vec3.js +39 -0
- package/src/generated/orbpro/vec3.ts +40 -0
- package/src/host/abi.js +158 -0
- package/src/host/browserEdgeShims.js +17 -4
- package/src/host/browserHost.js +260 -48
- package/src/host/isomorphicLoader.js +3 -2
- package/src/host/nodeHost.js +168 -71
- package/src/index.d.ts +99 -3
- package/src/runtime-host/index.js +34 -0
- package/src/testing/browserModuleHarness.js +16 -3
- package/src/testing/index.d.ts +1 -0
- package/src/testing/index.js +5 -4
package/src/host/nodeHost.js
CHANGED
|
@@ -63,6 +63,7 @@ export const NodeHostSupportedCapabilities = Object.freeze([
|
|
|
63
63
|
"crypto_decrypt",
|
|
64
64
|
"crypto_key_agreement",
|
|
65
65
|
"crypto_kdf",
|
|
66
|
+
"wallet_sign",
|
|
66
67
|
"process_exec",
|
|
67
68
|
]);
|
|
68
69
|
|
|
@@ -93,9 +94,13 @@ export const NodeHostSupportedOperations = Object.freeze([
|
|
|
93
94
|
"udp.request",
|
|
94
95
|
"tls.request",
|
|
95
96
|
"ipfs.invoke",
|
|
97
|
+
"ipfs.add",
|
|
98
|
+
"ipfs.cat",
|
|
96
99
|
"protocol_handle.register",
|
|
97
100
|
"protocol_handle.unregister",
|
|
98
101
|
"protocol_dial.dial",
|
|
102
|
+
"protocol.request",
|
|
103
|
+
"keyslot.get",
|
|
99
104
|
"exec.execFile",
|
|
100
105
|
"context.get",
|
|
101
106
|
"context.set",
|
|
@@ -160,6 +165,34 @@ function normalizeGrantedCapabilities(options) {
|
|
|
160
165
|
return normalized;
|
|
161
166
|
}
|
|
162
167
|
|
|
168
|
+
function resolveCapabilityAdapters(options = {}) {
|
|
169
|
+
const adapters =
|
|
170
|
+
options.capabilityAdapters && typeof options.capabilityAdapters === "object"
|
|
171
|
+
? options.capabilityAdapters
|
|
172
|
+
: {};
|
|
173
|
+
return {
|
|
174
|
+
filesystem: options.filesystem ?? adapters.filesystem ?? null,
|
|
175
|
+
network: options.network ?? adapters.network ?? null,
|
|
176
|
+
ipfs: options.ipfs ?? adapters.ipfs ?? null,
|
|
177
|
+
walletSign:
|
|
178
|
+
options.walletSign ??
|
|
179
|
+
adapters.walletSign ??
|
|
180
|
+
adapters.wallet_sign ??
|
|
181
|
+
adapters.keyslot ??
|
|
182
|
+
null,
|
|
183
|
+
protocolHandle:
|
|
184
|
+
options.protocolHandle ??
|
|
185
|
+
adapters.protocolHandle ??
|
|
186
|
+
adapters.protocol_handle ??
|
|
187
|
+
null,
|
|
188
|
+
protocolDial:
|
|
189
|
+
options.protocolDial ??
|
|
190
|
+
adapters.protocolDial ??
|
|
191
|
+
adapters.protocol_dial ??
|
|
192
|
+
null,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
163
196
|
function normalizeAllowedOrigins(origins) {
|
|
164
197
|
if (origins === undefined || origins === null) {
|
|
165
198
|
return null;
|
|
@@ -1445,10 +1478,13 @@ export class NodeHost {
|
|
|
1445
1478
|
);
|
|
1446
1479
|
this.fetch = options.fetch ?? globalThis.fetch;
|
|
1447
1480
|
this.WebSocket = options.WebSocket ?? globalThis.WebSocket;
|
|
1448
|
-
|
|
1449
|
-
this.
|
|
1450
|
-
this.
|
|
1451
|
-
this.
|
|
1481
|
+
const capabilityAdapters = resolveCapabilityAdapters(options);
|
|
1482
|
+
this._filesystemAdapter = capabilityAdapters.filesystem;
|
|
1483
|
+
this._networkAdapter = capabilityAdapters.network;
|
|
1484
|
+
this._ipfsAdapter = capabilityAdapters.ipfs;
|
|
1485
|
+
this._walletSignAdapter = capabilityAdapters.walletSign;
|
|
1486
|
+
this._protocolHandleAdapter = capabilityAdapters.protocolHandle;
|
|
1487
|
+
this._protocolDialAdapter = capabilityAdapters.protocolDial;
|
|
1452
1488
|
if (typeof this.fetch !== "function") {
|
|
1453
1489
|
throw new TypeError(
|
|
1454
1490
|
"A fetch implementation is required to create a Node host.",
|
|
@@ -1607,6 +1643,12 @@ export class NodeHost {
|
|
|
1607
1643
|
this.#withCapability("network", "network.request", async () => {
|
|
1608
1644
|
const transport = normalizeNetworkTransport(params);
|
|
1609
1645
|
const request = params.request ?? params;
|
|
1646
|
+
if (this._networkAdapter) {
|
|
1647
|
+
return invokeAdapterMethod(this._networkAdapter, "request", {
|
|
1648
|
+
...request,
|
|
1649
|
+
transport,
|
|
1650
|
+
}, "network");
|
|
1651
|
+
}
|
|
1610
1652
|
switch (transport) {
|
|
1611
1653
|
case "http":
|
|
1612
1654
|
return this.http.request(request);
|
|
@@ -1623,12 +1665,6 @@ export class NodeHost {
|
|
|
1623
1665
|
case "tls":
|
|
1624
1666
|
return this.tls.request(request);
|
|
1625
1667
|
default:
|
|
1626
|
-
if (this._networkAdapter) {
|
|
1627
|
-
return invokeAdapterMethod(this._networkAdapter, "request", {
|
|
1628
|
-
...request,
|
|
1629
|
-
transport,
|
|
1630
|
-
}, "network");
|
|
1631
|
-
}
|
|
1632
1668
|
throw new Error(
|
|
1633
1669
|
`Node host does not support network transport "${transport}".`,
|
|
1634
1670
|
);
|
|
@@ -1636,6 +1672,87 @@ export class NodeHost {
|
|
|
1636
1672
|
}),
|
|
1637
1673
|
});
|
|
1638
1674
|
|
|
1675
|
+
const builtinFilesystem = {
|
|
1676
|
+
resolvePath: (targetPath) => this.#resolveFilesystemPath(targetPath),
|
|
1677
|
+
readFile: async (targetPath, options = {}) => {
|
|
1678
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1679
|
+
const file = await readFile(resolvedPath);
|
|
1680
|
+
if (options.encoding) {
|
|
1681
|
+
return file.toString(options.encoding);
|
|
1682
|
+
}
|
|
1683
|
+
return new Uint8Array(file);
|
|
1684
|
+
},
|
|
1685
|
+
writeFile: async (targetPath, value, options = {}) => {
|
|
1686
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1687
|
+
await mkdir(path.dirname(resolvedPath), { recursive: true });
|
|
1688
|
+
await writeFile(
|
|
1689
|
+
resolvedPath,
|
|
1690
|
+
typeof value === "string" ? value : Buffer.from(toUint8Array(value)),
|
|
1691
|
+
options.encoding && typeof value === "string" ? options.encoding : undefined,
|
|
1692
|
+
);
|
|
1693
|
+
return { path: resolvedPath };
|
|
1694
|
+
},
|
|
1695
|
+
appendFile: async (targetPath, value, options = {}) => {
|
|
1696
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1697
|
+
await mkdir(path.dirname(resolvedPath), { recursive: true });
|
|
1698
|
+
const existing = await readFile(resolvedPath).catch((error) => {
|
|
1699
|
+
if (error?.code === "ENOENT") {
|
|
1700
|
+
return Buffer.alloc(0);
|
|
1701
|
+
}
|
|
1702
|
+
throw error;
|
|
1703
|
+
});
|
|
1704
|
+
const nextChunk =
|
|
1705
|
+
typeof value === "string"
|
|
1706
|
+
? Buffer.from(value, options.encoding ?? "utf8")
|
|
1707
|
+
: Buffer.from(toUint8Array(value));
|
|
1708
|
+
await writeFile(resolvedPath, Buffer.concat([existing, nextChunk]));
|
|
1709
|
+
return { path: resolvedPath };
|
|
1710
|
+
},
|
|
1711
|
+
deleteFile: async (targetPath) => {
|
|
1712
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1713
|
+
await rm(resolvedPath, { force: true });
|
|
1714
|
+
return { path: resolvedPath };
|
|
1715
|
+
},
|
|
1716
|
+
mkdir: async (targetPath, options = {}) => {
|
|
1717
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1718
|
+
await mkdir(resolvedPath, {
|
|
1719
|
+
recursive: options.recursive ?? true,
|
|
1720
|
+
});
|
|
1721
|
+
return { path: resolvedPath };
|
|
1722
|
+
},
|
|
1723
|
+
readdir: async (targetPath = ".") => {
|
|
1724
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1725
|
+
const entries = await readdir(resolvedPath, { withFileTypes: true });
|
|
1726
|
+
return entries
|
|
1727
|
+
.map((entry) => ({
|
|
1728
|
+
name: entry.name,
|
|
1729
|
+
isFile: entry.isFile(),
|
|
1730
|
+
isDirectory: entry.isDirectory(),
|
|
1731
|
+
}))
|
|
1732
|
+
.sort((left, right) => left.name.localeCompare(right.name));
|
|
1733
|
+
},
|
|
1734
|
+
stat: async (targetPath) => {
|
|
1735
|
+
const resolvedPath = this.#resolveFilesystemPath(targetPath);
|
|
1736
|
+
const metadata = await stat(resolvedPath);
|
|
1737
|
+
return {
|
|
1738
|
+
path: resolvedPath,
|
|
1739
|
+
size: metadata.size,
|
|
1740
|
+
isFile: metadata.isFile(),
|
|
1741
|
+
isDirectory: metadata.isDirectory(),
|
|
1742
|
+
ctimeMs: metadata.ctimeMs,
|
|
1743
|
+
mtimeMs: metadata.mtimeMs,
|
|
1744
|
+
};
|
|
1745
|
+
},
|
|
1746
|
+
rename: async (fromPath, toPath) => {
|
|
1747
|
+
const resolvedFrom = this.#resolveFilesystemPath(fromPath);
|
|
1748
|
+
const resolvedTo = this.#resolveFilesystemPath(toPath);
|
|
1749
|
+
await mkdir(path.dirname(resolvedTo), { recursive: true });
|
|
1750
|
+
await rename(resolvedFrom, resolvedTo);
|
|
1751
|
+
return { from: resolvedFrom, to: resolvedTo };
|
|
1752
|
+
},
|
|
1753
|
+
};
|
|
1754
|
+
const filesystem = this._filesystemAdapter ?? builtinFilesystem;
|
|
1755
|
+
|
|
1639
1756
|
this.mqtt = Object.freeze({
|
|
1640
1757
|
publish: async (mqttOptions = {}) =>
|
|
1641
1758
|
this.#withCapability("mqtt", "mqtt.publish", async () => {
|
|
@@ -1687,91 +1804,39 @@ export class NodeHost {
|
|
|
1687
1804
|
this.filesystem = Object.freeze({
|
|
1688
1805
|
resolvePath: (targetPath) =>
|
|
1689
1806
|
this.#withCapability("filesystem", "filesystem.resolvePath", () =>
|
|
1690
|
-
|
|
1807
|
+
filesystem.resolvePath(targetPath),
|
|
1691
1808
|
),
|
|
1692
1809
|
readFile: async (targetPath, options = {}) =>
|
|
1693
1810
|
this.#withCapability("filesystem", "filesystem.readFile", async () => {
|
|
1694
|
-
|
|
1695
|
-
const file = await readFile(resolvedPath);
|
|
1696
|
-
if (options.encoding) {
|
|
1697
|
-
return file.toString(options.encoding);
|
|
1698
|
-
}
|
|
1699
|
-
return new Uint8Array(file);
|
|
1811
|
+
return filesystem.readFile(targetPath, options);
|
|
1700
1812
|
}),
|
|
1701
1813
|
writeFile: async (targetPath, value, options = {}) =>
|
|
1702
1814
|
this.#withCapability("filesystem", "filesystem.writeFile", async () => {
|
|
1703
|
-
|
|
1704
|
-
await mkdir(path.dirname(resolvedPath), { recursive: true });
|
|
1705
|
-
await writeFile(
|
|
1706
|
-
resolvedPath,
|
|
1707
|
-
typeof value === "string" ? value : Buffer.from(toUint8Array(value)),
|
|
1708
|
-
options.encoding && typeof value === "string" ? options.encoding : undefined,
|
|
1709
|
-
);
|
|
1710
|
-
return { path: resolvedPath };
|
|
1815
|
+
return filesystem.writeFile(targetPath, value, options);
|
|
1711
1816
|
}),
|
|
1712
1817
|
appendFile: async (targetPath, value, options = {}) =>
|
|
1713
1818
|
this.#withCapability("filesystem", "filesystem.appendFile", async () => {
|
|
1714
|
-
|
|
1715
|
-
await mkdir(path.dirname(resolvedPath), { recursive: true });
|
|
1716
|
-
const existing = await readFile(resolvedPath).catch((error) => {
|
|
1717
|
-
if (error?.code === "ENOENT") {
|
|
1718
|
-
return Buffer.alloc(0);
|
|
1719
|
-
}
|
|
1720
|
-
throw error;
|
|
1721
|
-
});
|
|
1722
|
-
const nextChunk =
|
|
1723
|
-
typeof value === "string"
|
|
1724
|
-
? Buffer.from(value, options.encoding ?? "utf8")
|
|
1725
|
-
: Buffer.from(toUint8Array(value));
|
|
1726
|
-
await writeFile(resolvedPath, Buffer.concat([existing, nextChunk]));
|
|
1727
|
-
return { path: resolvedPath };
|
|
1819
|
+
return filesystem.appendFile(targetPath, value, options);
|
|
1728
1820
|
}),
|
|
1729
1821
|
deleteFile: async (targetPath) =>
|
|
1730
1822
|
this.#withCapability("filesystem", "filesystem.deleteFile", async () => {
|
|
1731
|
-
|
|
1732
|
-
await rm(resolvedPath, { force: true });
|
|
1733
|
-
return { path: resolvedPath };
|
|
1823
|
+
return filesystem.deleteFile(targetPath);
|
|
1734
1824
|
}),
|
|
1735
1825
|
mkdir: async (targetPath, options = {}) =>
|
|
1736
1826
|
this.#withCapability("filesystem", "filesystem.mkdir", async () => {
|
|
1737
|
-
|
|
1738
|
-
await mkdir(resolvedPath, {
|
|
1739
|
-
recursive: options.recursive ?? true,
|
|
1740
|
-
});
|
|
1741
|
-
return { path: resolvedPath };
|
|
1827
|
+
return filesystem.mkdir(targetPath, options);
|
|
1742
1828
|
}),
|
|
1743
1829
|
readdir: async (targetPath = ".") =>
|
|
1744
1830
|
this.#withCapability("filesystem", "filesystem.readdir", async () => {
|
|
1745
|
-
|
|
1746
|
-
const entries = await readdir(resolvedPath, { withFileTypes: true });
|
|
1747
|
-
return entries
|
|
1748
|
-
.map((entry) => ({
|
|
1749
|
-
name: entry.name,
|
|
1750
|
-
isFile: entry.isFile(),
|
|
1751
|
-
isDirectory: entry.isDirectory(),
|
|
1752
|
-
}))
|
|
1753
|
-
.sort((left, right) => left.name.localeCompare(right.name));
|
|
1831
|
+
return filesystem.readdir(targetPath);
|
|
1754
1832
|
}),
|
|
1755
1833
|
stat: async (targetPath) =>
|
|
1756
1834
|
this.#withCapability("filesystem", "filesystem.stat", async () => {
|
|
1757
|
-
|
|
1758
|
-
const metadata = await stat(resolvedPath);
|
|
1759
|
-
return {
|
|
1760
|
-
path: resolvedPath,
|
|
1761
|
-
size: metadata.size,
|
|
1762
|
-
isFile: metadata.isFile(),
|
|
1763
|
-
isDirectory: metadata.isDirectory(),
|
|
1764
|
-
ctimeMs: metadata.ctimeMs,
|
|
1765
|
-
mtimeMs: metadata.mtimeMs,
|
|
1766
|
-
};
|
|
1835
|
+
return filesystem.stat(targetPath);
|
|
1767
1836
|
}),
|
|
1768
1837
|
rename: async (fromPath, toPath) =>
|
|
1769
1838
|
this.#withCapability("filesystem", "filesystem.rename", async () => {
|
|
1770
|
-
|
|
1771
|
-
const resolvedTo = this.#resolveFilesystemPath(toPath);
|
|
1772
|
-
await mkdir(path.dirname(resolvedTo), { recursive: true });
|
|
1773
|
-
await rename(resolvedFrom, resolvedTo);
|
|
1774
|
-
return { from: resolvedFrom, to: resolvedTo };
|
|
1839
|
+
return filesystem.rename(fromPath, toPath);
|
|
1775
1840
|
}),
|
|
1776
1841
|
});
|
|
1777
1842
|
|
|
@@ -1921,6 +1986,14 @@ export class NodeHost {
|
|
|
1921
1986
|
}
|
|
1922
1987
|
return invokeAdapterMethod(this._ipfsAdapter, operation, params, "ipfs");
|
|
1923
1988
|
}),
|
|
1989
|
+
add: async (params = {}) =>
|
|
1990
|
+
this.#withCapability("ipfs", "ipfs.add", async () =>
|
|
1991
|
+
invokeAdapterMethod(this._ipfsAdapter, "add", params, "ipfs"),
|
|
1992
|
+
),
|
|
1993
|
+
cat: async (params = {}) =>
|
|
1994
|
+
this.#withCapability("ipfs", "ipfs.cat", async () =>
|
|
1995
|
+
invokeAdapterMethod(this._ipfsAdapter, "cat", params, "ipfs"),
|
|
1996
|
+
),
|
|
1924
1997
|
});
|
|
1925
1998
|
|
|
1926
1999
|
this.protocolHandle = Object.freeze({
|
|
@@ -1960,6 +2033,22 @@ export class NodeHost {
|
|
|
1960
2033
|
"protocol_dial",
|
|
1961
2034
|
),
|
|
1962
2035
|
),
|
|
2036
|
+
request: async (params = {}) =>
|
|
2037
|
+
this.#withCapability("protocol_dial", "protocol.request", async () =>
|
|
2038
|
+
invokeAdapterMethod(
|
|
2039
|
+
this._protocolDialAdapter,
|
|
2040
|
+
"request",
|
|
2041
|
+
params,
|
|
2042
|
+
"protocol_dial",
|
|
2043
|
+
),
|
|
2044
|
+
),
|
|
2045
|
+
});
|
|
2046
|
+
|
|
2047
|
+
this.keyslot = Object.freeze({
|
|
2048
|
+
get: async (params = {}) =>
|
|
2049
|
+
this.#withCapability("wallet_sign", "keyslot.get", async () =>
|
|
2050
|
+
invokeAdapterMethod(this._walletSignAdapter, "get", params, "wallet_sign"),
|
|
2051
|
+
),
|
|
1963
2052
|
});
|
|
1964
2053
|
}
|
|
1965
2054
|
|
|
@@ -2100,12 +2189,20 @@ export class NodeHost {
|
|
|
2100
2189
|
return this.tls.request(params);
|
|
2101
2190
|
case "ipfs.invoke":
|
|
2102
2191
|
return this.ipfs.invoke(params);
|
|
2192
|
+
case "ipfs.add":
|
|
2193
|
+
return this.ipfs.add(params);
|
|
2194
|
+
case "ipfs.cat":
|
|
2195
|
+
return this.ipfs.cat(params);
|
|
2103
2196
|
case "protocol_handle.register":
|
|
2104
2197
|
return this.protocolHandle.register(params);
|
|
2105
2198
|
case "protocol_handle.unregister":
|
|
2106
2199
|
return this.protocolHandle.unregister(params);
|
|
2107
2200
|
case "protocol_dial.dial":
|
|
2108
2201
|
return this.protocolDial.dial(params);
|
|
2202
|
+
case "protocol.request":
|
|
2203
|
+
return this.protocolDial.request(params);
|
|
2204
|
+
case "keyslot.get":
|
|
2205
|
+
return this.keyslot.get(params);
|
|
2109
2206
|
case "exec.execFile":
|
|
2110
2207
|
return this.exec.execFile(params);
|
|
2111
2208
|
case "context.get":
|
package/src/index.d.ts
CHANGED
|
@@ -409,6 +409,18 @@ export interface RuntimeHost {
|
|
|
409
409
|
rows: FlatSqlRuntimeStore;
|
|
410
410
|
regions: RuntimeRegionStore;
|
|
411
411
|
moduleRegistry: RuntimeModuleRegistry;
|
|
412
|
+
listCapabilities(): string[];
|
|
413
|
+
listSupportedCapabilities(): string[];
|
|
414
|
+
listOperations(): string[];
|
|
415
|
+
hasCapability(capability: string): boolean;
|
|
416
|
+
getCapability(capability: string): Record<string, (...args: any[]) => unknown> | null;
|
|
417
|
+
registerCapability(
|
|
418
|
+
capability: string,
|
|
419
|
+
adapter: Record<string, (...args: any[]) => unknown>,
|
|
420
|
+
): Record<string, (...args: any[]) => unknown>;
|
|
421
|
+
unregisterCapability(capability: string): boolean;
|
|
422
|
+
invokeCapability(operation: string, params?: Record<string, any>): Promise<unknown>;
|
|
423
|
+
invoke(operation: string, params?: Record<string, any>): Promise<unknown>;
|
|
412
424
|
}
|
|
413
425
|
|
|
414
426
|
export function createFlatBufferStreamIngestor(options?: {
|
|
@@ -1117,13 +1129,21 @@ export interface BrowserEdgeShims {
|
|
|
1117
1129
|
now(): number;
|
|
1118
1130
|
timeOrigin: number;
|
|
1119
1131
|
};
|
|
1132
|
+
network?: Record<string, (...args: any[]) => unknown> | null;
|
|
1133
|
+
ipfs?: Record<string, (...args: any[]) => unknown> | null;
|
|
1134
|
+
walletSign?: Record<string, (...args: any[]) => unknown> | null;
|
|
1135
|
+
protocolHandle?: Record<string, (...args: any[]) => unknown> | null;
|
|
1136
|
+
protocolDial?: Record<string, (...args: any[]) => unknown> | null;
|
|
1120
1137
|
filesystem?: BrowserFilesystemShim;
|
|
1138
|
+
filesystemRoot?: string;
|
|
1139
|
+
capabilityAdapters?: Record<string, Record<string, (...args: any[]) => unknown>>;
|
|
1121
1140
|
}
|
|
1122
1141
|
|
|
1123
1142
|
export interface BrowserHostOptions {
|
|
1124
1143
|
capabilities?: string[];
|
|
1125
1144
|
edgeShims?: BrowserEdgeShims;
|
|
1126
1145
|
contextStore?: Map<string, Map<string, unknown>>;
|
|
1146
|
+
wasmWallet?: unknown;
|
|
1127
1147
|
fetch?: (...args: any[]) => Promise<any>;
|
|
1128
1148
|
WebSocket?: any;
|
|
1129
1149
|
crypto?: any;
|
|
@@ -1133,6 +1153,12 @@ export interface BrowserHostOptions {
|
|
|
1133
1153
|
};
|
|
1134
1154
|
filesystem?: BrowserFilesystemShim;
|
|
1135
1155
|
filesystemRoot?: string;
|
|
1156
|
+
network?: Record<string, (...args: any[]) => unknown> | null;
|
|
1157
|
+
ipfs?: Record<string, (...args: any[]) => unknown> | null;
|
|
1158
|
+
walletSign?: Record<string, (...args: any[]) => unknown> | null;
|
|
1159
|
+
protocolHandle?: Record<string, (...args: any[]) => unknown> | null;
|
|
1160
|
+
protocolDial?: Record<string, (...args: any[]) => unknown> | null;
|
|
1161
|
+
capabilityAdapters?: Record<string, Record<string, (...args: any[]) => unknown>>;
|
|
1136
1162
|
}
|
|
1137
1163
|
|
|
1138
1164
|
export interface NodeHostOptions {
|
|
@@ -1156,6 +1182,40 @@ export interface NodeHostOptions {
|
|
|
1156
1182
|
contextStore?: NodeHostContextStore;
|
|
1157
1183
|
fetch?: (...args: any[]) => Promise<any>;
|
|
1158
1184
|
WebSocket?: any;
|
|
1185
|
+
filesystem?: {
|
|
1186
|
+
resolvePath(path: string): string;
|
|
1187
|
+
readFile(
|
|
1188
|
+
path: string,
|
|
1189
|
+
options?: { encoding?: string | null },
|
|
1190
|
+
): Promise<string | Uint8Array>;
|
|
1191
|
+
writeFile(
|
|
1192
|
+
path: string,
|
|
1193
|
+
value: Uint8Array | ArrayBuffer | ArrayBufferView | string,
|
|
1194
|
+
options?: { encoding?: string | null },
|
|
1195
|
+
): Promise<{ path: string }>;
|
|
1196
|
+
appendFile(
|
|
1197
|
+
path: string,
|
|
1198
|
+
value: Uint8Array | ArrayBuffer | ArrayBufferView | string,
|
|
1199
|
+
options?: { encoding?: string | null },
|
|
1200
|
+
): Promise<{ path: string }>;
|
|
1201
|
+
deleteFile(path: string): Promise<{ path: string }>;
|
|
1202
|
+
mkdir(
|
|
1203
|
+
path: string,
|
|
1204
|
+
options?: { recursive?: boolean },
|
|
1205
|
+
): Promise<{ path: string }>;
|
|
1206
|
+
readdir(path?: string): Promise<NodeHostFilesystemEntry[]>;
|
|
1207
|
+
stat(path: string): Promise<NodeHostFilesystemStat>;
|
|
1208
|
+
rename(
|
|
1209
|
+
fromPath: string,
|
|
1210
|
+
toPath: string,
|
|
1211
|
+
): Promise<{ from: string; to: string }>;
|
|
1212
|
+
} | null;
|
|
1213
|
+
network?: Record<string, (...args: any[]) => unknown> | null;
|
|
1214
|
+
ipfs?: Record<string, (...args: any[]) => unknown> | null;
|
|
1215
|
+
walletSign?: Record<string, (...args: any[]) => unknown> | null;
|
|
1216
|
+
protocolHandle?: Record<string, (...args: any[]) => unknown> | null;
|
|
1217
|
+
protocolDial?: Record<string, (...args: any[]) => unknown> | null;
|
|
1218
|
+
capabilityAdapters?: Record<string, Record<string, (...args: any[]) => unknown>>;
|
|
1159
1219
|
}
|
|
1160
1220
|
|
|
1161
1221
|
export class HostCapabilityError extends Error {
|
|
@@ -1468,16 +1528,51 @@ export class BrowserHost {
|
|
|
1468
1528
|
crypto: {
|
|
1469
1529
|
sha256(data: Uint8Array | ArrayBuffer | ArrayBufferView | string): Promise<Uint8Array>;
|
|
1470
1530
|
sha512(data: Uint8Array | ArrayBuffer | ArrayBufferView | string): Promise<Uint8Array>;
|
|
1531
|
+
hkdf(options: {
|
|
1532
|
+
ikm: Uint8Array | ArrayBuffer | ArrayBufferView | number[];
|
|
1533
|
+
salt: Uint8Array | ArrayBuffer | ArrayBufferView | number[];
|
|
1534
|
+
info?: Uint8Array | ArrayBuffer | ArrayBufferView | number[];
|
|
1535
|
+
length: number;
|
|
1536
|
+
}): Promise<Uint8Array>;
|
|
1471
1537
|
aesGcmEncrypt(options: {
|
|
1472
1538
|
key: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1473
1539
|
plaintext: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1474
1540
|
iv?: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1475
|
-
|
|
1541
|
+
aad?: Uint8Array | ArrayBuffer | ArrayBufferView | number[] | null;
|
|
1542
|
+
}): Promise<{
|
|
1543
|
+
ciphertext: Uint8Array;
|
|
1544
|
+
tag: Uint8Array;
|
|
1545
|
+
iv: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1546
|
+
}>;
|
|
1476
1547
|
aesGcmDecrypt(options: {
|
|
1477
1548
|
key: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1478
1549
|
ciphertext: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1550
|
+
tag: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1479
1551
|
iv: Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
1552
|
+
aad?: Uint8Array | ArrayBuffer | ArrayBufferView | number[] | null;
|
|
1480
1553
|
}): Promise<Uint8Array>;
|
|
1554
|
+
generateX25519Keypair(): Promise<X25519Keypair>;
|
|
1555
|
+
x25519PublicKey(
|
|
1556
|
+
privateKey: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1557
|
+
): Promise<Uint8Array>;
|
|
1558
|
+
x25519SharedSecret(
|
|
1559
|
+
privateKey: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1560
|
+
publicKey: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1561
|
+
): Promise<Uint8Array>;
|
|
1562
|
+
ed25519: {
|
|
1563
|
+
publicKeyFromSeed(
|
|
1564
|
+
seed: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1565
|
+
): Promise<Uint8Array>;
|
|
1566
|
+
sign(
|
|
1567
|
+
message: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1568
|
+
seed: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1569
|
+
): Promise<Uint8Array>;
|
|
1570
|
+
verify(
|
|
1571
|
+
message: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1572
|
+
signature: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1573
|
+
publicKey: Uint8Array | ArrayBuffer | ArrayBufferView | number[],
|
|
1574
|
+
): Promise<boolean>;
|
|
1575
|
+
};
|
|
1481
1576
|
};
|
|
1482
1577
|
filesystem: BrowserFilesystemShim;
|
|
1483
1578
|
constructor(options?: BrowserHostOptions);
|
|
@@ -1576,6 +1671,7 @@ export interface BrowserModuleHarness {
|
|
|
1576
1671
|
host: BrowserHost;
|
|
1577
1672
|
bridge: HostcallBridge | null;
|
|
1578
1673
|
wasi: BrowserWasiShim;
|
|
1674
|
+
callHost(operation: string, params?: Record<string, any>): Promise<unknown>;
|
|
1579
1675
|
invokeRaw(
|
|
1580
1676
|
requestBytes: Uint8Array | ArrayBuffer | ArrayBufferView,
|
|
1581
1677
|
): Promise<Uint8Array>;
|
|
@@ -1594,7 +1690,7 @@ export interface BrowserModuleHarness {
|
|
|
1594
1690
|
export function detectArtifactProfile(wasmModule: WebAssembly.Module): string;
|
|
1595
1691
|
export function createBrowserModuleHarness(options?: {
|
|
1596
1692
|
wasmSource: Uint8Array | ArrayBuffer | string | WebAssembly.Module | unknown;
|
|
1597
|
-
host?: BrowserHost
|
|
1693
|
+
host?: BrowserHost | RuntimeHost | Record<string, unknown>;
|
|
1598
1694
|
hostOptions?: BrowserHostOptions;
|
|
1599
1695
|
args?: string[];
|
|
1600
1696
|
env?: Record<string, string>;
|
|
@@ -1665,7 +1761,7 @@ export function createModuleFlatBufferStreamPump(options: {
|
|
|
1665
1761
|
}): ModuleFlatBufferStreamPump;
|
|
1666
1762
|
export function loadModule(options?: {
|
|
1667
1763
|
wasmSource: Uint8Array | ArrayBuffer | string | WebAssembly.Module | unknown;
|
|
1668
|
-
host?: BrowserHost
|
|
1764
|
+
host?: BrowserHost | RuntimeHost | Record<string, unknown>;
|
|
1669
1765
|
hostOptions?: BrowserHostOptions;
|
|
1670
1766
|
args?: string[];
|
|
1671
1767
|
env?: Record<string, string | undefined>;
|
|
@@ -23,6 +23,28 @@ function createCapabilityRegistry(capabilities = {}) {
|
|
|
23
23
|
return registry;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function listCapabilityOperations(capabilities) {
|
|
27
|
+
const operations = new Set();
|
|
28
|
+
for (const [capabilityId, adapter] of capabilities.entries()) {
|
|
29
|
+
if (!adapter || typeof adapter !== "object") {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const methodIds = Object.keys(adapter).filter(
|
|
33
|
+
(methodId) => typeof adapter[methodId] === "function" && methodId !== "invoke",
|
|
34
|
+
);
|
|
35
|
+
if (methodIds.length > 0) {
|
|
36
|
+
for (const methodId of methodIds) {
|
|
37
|
+
operations.add(`${capabilityId}.${methodId}`);
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (typeof adapter.invoke === "function") {
|
|
42
|
+
operations.add(`${capabilityId}.invoke`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return Array.from(operations).sort();
|
|
46
|
+
}
|
|
47
|
+
|
|
26
48
|
export function createRuntimeHost(options = {}) {
|
|
27
49
|
const rows = options.rows ?? createFlatSqlRuntimeStore();
|
|
28
50
|
const regions = options.regions ?? createRuntimeRegionStore();
|
|
@@ -36,6 +58,15 @@ export function createRuntimeHost(options = {}) {
|
|
|
36
58
|
listCapabilities() {
|
|
37
59
|
return Array.from(capabilities.keys()).sort();
|
|
38
60
|
},
|
|
61
|
+
listSupportedCapabilities() {
|
|
62
|
+
return Array.from(capabilities.keys()).sort();
|
|
63
|
+
},
|
|
64
|
+
listOperations() {
|
|
65
|
+
return listCapabilityOperations(capabilities);
|
|
66
|
+
},
|
|
67
|
+
hasCapability(capability) {
|
|
68
|
+
return capabilities.has(normalizeCapabilityId(capability));
|
|
69
|
+
},
|
|
39
70
|
getCapability(capability) {
|
|
40
71
|
return capabilities.get(normalizeCapabilityId(capability)) ?? null;
|
|
41
72
|
},
|
|
@@ -68,6 +99,9 @@ export function createRuntimeHost(options = {}) {
|
|
|
68
99
|
`Runtime host capability "${capabilityId}" does not implement "${methodId}" or invoke().`,
|
|
69
100
|
);
|
|
70
101
|
},
|
|
102
|
+
async invoke(operation, params = {}) {
|
|
103
|
+
return this.invokeCapability(operation, params);
|
|
104
|
+
},
|
|
71
105
|
};
|
|
72
106
|
}
|
|
73
107
|
|
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
import { createBrowserWasiShim, WasiExitError } from "../host/wasiShim.js";
|
|
16
16
|
import { createBrowserHost } from "../host/browserHost.js";
|
|
17
|
+
import { getWasmWallet } from "../utils/wasmCrypto.js";
|
|
17
18
|
import {
|
|
18
19
|
createJsonHostcallBridge,
|
|
20
|
+
createAsyncHostDispatcher,
|
|
19
21
|
createHostSyncDispatcher,
|
|
20
|
-
dispatchHostOperation,
|
|
21
22
|
DEFAULT_HOSTCALL_IMPORT_MODULE,
|
|
22
23
|
} from "../host/abi.js";
|
|
23
24
|
import {
|
|
@@ -126,8 +127,20 @@ async function instantiateBrowserModule(options = {}) {
|
|
|
126
127
|
* @param {string} [options.surface] - "direct" or "command" (default: auto-detect).
|
|
127
128
|
*/
|
|
128
129
|
export async function createBrowserModuleHarness(options = {}) {
|
|
129
|
-
const host = options.host ?? createBrowserHost(options.hostOptions);
|
|
130
130
|
const wasmModule = await compileWasmModule(options.wasmSource);
|
|
131
|
+
const moduleImports = WebAssembly.Module.imports(wasmModule);
|
|
132
|
+
const needsHostBridge = moduleImports.some(
|
|
133
|
+
(entry) => entry.module === DEFAULT_HOSTCALL_IMPORT_MODULE,
|
|
134
|
+
);
|
|
135
|
+
const hostOptions =
|
|
136
|
+
!options.host && needsHostBridge && !options.hostOptions?.wasmWallet
|
|
137
|
+
? {
|
|
138
|
+
...options.hostOptions,
|
|
139
|
+
wasmWallet: await getWasmWallet(),
|
|
140
|
+
}
|
|
141
|
+
: options.hostOptions;
|
|
142
|
+
const host = options.host ?? createBrowserHost(hostOptions);
|
|
143
|
+
const dispatchHost = createAsyncHostDispatcher(host);
|
|
131
144
|
|
|
132
145
|
const profile = detectArtifactProfile(wasmModule);
|
|
133
146
|
const moduleExports = WebAssembly.Module.exports(wasmModule);
|
|
@@ -240,7 +253,7 @@ export async function createBrowserModuleHarness(options = {}) {
|
|
|
240
253
|
}
|
|
241
254
|
|
|
242
255
|
async function callHost(operation, params = {}) {
|
|
243
|
-
return
|
|
256
|
+
return dispatchHost(operation, params);
|
|
244
257
|
}
|
|
245
258
|
|
|
246
259
|
function readManifest() {
|
package/src/testing/index.d.ts
CHANGED
|
@@ -335,6 +335,7 @@ export interface BrowserModuleHarness {
|
|
|
335
335
|
stdout: Uint8Array;
|
|
336
336
|
stderr: Uint8Array;
|
|
337
337
|
};
|
|
338
|
+
callHost(operation: string, params?: Record<string, any>): Promise<unknown>;
|
|
338
339
|
invokeRaw(
|
|
339
340
|
requestBytes: Uint8Array | ArrayBuffer | ArrayBufferView,
|
|
340
341
|
): Promise<Uint8Array>;
|
package/src/testing/index.js
CHANGED
|
@@ -98,6 +98,7 @@ const CapabilitySurfaceMatrix = Object.freeze({
|
|
|
98
98
|
notes: [
|
|
99
99
|
"WASI preopens are the preferred cross-runtime filesystem surface.",
|
|
100
100
|
"The sync hostcall ABI currently exposes filesystem.resolvePath only.",
|
|
101
|
+
"Awaited filesystem reads and writes live on the generic async host boundary shared by NodeHost, BrowserHost, runtime-host capability registries, and harness callHost dispatch.",
|
|
101
102
|
],
|
|
102
103
|
}),
|
|
103
104
|
pipe: Object.freeze({
|
|
@@ -121,7 +122,7 @@ const CapabilitySurfaceMatrix = Object.freeze({
|
|
|
121
122
|
nodeHostApi: true,
|
|
122
123
|
notes: [
|
|
123
124
|
"The coarse network capability maps to async host-side HTTP/TCP/UDP/TLS/WebSocket services.",
|
|
124
|
-
"Browser harnesses can await the same capability surface through BrowserHost.invoke().",
|
|
125
|
+
"Browser and Node harnesses can await the same capability surface through BrowserHost.invoke(), loadModule(...).callHost(...), and createBrowserModuleHarness(...).callHost(...).",
|
|
125
126
|
"Pure WASI guests cannot reach that surface through the current sync hostcall ABI.",
|
|
126
127
|
"WasmEdge provides non-blocking socket-oriented extensions that can serve as the standard server-side max-WASI target.",
|
|
127
128
|
],
|
|
@@ -207,7 +208,7 @@ const CapabilitySurfaceMatrix = Object.freeze({
|
|
|
207
208
|
syncHostcall: false,
|
|
208
209
|
nodeHostApi: true,
|
|
209
210
|
notes: [
|
|
210
|
-
"IPFS access is available through async host
|
|
211
|
+
"IPFS access is available through the generic async host boundary and browser/module harness dispatch.",
|
|
211
212
|
"Pure WASM guests cannot reach that surface through the current sync hostcall ABI.",
|
|
212
213
|
],
|
|
213
214
|
}),
|
|
@@ -219,7 +220,7 @@ const CapabilitySurfaceMatrix = Object.freeze({
|
|
|
219
220
|
syncHostcall: false,
|
|
220
221
|
nodeHostApi: true,
|
|
221
222
|
notes: [
|
|
222
|
-
"Protocol registration is available through async host
|
|
223
|
+
"Protocol registration is available through the generic async host boundary and browser/module harness dispatch.",
|
|
223
224
|
"Pure WASM guests cannot reach that surface through the current sync hostcall ABI.",
|
|
224
225
|
],
|
|
225
226
|
}),
|
|
@@ -231,7 +232,7 @@ const CapabilitySurfaceMatrix = Object.freeze({
|
|
|
231
232
|
syncHostcall: false,
|
|
232
233
|
nodeHostApi: true,
|
|
233
234
|
notes: [
|
|
234
|
-
"Protocol dialing is available through async host
|
|
235
|
+
"Protocol dialing is available through the generic async host boundary and browser/module harness dispatch.",
|
|
235
236
|
"Pure WASM guests cannot reach that surface through the current sync hostcall ABI.",
|
|
236
237
|
],
|
|
237
238
|
}),
|