@haex-space/vault-sdk 2.9.3 → 3.1.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/dist/vue.mjs CHANGED
@@ -267,7 +267,24 @@ var HAEXSPACE_MESSAGE_TYPES = {
267
267
  /** Debug message for development/troubleshooting */
268
268
  DEBUG: "haexspace:debug",
269
269
  /** Console forwarding from extension iframe */
270
- CONSOLE_FORWARD: "console.forward"
270
+ CONSOLE_FORWARD: "console.forward",
271
+ /**
272
+ * Sent from main window to iframe on the shared window listener, carrying
273
+ * one `MessagePort` in `event.ports[0]`. Once received, the SDK switches
274
+ * to port-based messaging and never reads the window listener again.
275
+ *
276
+ * Payload: `{ type: PORT_INIT }` — no data. The port itself is the payload.
277
+ */
278
+ PORT_INIT: "haexspace:port:init",
279
+ /**
280
+ * Sent from SDK to main window *over the MessagePort* after the port is
281
+ * installed. Main uses this to mark the iframe as ready and flush any
282
+ * events buffered during the handshake window. Only valid on the port —
283
+ * a READY sent over window.postMessage is ignored.
284
+ *
285
+ * Payload: `{ type: PORT_READY }` — no data.
286
+ */
287
+ PORT_READY: "haexspace:port:ready"
271
288
  };
272
289
 
273
290
  // src/polyfills/debug.ts
@@ -680,7 +697,7 @@ var DatabaseAPI = class {
680
697
  }
681
698
  async transaction(statements) {
682
699
  await this.client.request(DATABASE_COMMANDS.transaction, {
683
- statements
700
+ statements: statements.map((s) => [s.sql, s.params || []])
684
701
  });
685
702
  }
686
703
  async createTable(tableName, columns) {
@@ -1649,6 +1666,7 @@ function parseTableName(fullTableName) {
1649
1666
  }
1650
1667
 
1651
1668
  // src/client/init.ts
1669
+ var PORT_HANDSHAKE_TIMEOUT_MS = 1e4;
1652
1670
  function isInIframe() {
1653
1671
  return window.self !== window.top;
1654
1672
  }
@@ -1905,11 +1923,14 @@ async function initIframeMode(ctx, log, messageHandler, request) {
1905
1923
  if (!isInIframe()) {
1906
1924
  throw new HaexVaultSdkError("NOT_IN_IFRAME" /* NOT_IN_IFRAME */, "errors.not_in_iframe");
1907
1925
  }
1926
+ const port = await waitForHostPortAsync(log);
1908
1927
  ctx.handlers.messageHandler = messageHandler;
1909
- window.addEventListener("message", messageHandler);
1928
+ port.addEventListener("message", messageHandler);
1929
+ port.start();
1930
+ port.postMessage({ type: HAEXSPACE_MESSAGE_TYPES.PORT_READY });
1910
1931
  ctx.state.isNativeWindow = false;
1911
1932
  ctx.state.initialized = true;
1912
- log("HaexVault SDK initialized in iframe mode");
1933
+ log("HaexVault SDK initialized in iframe mode (MessagePort transport)");
1913
1934
  if (ctx.config.manifest) {
1914
1935
  ctx.state.extensionInfo = {
1915
1936
  publicKey: ctx.config.manifest.publicKey,
@@ -1923,7 +1944,42 @@ async function initIframeMode(ctx, log, messageHandler, request) {
1923
1944
  const context2 = await request(EXTENSION_COMMANDS.getContext);
1924
1945
  ctx.state.context = context2;
1925
1946
  log("Application context received:", context2);
1926
- return { context: context2 };
1947
+ return { context: context2, port };
1948
+ }
1949
+ function waitForHostPortAsync(log) {
1950
+ return new Promise((resolve, reject) => {
1951
+ let settled = false;
1952
+ const cleanup = () => {
1953
+ window.removeEventListener("message", handler);
1954
+ };
1955
+ const timeoutId = setTimeout(() => {
1956
+ if (settled) return;
1957
+ settled = true;
1958
+ cleanup();
1959
+ reject(
1960
+ new HaexVaultSdkError(
1961
+ "TIMEOUT" /* TIMEOUT */,
1962
+ "errors.port_handshake_timeout",
1963
+ { timeout: PORT_HANDSHAKE_TIMEOUT_MS }
1964
+ )
1965
+ );
1966
+ }, PORT_HANDSHAKE_TIMEOUT_MS);
1967
+ const handler = (event) => {
1968
+ const type = event.data?.type;
1969
+ if (type !== HAEXSPACE_MESSAGE_TYPES.PORT_INIT) return;
1970
+ const port = event.ports[0];
1971
+ if (!port) {
1972
+ log("PORT_INIT received but event.ports is empty \u2014 ignoring");
1973
+ return;
1974
+ }
1975
+ if (settled) return;
1976
+ settled = true;
1977
+ clearTimeout(timeoutId);
1978
+ cleanup();
1979
+ resolve(port);
1980
+ };
1981
+ window.addEventListener("message", handler);
1982
+ });
1927
1983
  }
1928
1984
  function sendDebugInfo(config) {
1929
1985
  if (!config.debug) return;
@@ -1947,7 +2003,15 @@ postMessage error: ${e}`);
1947
2003
  function generateRequestId(counter) {
1948
2004
  return `req_${counter}`;
1949
2005
  }
1950
- function sendPostMessage(method, params, requestId, config, extensionInfo2, pendingRequests) {
2006
+ function sendPostMessage(method, params, requestId, config, extensionInfo2, pendingRequests, port) {
2007
+ if (!port) {
2008
+ return Promise.reject(
2009
+ new HaexVaultSdkError(
2010
+ "EXTENSION_NOT_INITIALIZED" /* EXTENSION_NOT_INITIALIZED */,
2011
+ "errors.port_not_connected"
2012
+ )
2013
+ );
2014
+ }
1951
2015
  const request = {
1952
2016
  method,
1953
2017
  params,
@@ -1963,17 +2027,16 @@ function sendPostMessage(method, params, requestId, config, extensionInfo2, pend
1963
2027
  );
1964
2028
  }, config.timeout);
1965
2029
  pendingRequests.set(requestId, { resolve, reject, timeout });
1966
- const targetOrigin = "*";
1967
2030
  if (config.debug) {
1968
2031
  console.log("[SDK Debug] ========== Sending Request ==========");
1969
2032
  console.log("[SDK Debug] Request ID:", requestId);
1970
2033
  console.log("[SDK Debug] Method:", request.method);
1971
2034
  console.log("[SDK Debug] Params:", request.params);
1972
- console.log("[SDK Debug] Target origin:", targetOrigin);
2035
+ console.log("[SDK Debug] Transport: MessagePort");
1973
2036
  console.log("[SDK Debug] Extension info:", extensionInfo2);
1974
2037
  console.log("[SDK Debug] ========================================");
1975
2038
  }
1976
- window.parent.postMessage({ id: requestId, ...request }, targetOrigin);
2039
+ port.postMessage({ id: requestId, ...request });
1977
2040
  });
1978
2041
  }
1979
2042
  async function sendInvoke(method, params, config, _log) {
@@ -1992,11 +2055,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo2, onEvent)
1992
2055
  return (event) => {
1993
2056
  if (config.debug) {
1994
2057
  console.log("[SDK Debug] ========== Message Received ==========");
1995
- console.log("[SDK Debug] Event origin:", event.origin);
1996
- console.log(
1997
- "[SDK Debug] Event source:",
1998
- event.source === window.parent ? "parent window" : "unknown"
1999
- );
2000
2058
  console.log("[SDK Debug] Event data:", event.data);
2001
2059
  console.log("[SDK Debug] Extension info loaded:", !!extensionInfo2());
2002
2060
  console.log(
@@ -2004,12 +2062,6 @@ function createMessageHandler(config, pendingRequests, extensionInfo2, onEvent)
2004
2062
  pendingRequests.size
2005
2063
  );
2006
2064
  }
2007
- if (event.source !== window.parent) {
2008
- if (config.debug) {
2009
- console.error("[SDK Debug] \u274C REJECTED: Message not from parent window!");
2010
- }
2011
- return;
2012
- }
2013
2065
  const data = event.data;
2014
2066
  if ("id" in data && pendingRequests.has(data.id)) {
2015
2067
  if (config.debug) {
@@ -2231,6 +2283,13 @@ var HaexVaultSdk = class {
2231
2283
  this.reactiveSubscribers = /* @__PURE__ */ new Set();
2232
2284
  // Handlers
2233
2285
  this.messageHandler = null;
2286
+ /**
2287
+ * MessagePort obtained from the main window during iframe-mode handshake.
2288
+ * `null` until `initIframe()` completes successfully. Every outbound
2289
+ * request in iframe mode flows through this port; `sendPostMessage` rejects
2290
+ * if called before the handshake finishes.
2291
+ */
2292
+ this.hostPort = null;
2234
2293
  this.setupPromise = null;
2235
2294
  this.setupHook = null;
2236
2295
  // Public APIs
@@ -2404,7 +2463,15 @@ var HaexVaultSdk = class {
2404
2463
  return sendInvoke(method, paramsWithCredentials, this.config, this.log.bind(this));
2405
2464
  }
2406
2465
  const requestId = generateRequestId(++this.requestCounter);
2407
- return sendPostMessage(method, resolvedParams, requestId, this.config, this._extensionInfo, this.pendingRequests);
2466
+ return sendPostMessage(
2467
+ method,
2468
+ resolvedParams,
2469
+ requestId,
2470
+ this.config,
2471
+ this._extensionInfo,
2472
+ this.pendingRequests,
2473
+ this.hostPort
2474
+ );
2408
2475
  }
2409
2476
  // ==========================================================================
2410
2477
  // Private: Initialization
@@ -2471,7 +2538,7 @@ var HaexVaultSdk = class {
2471
2538
  () => this._extensionInfo,
2472
2539
  this.handleEvent.bind(this)
2473
2540
  );
2474
- const { context: context2 } = await initIframeMode(
2541
+ const { context: context2, port } = await initIframeMode(
2475
2542
  {
2476
2543
  config: this.config,
2477
2544
  state: {
@@ -2503,6 +2570,7 @@ var HaexVaultSdk = class {
2503
2570
  this.messageHandler,
2504
2571
  this.request.bind(this)
2505
2572
  );
2573
+ this.hostPort = port;
2506
2574
  if (this.config.manifest) {
2507
2575
  this._extensionInfo = {
2508
2576
  publicKey: this.config.manifest.publicKey,