aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/platform.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/platform.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/platform.js45
1 files changed, 44 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/platform.js b/packages/meshbay-hub/src/meshbay_hub/static/platform.js
index 0663a42..fcc866e 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/platform.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/platform.js
@@ -88,6 +88,40 @@ export const secrets = {
};
/**
+ * Call the hub.
+ *
+ * In a browser this is `fetch`, unchanged — the page came from the hub, so the
+ * request is same-origin and nothing is in the way.
+ *
+ * In the application the page's origin is `app://meshbay`, and a browser fetch
+ * from it is refused by CORS. The hub has **no CORS middleware at all**, and
+ * that is worth keeping: its API is reachable from no web origin whatever.
+ * Widening it for `app://meshbay` would be worse than it appears, because that
+ * origin is not a credential — any Electron application can claim the same
+ * scheme and host name.
+ *
+ * So the main process makes the call. It returns a small object rather than a
+ * Response, and this shapes it back into something with `.ok`, `.status` and
+ * `.json()`, so callers do not have to know which one they got.
+ */
+export async function apiFetch(url, init) {
+ if (!bridge || !bridge.fetch) return fetch(url, init);
+ const raw = await bridge.fetch(String(url), init && {
+ method: init.method,
+ headers: init.headers,
+ body: init.body,
+ });
+ return {
+ ok: raw.ok,
+ status: raw.status,
+ statusText: String(raw.status),
+ headers: new Headers(raw.headers || {}),
+ text: async () => raw.body,
+ json: async () => JSON.parse(raw.body),
+ };
+}
+
+/**
* Save a decrypted file to disk.
*
* Returns null when there is no native path, so the caller keeps today's
@@ -100,4 +134,13 @@ export async function nativeSave(suggestedName, size) {
return bridge.saveFile(suggestedName, size);
}
-export default { isNative, hubBase, capabilities, secrets, nativeSave };
+export default { isNative, hubBase, capabilities, secrets, nativeSave, apiFetch };
+
+// Also a global, because `transport.js` is loaded as a classic script — it
+// predates the module graph and exposes `MeshBayTransport` the same way. The
+// alternative was a second fetch path there, which is how two callers of one
+// hub end up disagreeing about how to reach it.
+if (typeof window !== 'undefined') {
+ window.MeshBayPlatform = { isNative, hubBase, capabilities, secrets,
+ nativeSave, apiFetch };
+}