Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@opensea/vessel

Package Overview
Dependencies
Maintainers
9
Versions
609
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@opensea/vessel - npm Package Compare versions

Comparing version 0.0.17 to 0.0.18

308

dist/@opensea/vessel.es.js

@@ -1,25 +0,25 @@

var O = Object.defineProperty;
var C = (s, e, t) => e in s ? O(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
var o = (s, e, t) => (C(s, typeof e != "symbol" ? e + "" : e, t), t);
const d = /* @__PURE__ */ new Map();
function g(s, e, t) {
const n = d.get(s);
var m = Object.defineProperty;
var O = (s, e, t) => e in s ? m(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
var i = (s, e, t) => (O(s, typeof e != "symbol" ? e + "" : e, t), t);
const l = /* @__PURE__ */ new Map();
function f(s, e, t) {
const n = l.get(s);
n && (n.timeout && clearTimeout(n.timeout), n.reject(
new Error("[Vessel] Same action fired again. Keeping only latest.")
), d.delete(s)), d.set(s, e), typeof t == "number" && t > 0 && (e.timeout = setTimeout(() => {
u(s), e.reject(new Error("[Vessel] Action timed out."));
), l.delete(s)), l.set(s, e), typeof t == "number" && t > 0 && (e.timeout = setTimeout(() => {
p(s), e.reject(new Error("[Vessel] Action timed out."));
}, t));
}
function u(s) {
const e = d.get(s);
e && (e.timeout && clearTimeout(e.timeout), d.delete(s));
function p(s) {
const e = l.get(s);
e && (e.timeout && clearTimeout(e.timeout), l.delete(s));
}
function w(s) {
return d.get(s);
function g(s) {
return l.get(s);
}
function b(s) {
function M(s) {
return `${s ? `[VESSEL-${s.toUpperCase()}]:` : "[VESSEL]:"}`.trimStart();
}
function f(s = "log", e) {
const t = b(e == null ? void 0 : e.scope);
function u(s = "log", e) {
const t = M(e == null ? void 0 : e.scope);
return (...n) => {

@@ -29,7 +29,7 @@ e != null && e.debug && console[s](t, ...n);

}
function R(s) {
function b(s) {
return {
info: f("info", s),
warn: f("warn", s),
error: f("error", s)
info: u("info", s),
warn: u("warn", s),
error: u("error", s)
};

@@ -39,27 +39,26 @@ }

constructor(e, t) {
super(`${b(t)} ${e}`), this.name = "VesselError";
super(`${M(t)} ${e}`), this.name = "VesselError";
}
}
let I = (s = 21) => crypto.getRandomValues(new Uint8Array(s)).reduce((e, t) => (t &= 63, t < 36 ? e += t.toString(36) : t < 62 ? e += (t - 26).toString(36).toUpperCase() : t > 62 ? e += "-" : e += "_", e), "");
let R = (s = 21) => crypto.getRandomValues(new Uint8Array(s)).reduce((e, t) => (t &= 63, t < 36 ? e += t.toString(36) : t < 62 ? e += (t - 26).toString(36).toUpperCase() : t > 62 ? e += "-" : e += "_", e), "");
const v = "application/x-opensea-vessel-v1+json";
function E() {
return `op-${I()}`;
function I() {
return `op-${R()}`;
}
function H() {
return `msg-${I()}`;
function C() {
return `msg-${R()}`;
}
function $(s) {
function H(s) {
const e = new URL(s);
return `${e.protocol}//${e.host}`;
}
var i = /* @__PURE__ */ ((s) => (s.Handshake = "handshake", s.HandshakeReply = "handshake-reply", s.Message = "message", s.MessageReply = "message-reply", s.Close = "close", s))(i || {});
var r = /* @__PURE__ */ ((s) => (s.Handshake = "handshake", s.HandshakeReply = "handshake-reply", s.Message = "message", s.MessageReply = "message-reply", s.Close = "close", s))(r || {});
class h {
constructor(e, t) {
o(this, "type");
o(this, "id");
o(this, "from");
o(this, "operation");
o(this, "payload");
o(this, "metadata");
this.type = e, this.id = (t == null ? void 0 : t.id) ?? H(), this.from = (t == null ? void 0 : t.from) ?? v, this.operation = (t == null ? void 0 : t.operation) ?? E(), this.payload = t == null ? void 0 : t.payload, this.metadata = t == null ? void 0 : t.metadata;
i(this, "type");
i(this, "id");
i(this, "from");
i(this, "operation");
i(this, "payload");
this.type = e, this.id = (t == null ? void 0 : t.id) ?? C(), this.from = (t == null ? void 0 : t.from) ?? v, this.operation = (t == null ? void 0 : t.operation) ?? I(), this.payload = t == null ? void 0 : t.payload;
}

@@ -72,9 +71,8 @@ toObject() {

operation: this.operation,
payload: this.payload,
metadata: this.metadata
payload: this.payload
};
}
}
function A(s, e = v) {
if (s && typeof s == "object" && "from" in s && s.from === e && "type" in s && Object.values(i).includes(s.type) && "id" in s && "operation" in s)
function $(s, e = v) {
if (s && typeof s == "object" && "from" in s && s.from === e && "type" in s && Object.values(r).includes(s.type) && "id" in s && "operation" in s)
return new h(s.type, {

@@ -84,37 +82,34 @@ id: s.id,

operation: s.operation,
payload: s.payload,
metadata: s.metadata
payload: s.payload
});
throw new c("Invalid message.");
}
function m(s, e, t) {
function E(s, e, t) {
if (e === "*" || s.origin === e)
return A(s.data, t ?? v);
throw new c("Invalid message event origin.");
return $(s.data, t ?? v);
}
class k {
class w {
constructor(e) {
o(this, "log");
o(this, "parent", window.parent);
o(this, "subscriptions");
o(this, "closed", !1);
o(this, "parentOrigin");
i(this, "log");
i(this, "parent", window.parent);
i(this, "subscriptions");
i(this, "closed", !1);
i(this, "parentOrigin");
this.parentOrigin = e.parentOrigin, this.subscriptions = {
[i.Message]: [],
[i.Close]: []
}, this.log = R({ debug: e.debug, scope: "CHILD" }), this.onMessage = this.onMessage.bind(this), window.addEventListener("message", this.onMessage, !1);
[r.Message]: [],
[r.Close]: []
}, this.log = b({ debug: e.debug, scope: "CHILD" }), this.onMessage = this.onMessage.bind(this), window.addEventListener("message", this.onMessage, !1);
}
callSubscriptions(e, t) {
const n = this.sendMessage.bind(this);
if (e === i.Close) {
this.close(), this.subscriptions[e].forEach((r) => r(t));
if (e === r.Close) {
this.close(), this.subscriptions[e].forEach((o) => o(t));
return;
}
this.subscriptions[e].forEach((r) => {
r(t, (a, l) => {
this.subscriptions[e].forEach((o) => {
o(t, (a) => {
n(
new h(i.MessageReply, {
new h(r.MessageReply, {
operation: t.operation,
payload: a,
metadata: l
payload: a
})

@@ -127,11 +122,13 @@ );

try {
const t = m(e, this.parentOrigin);
const t = E(e, this.parentOrigin);
if (!t)
return;
switch (t.type) {
case i.Handshake:
case r.Handshake:
this.sendHandshakeReply(t);
return;
case i.Message:
this.callSubscriptions(i.Message, t);
case r.Message:
this.callSubscriptions(r.Message, t);
return;
case i.MessageReply:
case r.MessageReply:
this.resolveReply(t);

@@ -146,3 +143,3 @@ return;

this.log.info(`Received handshake from ${this.parentOrigin}`);
const t = new h(i.HandshakeReply, {
const t = new h(r.HandshakeReply, {
operation: e.operation

@@ -160,11 +157,11 @@ });

try {
const n = w(e.operation);
const n = g(e.operation);
if (n) {
this.log.info(`Resolving action ${e.operation}`);
const { resolve: r, reject: a } = n;
if (u(e.operation), (t = e.payload) != null && t.error) {
const { resolve: o, reject: a } = n;
if (p(e.operation), (t = e.payload) != null && t.error) {
a(e.payload.error);
return;
}
r(e.payload);
o(e.payload);
}

@@ -186,17 +183,15 @@ } catch (n) {

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
* @param timeout The timeout in milliseconds to wait for a reply, defaults to 5000
* @returns A promise that resolves with the reply payload. Rejects if the timeout is reached.
*/
async send(e, t, n = 5e3) {
return new Promise((r, a) => {
const l = new h(i.Message, {
payload: e,
metadata: t
async send(e, t = 5e3) {
return new Promise((n, o) => {
const a = new h(r.Message, {
payload: e
});
g(l.operation, { resolve: r, reject: a }, n);
f(a.operation, { resolve: n, reject: o }, t);
try {
this.sendMessage(l);
} catch (p) {
this.log.error("Error sending message to parent", p), a(p);
this.sendMessage(a);
} catch (d) {
this.log.error("Error sending message to parent", d), o(d);
}

@@ -208,10 +203,8 @@ });

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
*/
emit(e, t) {
const n = new h(i.Message, {
payload: e,
metadata: t
emit(e) {
const t = new h(r.Message, {
payload: e
});
this.sendMessage(n);
this.sendMessage(t);
}

@@ -224,4 +217,4 @@ on(e, t) {

once(e, t) {
const n = this.on(e, (...r) => {
n(), t(...r);
const n = this.on(e, (...o) => {
n(), t(...o);
});

@@ -234,28 +227,28 @@ }

this.closed = !0, window.removeEventListener("message", this.onMessage);
const e = new h(i.Close);
const e = new h(r.Close);
this.parent.postMessage(e.toObject(), this.parentOrigin);
}
}
class y {
class k {
constructor(e) {
o(this, "parentFrame");
o(this, "child");
o(this, "frame");
o(this, "handshakeOperation");
o(this, "handshakeInterval");
o(this, "handshakeIntervalTimeout", 500);
o(this, "handshakeActionResolverId");
o(this, "subscriptions");
o(this, "log");
o(this, "childOrigin");
o(this, "childUrl");
o(this, "connected");
this.frame = e.frame, this.parentFrame = window, this.child = null, this.childUrl = e.url, this.childOrigin = $(e.url), this.connected = !1, this.handshakeOperation = null, this.handshakeInterval = null, e.handshakeIntervalTimeout && (this.handshakeIntervalTimeout = e.handshakeIntervalTimeout), this.subscriptions = {
[i.Message]: [],
[i.Close]: []
}, this.log = R({ debug: e.debug, scope: "PARENT" }), this.parentFrame.addEventListener(
i(this, "parentFrame");
i(this, "child");
i(this, "frame");
i(this, "handshakeOperation");
i(this, "handshakeInterval");
i(this, "handshakeIntervalTimeout", 500);
i(this, "handshakeActionResolverId");
i(this, "subscriptions");
i(this, "log");
i(this, "childOrigin");
i(this, "childUrl");
i(this, "connected");
this.frame = e.frame, this.parentFrame = window, this.child = null, this.childUrl = e.url, this.childOrigin = H(e.url), this.connected = !1, this.handshakeOperation = null, this.handshakeInterval = null, e.handshakeIntervalTimeout && (this.handshakeIntervalTimeout = e.handshakeIntervalTimeout), this.subscriptions = {
[r.Message]: [],
[r.Close]: []
}, this.log = b({ debug: e.debug, scope: "PARENT" }), this.parentFrame.addEventListener(
"message",
this.onMessage.bind(this),
!1
), this.handshakeActionResolverId = E();
), this.handshakeActionResolverId = I();
}

@@ -269,3 +262,3 @@ startHandshake() {

e += 1;
const n = new h(i.Handshake);
const n = new h(r.Handshake);
this.handshakeOperation = n.operation, this.sendMessage(n);

@@ -284,13 +277,12 @@ }

const n = this.sendMessage.bind(this);
if (e === i.Close) {
this.close(), this.subscriptions[e].forEach((r) => r(t));
if (e === r.Close) {
this.close(), this.subscriptions[e].forEach((o) => o(t));
return;
}
this.subscriptions[e].forEach((r) => {
r(t, (a, l) => {
this.subscriptions[e].forEach((o) => {
o(t, (a) => {
n(
new h(i.MessageReply, {
new h(r.MessageReply, {
operation: t.operation,
payload: a,
metadata: l
payload: a
})

@@ -306,9 +298,9 @@ );

this.handshakeInterval && window.clearInterval(this.handshakeInterval), this.connected = !0;
const t = w(this.handshakeActionResolverId);
const t = g(this.handshakeActionResolverId);
if (!t)
throw new c("Handshake resolver not found");
this.log.info(`Resolving action ${this.handshakeActionResolverId}`);
const { resolve: n, reject: r } = t;
if (u(this.handshakeActionResolverId), (a = e.payload) != null && a.error) {
r(e.payload.error);
const { resolve: n, reject: o } = t;
if (p(this.handshakeActionResolverId), (a = e.payload) != null && a.error) {
o(e.payload.error);
return;

@@ -320,15 +312,17 @@ }

try {
const t = m(e, this.childOrigin);
const t = E(e, this.childOrigin);
if (!t)
return;
switch (t.type) {
case i.HandshakeReply:
case r.HandshakeReply:
this.handleHandshakeReply(t);
break;
case i.Message:
this.callSubscriptions(i.Message, t);
case r.Message:
this.callSubscriptions(r.Message, t);
break;
case i.MessageReply:
case r.MessageReply:
this.resolveReply(t);
break;
case i.Close:
this.callSubscriptions(i.Close, t);
case r.Close:
this.callSubscriptions(r.Close, t);
break;

@@ -346,11 +340,11 @@ default:

try {
const n = w(e.operation);
const n = g(e.operation);
if (n) {
this.log.info(`Resolving action ${e.operation}`);
const { resolve: r, reject: a } = n;
if (u(e.operation), (t = e.payload) != null && t.error) {
const { resolve: o, reject: a } = n;
if (p(e.operation), (t = e.payload) != null && t.error) {
a(e.payload.error);
return;
}
r(e.payload);
o(e.payload);
}

@@ -364,3 +358,3 @@ } catch (n) {

throw new c("Child frame not found.");
if (e.type !== i.Handshake && !this.connected)
if (e.type !== r.Handshake && !this.connected)
throw new c("Not connected to child frame.");

@@ -373,17 +367,15 @@ this.child.postMessage(e.toObject(), this.childOrigin);

* @param payload The payload to send to the child frame
* @param metadata The metadata to send to the child frame
* @param timeout The timeout in milliseconds to wait for a reply, defaults to 5000
* @returns A promise that resolves with the reply payload. Rejects if the timeout is reached.
*/
async send(e, t, n = 5e3) {
return new Promise((r, a) => {
const l = new h(i.Message, {
payload: e,
metadata: t
async send(e, t = 5e3) {
return new Promise((n, o) => {
const a = new h(r.Message, {
payload: e
});
g(l.operation, { resolve: r, reject: a }, n);
f(a.operation, { resolve: n, reject: o }, t);
try {
this.sendMessage(l);
} catch (p) {
this.log.error("Error sending message to child", p), a(p);
this.sendMessage(a);
} catch (d) {
this.log.error("Error sending message to child", d), o(d);
}

@@ -395,14 +387,12 @@ });

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
*/
emit(e, t) {
const n = new h(i.Message, {
payload: e,
metadata: t
emit(e) {
const t = new h(r.Message, {
payload: e
});
this.sendMessage(n);
this.sendMessage(t);
}
connect({ isFrameLoaded: e = !1 } = {}) {
return new Promise((t, n) => {
this.log.info(`Connecting to child iframe ${this.childUrl}`), e ? this.startHandshake() : this.frame.addEventListener("load", this.startHandshake.bind(this)), g(this.handshakeActionResolverId, { resolve: t, reject: n });
this.log.info(`Connecting to child iframe ${this.childUrl}`), e ? this.startHandshake() : this.frame.addEventListener("load", this.startHandshake.bind(this)), f(this.handshakeActionResolverId, { resolve: t, reject: n });
});

@@ -416,4 +406,4 @@ }

once(e, t) {
const n = this.on(e, (...r) => {
n(), t(...r);
const n = this.on(e, (...o) => {
n(), t(...o);
});

@@ -425,19 +415,19 @@ }

close() {
this.log.info("Closing frames"), this.subscriptions[i.Message] = [], this.subscriptions[i.Close] = [], this.handshakeOperation = null, this.handshakeInterval && window.clearInterval(this.handshakeInterval), u(this.handshakeActionResolverId), this.connected = !1;
this.log.info("Closing frames"), this.subscriptions[r.Message] = [], this.subscriptions[r.Close] = [], this.handshakeOperation = null, this.handshakeInterval && window.clearInterval(this.handshakeInterval), p(this.handshakeActionResolverId), this.connected = !1;
}
}
class M {
class y {
static createParentFrame(e) {
return new y(e);
return new k(e);
}
static createChildFrame(e) {
return new k(e);
return new w(e);
}
}
o(M, "ParentFrame", y), o(M, "ChildFrame", k);
i(y, "ParentFrame", k), i(y, "ChildFrame", w);
export {
k as ChildFrame,
i as MessageType,
y as ParentFrame,
M as Vessel
w as ChildFrame,
r as MessageType,
k as ParentFrame,
y as Vessel
};

@@ -1,1 +0,1 @@

(function(l,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(l=typeof globalThis<"u"?globalThis:l||self,a(l.Vessel={}))})(this,function(l){"use strict";var S=Object.defineProperty;var A=(l,a,d)=>a in l?S(l,a,{enumerable:!0,configurable:!0,writable:!0,value:d}):l[a]=d;var o=(l,a,d)=>(A(l,typeof a!="symbol"?a+"":a,d),d);const a=new Map;function d(s,e,t){const n=a.get(s);n&&(n.timeout&&clearTimeout(n.timeout),n.reject(new Error("[Vessel] Same action fired again. Keeping only latest.")),a.delete(s)),a.set(s,e),typeof t=="number"&&t>0&&(e.timeout=setTimeout(()=>{u(s),e.reject(new Error("[Vessel] Action timed out."))},t))}function u(s){const e=a.get(s);e&&(e.timeout&&clearTimeout(e.timeout),a.delete(s))}function v(s){return a.get(s)}function R(s){return`${s?`[VESSEL-${s.toUpperCase()}]:`:"[VESSEL]:"}`.trimStart()}function w(s="log",e){const t=R(e==null?void 0:e.scope);return(...n)=>{e!=null&&e.debug&&console[s](t,...n)}}function m(s){return{info:w("info",s),warn:w("warn",s),error:w("error",s)}}class f extends Error{constructor(e,t){super(`${R(t)} ${e}`),this.name="VesselError"}}let I=(s=21)=>crypto.getRandomValues(new Uint8Array(s)).reduce((e,t)=>(t&=63,t<36?e+=t.toString(36):t<62?e+=(t-26).toString(36).toUpperCase():t>62?e+="-":e+="_",e),"");const k="application/x-opensea-vessel-v1+json";function E(){return`op-${I()}`}function C(){return`msg-${I()}`}function H(s){const e=new URL(s);return`${e.protocol}//${e.host}`}var i=(s=>(s.Handshake="handshake",s.HandshakeReply="handshake-reply",s.Message="message",s.MessageReply="message-reply",s.Close="close",s))(i||{});class c{constructor(e,t){o(this,"type");o(this,"id");o(this,"from");o(this,"operation");o(this,"payload");o(this,"metadata");this.type=e,this.id=(t==null?void 0:t.id)??C(),this.from=(t==null?void 0:t.from)??k,this.operation=(t==null?void 0:t.operation)??E(),this.payload=t==null?void 0:t.payload,this.metadata=t==null?void 0:t.metadata}toObject(){return{type:this.type,id:this.id,from:this.from,operation:this.operation,payload:this.payload,metadata:this.metadata}}}function $(s,e=k){if(s&&typeof s=="object"&&"from"in s&&s.from===e&&"type"in s&&Object.values(i).includes(s.type)&&"id"in s&&"operation"in s)return new c(s.type,{id:s.id,from:s.from,operation:s.operation,payload:s.payload,metadata:s.metadata});throw new f("Invalid message.")}function O(s,e,t){if(e==="*"||s.origin===e)return $(s.data,t??k);throw new f("Invalid message event origin.")}class y{constructor(e){o(this,"log");o(this,"parent",window.parent);o(this,"subscriptions");o(this,"closed",!1);o(this,"parentOrigin");this.parentOrigin=e.parentOrigin,this.subscriptions={[i.Message]:[],[i.Close]:[]},this.log=m({debug:e.debug,scope:"CHILD"}),this.onMessage=this.onMessage.bind(this),window.addEventListener("message",this.onMessage,!1)}callSubscriptions(e,t){const n=this.sendMessage.bind(this);if(e===i.Close){this.close(),this.subscriptions[e].forEach(r=>r(t));return}this.subscriptions[e].forEach(r=>{r(t,(h,p)=>{n(new c(i.MessageReply,{operation:t.operation,payload:h,metadata:p}))})})}onMessage(e){try{const t=O(e,this.parentOrigin);switch(t.type){case i.Handshake:this.sendHandshakeReply(t);return;case i.Message:this.callSubscriptions(i.Message,t);return;case i.MessageReply:this.resolveReply(t);return}}catch(t){this.log.error("Error parsing message from parent",t)}}sendHandshakeReply(e){this.log.info(`Received handshake from ${this.parentOrigin}`);const t=new c(i.HandshakeReply,{operation:e.operation});try{this.parent.postMessage(t.toObject(),this.parentOrigin)}catch(n){this.log.error("Error sending handshake reply",n)}}resolveReply(e){var t;this.log.info(`Received reply for action ${e.operation}`);try{const n=v(e.operation);if(n){this.log.info(`Resolving action ${e.operation}`);const{resolve:r,reject:h}=n;if(u(e.operation),(t=e.payload)!=null&&t.error){h(e.payload.error);return}r(e.payload)}}catch(n){this.log.error("Error resolving reply",n)}}sendMessage(e){if(!this.parent)throw new f("Parent frame not found.");if(this.closed)throw new f("Cannot send message, frame is closed.");this.parent.postMessage(e.toObject(),this.parentOrigin)}async send(e,t,n=5e3){return new Promise((r,h)=>{const p=new c(i.Message,{payload:e,metadata:t});d(p.operation,{resolve:r,reject:h},n);try{this.sendMessage(p)}catch(g){this.log.error("Error sending message to parent",g),h(g)}})}emit(e,t){const n=new c(i.Message,{payload:e,metadata:t});this.sendMessage(n)}on(e,t){return this.subscriptions[e].push(t),()=>{this.off.call(this,e,t)}}once(e,t){const n=this.on(e,(...r)=>{n(),t(...r)})}off(e,t){this.subscriptions[e]=this.subscriptions[e].filter(n=>n!==t)}close(){this.closed=!0,window.removeEventListener("message",this.onMessage);const e=new c(i.Close);this.parent.postMessage(e.toObject(),this.parentOrigin)}}class M{constructor(e){o(this,"parentFrame");o(this,"child");o(this,"frame");o(this,"handshakeOperation");o(this,"handshakeInterval");o(this,"handshakeIntervalTimeout",500);o(this,"handshakeActionResolverId");o(this,"subscriptions");o(this,"log");o(this,"childOrigin");o(this,"childUrl");o(this,"connected");this.frame=e.frame,this.parentFrame=window,this.child=null,this.childUrl=e.url,this.childOrigin=H(e.url),this.connected=!1,this.handshakeOperation=null,this.handshakeInterval=null,e.handshakeIntervalTimeout&&(this.handshakeIntervalTimeout=e.handshakeIntervalTimeout),this.subscriptions={[i.Message]:[],[i.Close]:[]},this.log=m({debug:e.debug,scope:"PARENT"}),this.parentFrame.addEventListener("message",this.onMessage.bind(this),!1),this.handshakeActionResolverId=E()}startHandshake(){if(this.log.info(`Sending handshake to ${this.childUrl}`),this.child=this.frame.contentWindow,!this.child)throw new Error("Child frame not found");let e=0;const t=()=>{if(this.log.info("Attempting handshake..."),this.child){e+=1;const n=new c(i.Handshake);this.handshakeOperation=n.operation,this.sendMessage(n)}};t(),this.handshakeInterval=window.setInterval(()=>{if(e>=5){this.log.warn("Handshake failed after 5 attempts. Giving up."),this.handshakeInterval&&window.clearInterval(this.handshakeInterval);return}t()},this.handshakeIntervalTimeout)}callSubscriptions(e,t){const n=this.sendMessage.bind(this);if(e===i.Close){this.close(),this.subscriptions[e].forEach(r=>r(t));return}this.subscriptions[e].forEach(r=>{r(t,(h,p)=>{n(new c(i.MessageReply,{operation:t.operation,payload:h,metadata:p}))})})}handleHandshakeReply(e){var h;if(this.log.info(`Received handshake reply from ${this.childUrl}`),e.operation!==this.handshakeOperation)throw new Error("Handshake reply operation does not match");this.handshakeInterval&&window.clearInterval(this.handshakeInterval),this.connected=!0;const t=v(this.handshakeActionResolverId);if(!t)throw new f("Handshake resolver not found");this.log.info(`Resolving action ${this.handshakeActionResolverId}`);const{resolve:n,reject:r}=t;if(u(this.handshakeActionResolverId),(h=e.payload)!=null&&h.error){r(e.payload.error);return}n(e.payload)}onMessage(e){try{const t=O(e,this.childOrigin);switch(t.type){case i.HandshakeReply:this.handleHandshakeReply(t);break;case i.Message:this.callSubscriptions(i.Message,t);break;case i.MessageReply:this.resolveReply(t);break;case i.Close:this.callSubscriptions(i.Close,t);break;default:this.log.warn(`Unknown message type: ${t.type}`)}}catch(t){this.log.error("Error handling message",t)}}resolveReply(e){var t;this.log.info(`Received reply for action ${e.operation}`);try{const n=v(e.operation);if(n){this.log.info(`Resolving action ${e.operation}`);const{resolve:r,reject:h}=n;if(u(e.operation),(t=e.payload)!=null&&t.error){h(e.payload.error);return}r(e.payload)}}catch(n){this.log.error("Error resolving reply",n)}}sendMessage(e){if(!this.child)throw new f("Child frame not found.");if(e.type!==i.Handshake&&!this.connected)throw new f("Not connected to child frame.");this.child.postMessage(e.toObject(),this.childOrigin)}async send(e,t,n=5e3){return new Promise((r,h)=>{const p=new c(i.Message,{payload:e,metadata:t});d(p.operation,{resolve:r,reject:h},n);try{this.sendMessage(p)}catch(g){this.log.error("Error sending message to child",g),h(g)}})}emit(e,t){const n=new c(i.Message,{payload:e,metadata:t});this.sendMessage(n)}connect({isFrameLoaded:e=!1}={}){return new Promise((t,n)=>{this.log.info(`Connecting to child iframe ${this.childUrl}`),e?this.startHandshake():this.frame.addEventListener("load",this.startHandshake.bind(this)),d(this.handshakeActionResolverId,{resolve:t,reject:n})})}on(e,t){return this.subscriptions[e].push(t),()=>{this.off.call(this,e,t)}}once(e,t){const n=this.on(e,(...r)=>{n(),t(...r)})}off(e,t){this.subscriptions[e]=this.subscriptions[e].filter(n=>n!==t)}close(){this.log.info("Closing frames"),this.subscriptions[i.Message]=[],this.subscriptions[i.Close]=[],this.handshakeOperation=null,this.handshakeInterval&&window.clearInterval(this.handshakeInterval),u(this.handshakeActionResolverId),this.connected=!1}}class b{static createParentFrame(e){return new M(e)}static createChildFrame(e){return new y(e)}}o(b,"ParentFrame",M),o(b,"ChildFrame",y),l.ChildFrame=y,l.MessageType=i,l.ParentFrame=M,l.Vessel=b,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
(function(l,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(l=typeof globalThis<"u"?globalThis:l||self,a(l.Vessel={}))})(this,function(l){"use strict";var $=Object.defineProperty;var S=(l,a,d)=>a in l?$(l,a,{enumerable:!0,configurable:!0,writable:!0,value:d}):l[a]=d;var r=(l,a,d)=>(S(l,typeof a!="symbol"?a+"":a,d),d);const a=new Map;function d(s,e,t){const n=a.get(s);n&&(n.timeout&&clearTimeout(n.timeout),n.reject(new Error("[Vessel] Same action fired again. Keeping only latest.")),a.delete(s)),a.set(s,e),typeof t=="number"&&t>0&&(e.timeout=setTimeout(()=>{f(s),e.reject(new Error("[Vessel] Action timed out."))},t))}function f(s){const e=a.get(s);e&&(e.timeout&&clearTimeout(e.timeout),a.delete(s))}function g(s){return a.get(s)}function b(s){return`${s?`[VESSEL-${s.toUpperCase()}]:`:"[VESSEL]:"}`.trimStart()}function v(s="log",e){const t=b(e==null?void 0:e.scope);return(...n)=>{e!=null&&e.debug&&console[s](t,...n)}}function R(s){return{info:v("info",s),warn:v("warn",s),error:v("error",s)}}class p extends Error{constructor(e,t){super(`${b(t)} ${e}`),this.name="VesselError"}}let m=(s=21)=>crypto.getRandomValues(new Uint8Array(s)).reduce((e,t)=>(t&=63,t<36?e+=t.toString(36):t<62?e+=(t-26).toString(36).toUpperCase():t>62?e+="-":e+="_",e),"");const w="application/x-opensea-vessel-v1+json";function I(){return`op-${m()}`}function O(){return`msg-${m()}`}function C(s){const e=new URL(s);return`${e.protocol}//${e.host}`}var i=(s=>(s.Handshake="handshake",s.HandshakeReply="handshake-reply",s.Message="message",s.MessageReply="message-reply",s.Close="close",s))(i||{});class c{constructor(e,t){r(this,"type");r(this,"id");r(this,"from");r(this,"operation");r(this,"payload");this.type=e,this.id=(t==null?void 0:t.id)??O(),this.from=(t==null?void 0:t.from)??w,this.operation=(t==null?void 0:t.operation)??I(),this.payload=t==null?void 0:t.payload}toObject(){return{type:this.type,id:this.id,from:this.from,operation:this.operation,payload:this.payload}}}function H(s,e=w){if(s&&typeof s=="object"&&"from"in s&&s.from===e&&"type"in s&&Object.values(i).includes(s.type)&&"id"in s&&"operation"in s)return new c(s.type,{id:s.id,from:s.from,operation:s.operation,payload:s.payload});throw new p("Invalid message.")}function E(s,e,t){if(e==="*"||s.origin===e)return H(s.data,t??w)}class k{constructor(e){r(this,"log");r(this,"parent",window.parent);r(this,"subscriptions");r(this,"closed",!1);r(this,"parentOrigin");this.parentOrigin=e.parentOrigin,this.subscriptions={[i.Message]:[],[i.Close]:[]},this.log=R({debug:e.debug,scope:"CHILD"}),this.onMessage=this.onMessage.bind(this),window.addEventListener("message",this.onMessage,!1)}callSubscriptions(e,t){const n=this.sendMessage.bind(this);if(e===i.Close){this.close(),this.subscriptions[e].forEach(o=>o(t));return}this.subscriptions[e].forEach(o=>{o(t,h=>{n(new c(i.MessageReply,{operation:t.operation,payload:h}))})})}onMessage(e){try{const t=E(e,this.parentOrigin);if(!t)return;switch(t.type){case i.Handshake:this.sendHandshakeReply(t);return;case i.Message:this.callSubscriptions(i.Message,t);return;case i.MessageReply:this.resolveReply(t);return}}catch(t){this.log.error("Error parsing message from parent",t)}}sendHandshakeReply(e){this.log.info(`Received handshake from ${this.parentOrigin}`);const t=new c(i.HandshakeReply,{operation:e.operation});try{this.parent.postMessage(t.toObject(),this.parentOrigin)}catch(n){this.log.error("Error sending handshake reply",n)}}resolveReply(e){var t;this.log.info(`Received reply for action ${e.operation}`);try{const n=g(e.operation);if(n){this.log.info(`Resolving action ${e.operation}`);const{resolve:o,reject:h}=n;if(f(e.operation),(t=e.payload)!=null&&t.error){h(e.payload.error);return}o(e.payload)}}catch(n){this.log.error("Error resolving reply",n)}}sendMessage(e){if(!this.parent)throw new p("Parent frame not found.");if(this.closed)throw new p("Cannot send message, frame is closed.");this.parent.postMessage(e.toObject(),this.parentOrigin)}async send(e,t=5e3){return new Promise((n,o)=>{const h=new c(i.Message,{payload:e});d(h.operation,{resolve:n,reject:o},t);try{this.sendMessage(h)}catch(u){this.log.error("Error sending message to parent",u),o(u)}})}emit(e){const t=new c(i.Message,{payload:e});this.sendMessage(t)}on(e,t){return this.subscriptions[e].push(t),()=>{this.off.call(this,e,t)}}once(e,t){const n=this.on(e,(...o)=>{n(),t(...o)})}off(e,t){this.subscriptions[e]=this.subscriptions[e].filter(n=>n!==t)}close(){this.closed=!0,window.removeEventListener("message",this.onMessage);const e=new c(i.Close);this.parent.postMessage(e.toObject(),this.parentOrigin)}}class y{constructor(e){r(this,"parentFrame");r(this,"child");r(this,"frame");r(this,"handshakeOperation");r(this,"handshakeInterval");r(this,"handshakeIntervalTimeout",500);r(this,"handshakeActionResolverId");r(this,"subscriptions");r(this,"log");r(this,"childOrigin");r(this,"childUrl");r(this,"connected");this.frame=e.frame,this.parentFrame=window,this.child=null,this.childUrl=e.url,this.childOrigin=C(e.url),this.connected=!1,this.handshakeOperation=null,this.handshakeInterval=null,e.handshakeIntervalTimeout&&(this.handshakeIntervalTimeout=e.handshakeIntervalTimeout),this.subscriptions={[i.Message]:[],[i.Close]:[]},this.log=R({debug:e.debug,scope:"PARENT"}),this.parentFrame.addEventListener("message",this.onMessage.bind(this),!1),this.handshakeActionResolverId=I()}startHandshake(){if(this.log.info(`Sending handshake to ${this.childUrl}`),this.child=this.frame.contentWindow,!this.child)throw new Error("Child frame not found");let e=0;const t=()=>{if(this.log.info("Attempting handshake..."),this.child){e+=1;const n=new c(i.Handshake);this.handshakeOperation=n.operation,this.sendMessage(n)}};t(),this.handshakeInterval=window.setInterval(()=>{if(e>=5){this.log.warn("Handshake failed after 5 attempts. Giving up."),this.handshakeInterval&&window.clearInterval(this.handshakeInterval);return}t()},this.handshakeIntervalTimeout)}callSubscriptions(e,t){const n=this.sendMessage.bind(this);if(e===i.Close){this.close(),this.subscriptions[e].forEach(o=>o(t));return}this.subscriptions[e].forEach(o=>{o(t,h=>{n(new c(i.MessageReply,{operation:t.operation,payload:h}))})})}handleHandshakeReply(e){var h;if(this.log.info(`Received handshake reply from ${this.childUrl}`),e.operation!==this.handshakeOperation)throw new Error("Handshake reply operation does not match");this.handshakeInterval&&window.clearInterval(this.handshakeInterval),this.connected=!0;const t=g(this.handshakeActionResolverId);if(!t)throw new p("Handshake resolver not found");this.log.info(`Resolving action ${this.handshakeActionResolverId}`);const{resolve:n,reject:o}=t;if(f(this.handshakeActionResolverId),(h=e.payload)!=null&&h.error){o(e.payload.error);return}n(e.payload)}onMessage(e){try{const t=E(e,this.childOrigin);if(!t)return;switch(t.type){case i.HandshakeReply:this.handleHandshakeReply(t);break;case i.Message:this.callSubscriptions(i.Message,t);break;case i.MessageReply:this.resolveReply(t);break;case i.Close:this.callSubscriptions(i.Close,t);break;default:this.log.warn(`Unknown message type: ${t.type}`)}}catch(t){this.log.error("Error handling message",t)}}resolveReply(e){var t;this.log.info(`Received reply for action ${e.operation}`);try{const n=g(e.operation);if(n){this.log.info(`Resolving action ${e.operation}`);const{resolve:o,reject:h}=n;if(f(e.operation),(t=e.payload)!=null&&t.error){h(e.payload.error);return}o(e.payload)}}catch(n){this.log.error("Error resolving reply",n)}}sendMessage(e){if(!this.child)throw new p("Child frame not found.");if(e.type!==i.Handshake&&!this.connected)throw new p("Not connected to child frame.");this.child.postMessage(e.toObject(),this.childOrigin)}async send(e,t=5e3){return new Promise((n,o)=>{const h=new c(i.Message,{payload:e});d(h.operation,{resolve:n,reject:o},t);try{this.sendMessage(h)}catch(u){this.log.error("Error sending message to child",u),o(u)}})}emit(e){const t=new c(i.Message,{payload:e});this.sendMessage(t)}connect({isFrameLoaded:e=!1}={}){return new Promise((t,n)=>{this.log.info(`Connecting to child iframe ${this.childUrl}`),e?this.startHandshake():this.frame.addEventListener("load",this.startHandshake.bind(this)),d(this.handshakeActionResolverId,{resolve:t,reject:n})})}on(e,t){return this.subscriptions[e].push(t),()=>{this.off.call(this,e,t)}}once(e,t){const n=this.on(e,(...o)=>{n(),t(...o)})}off(e,t){this.subscriptions[e]=this.subscriptions[e].filter(n=>n!==t)}close(){this.log.info("Closing frames"),this.subscriptions[i.Message]=[],this.subscriptions[i.Close]=[],this.handshakeOperation=null,this.handshakeInterval&&window.clearInterval(this.handshakeInterval),f(this.handshakeActionResolverId),this.connected=!1}}class M{static createParentFrame(e){return new y(e)}static createChildFrame(e){return new k(e)}}r(M,"ParentFrame",y),r(M,"ChildFrame",k),l.ChildFrame=k,l.MessageType=i,l.ParentFrame=y,l.Vessel=M,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
import { ActionSubscriptionFn } from "./parent";
import { MessageMetadataType, MessagePayloadType, MessageType } from "./utils/messaging";
import { MessagePayloadType, MessageType } from "./utils/messaging";
type ChildFramesParams = {

@@ -23,13 +23,11 @@ parentOrigin: string;

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
* @param timeout The timeout in milliseconds to wait for a reply, defaults to 5000
* @returns A promise that resolves with the reply payload. Rejects if the timeout is reached.
*/
send<P extends MessagePayloadType, R extends MessagePayloadType, M extends MessageMetadataType>(payload: P, metadata?: M, timeout?: number): Promise<R>;
send<P extends MessagePayloadType, R extends MessagePayloadType>(payload: P, timeout?: number): Promise<R>;
/**
* Emit a message to the parent frame and don't wait for a reply.
* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
*/
emit<P extends MessagePayloadType, M extends MessageMetadataType>(payload: P, metadata?: M): void;
emit<P extends MessagePayloadType>(payload: P): void;
on(type: MessageType.Message, fn: ActionSubscriptionFn): () => void;

@@ -36,0 +34,0 @@ once(type: MessageType.Message, fn: ActionSubscriptionFn): void;

import { ChildFrame } from "./child";
import { ActionSubscriptionFn, ParentFrame } from "./parent";
import { MessageType } from "./utils/messaging";
import type { Message, MessagePayloadType, MessageMetadataType } from "./utils/messaging";
import type { MessagePayloadType } from "./utils/messaging";
export declare class Vessel {

@@ -12,2 +12,2 @@ static ParentFrame: typeof ParentFrame;

export { ChildFrame, ParentFrame, MessageType };
export type { ActionSubscriptionFn, Message, MessagePayloadType, MessageMetadataType, };
export type { ActionSubscriptionFn, MessagePayloadType };

@@ -1,2 +0,2 @@

import { Message, MessageMetadataType, MessagePayloadType, MessageType } from "./utils/messaging";
import { Message, MessagePayloadType, MessageType } from "./utils/messaging";
type ParentFrameParams = {

@@ -8,4 +8,4 @@ frame: HTMLIFrameElement;

};
export type ActionSubscriptionFn = (message: Message<any, any>, reply: (payload: MessagePayloadType, metadata?: MessageMetadataType) => void) => void;
export type CloseSubscriptionFn = (message: Message<any, any>) => void;
export type ActionSubscriptionFn = (message: Message<any>, reply: (payload: MessagePayloadType) => void) => void;
export type CloseSubscriptionFn = (message: Message<any>) => void;
type ConnectOptions = {

@@ -38,13 +38,11 @@ isFrameLoaded?: boolean;

* @param payload The payload to send to the child frame
* @param metadata The metadata to send to the child frame
* @param timeout The timeout in milliseconds to wait for a reply, defaults to 5000
* @returns A promise that resolves with the reply payload. Rejects if the timeout is reached.
*/
send<P extends MessagePayloadType, R extends MessagePayloadType, M extends MessageMetadataType>(payload: P, metadata?: M, timeout?: number): Promise<R>;
send<P extends MessagePayloadType, R extends MessagePayloadType>(payload: P, timeout?: number): Promise<R>;
/**
* Emit a message to the parent frame and don't wait for a reply.
* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
*/
emit<P extends MessagePayloadType, M extends MessageMetadataType>(payload: P, metadata?: M): void;
emit<P extends MessagePayloadType>(payload: P): void;
connect({ isFrameLoaded }?: ConnectOptions): Promise<void>;

@@ -51,0 +49,0 @@ on(type: MessageType.Message, fn: ActionSubscriptionFn): () => void;

@@ -5,7 +5,5 @@ export declare const DEFAULT_FROM = "application/x-opensea-vessel-v1+json";

export declare function getOrigin(url: string): string;
export type MessageObject = Record<string, string | number | boolean | undefined>;
export type MessagePayloadType = {
[key: string]: string | number | boolean | MessagePayloadType;
} | undefined;
export type MessageMetadataType = Record<string, string | number | boolean> | undefined;
export type MessagePayloadType = string | number | boolean | undefined | {
[key: string]: MessagePayloadType;
} | MessagePayloadType[];
export declare enum MessageType {

@@ -18,3 +16,3 @@ Handshake = "handshake",

}
export declare class Message<P extends MessagePayloadType, M extends MessageMetadataType> {
export declare class Message<P extends MessagePayloadType> {
type: MessageType;

@@ -25,6 +23,4 @@ id: string;

payload: P;
metadata: M;
constructor(type: MessageType, params?: {
payload?: P;
metadata?: M;
id?: string;

@@ -40,6 +36,5 @@ from?: string;

payload: P;
metadata: M;
};
}
export declare function parseMessage<P extends MessagePayloadType, M extends MessageMetadataType>(message: any, from?: string): Message<P, M>;
export declare function parseMessageFromMessageEvent(messageEvent: MessageEvent<any>, allowedOrigin: string, from?: string): Message<MessagePayloadType, MessageMetadataType>;
export declare function parseMessage<P extends MessagePayloadType>(message: any, from?: string): Message<P>;
export declare function parseMessageFromMessageEvent(messageEvent: MessageEvent<any>, allowedOrigin: string, from?: string): Message<MessagePayloadType> | undefined;
{
"name": "@opensea/vessel",
"version": "0.0.17",
"version": "0.0.18",
"description": "🚢 Vessel: a promise-based postMessage library that sails your data smoothly across the Opensea.",

@@ -23,5 +23,2 @@ "files": [

"dev:e2e": "concurrently 'serve -l 3000 tests/parent' 'serve -l 3001 tests/child' 'playwright test --ui' --kill-others --success first",
"lint:code": "eslint --ext .ts,.tsx src",
"lint:fix": "eslint --fix --ext .ts,.tsx ",
"lint:format": "prettier --check src",
"lint:types": "tsc",

@@ -28,0 +25,0 @@ "postinstall": "husky install || exit 0",

@@ -242,3 +242,3 @@ import {

const promise = cf.send({ test: "test" }, undefined, 100)
const promise = cf.send({ test: "test" }, 100)
clock.advanceTimersByTime(100)

@@ -245,0 +245,0 @@

@@ -10,3 +10,2 @@ import { ActionSubscriptionFn, CloseSubscriptionFn } from "./parent"

Message,
MessageMetadataType,
MessagePayloadType,

@@ -52,3 +51,3 @@ MessageType,

type: MessageType.Message | MessageType.Close,
message: Message<any, any>,
message: Message<any>,
) {

@@ -64,3 +63,3 @@ const send = this.sendMessage.bind(this)

this.subscriptions[type].forEach(fn => {
fn(message, (payload, metadata) => {
fn(message, payload => {
send(

@@ -70,3 +69,2 @@ new Message(MessageType.MessageReply, {

payload,
metadata,
}),

@@ -82,2 +80,7 @@ )

if (!message) {
// Ignore messages from unallowed origins
return
}
switch (message.type) {

@@ -101,3 +104,3 @@ case MessageType.Handshake:

private sendHandshakeReply(message: Message<any, any>) {
private sendHandshakeReply(message: Message<any>) {
this.log.info(`Received handshake from ${this.parentOrigin}`)

@@ -116,3 +119,3 @@

private resolveReply(message: Message<any, any>) {
private resolveReply(message: Message<any>) {
this.log.info(`Received reply for action ${message.operation}`)

@@ -141,6 +144,3 @@

private sendMessage<
P extends MessagePayloadType,
M extends MessageMetadataType,
>(message: Message<P, M>) {
private sendMessage<P extends MessagePayloadType>(message: Message<P>) {
if (!this.parent) {

@@ -161,15 +161,12 @@ throw new VesselError("Parent frame not found.")

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
* @param timeout The timeout in milliseconds to wait for a reply, defaults to 5000
* @returns A promise that resolves with the reply payload. Rejects if the timeout is reached.
*/
async send<
P extends MessagePayloadType,
R extends MessagePayloadType,
M extends MessageMetadataType,
>(payload: P, metadata?: M, timeout: number = 5000) {
async send<P extends MessagePayloadType, R extends MessagePayloadType>(
payload: P,
timeout: number = 5000,
) {
return new Promise<R>((resolve, reject) => {
const message = new Message<P, M>(MessageType.Message, {
const message = new Message<P>(MessageType.Message, {
payload,
metadata,
})

@@ -191,11 +188,6 @@

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
*/
emit<P extends MessagePayloadType, M extends MessageMetadataType>(
payload: P,
metadata?: M,
) {
const message = new Message<P, M>(MessageType.Message, {
emit<P extends MessagePayloadType>(payload: P) {
const message = new Message<P>(MessageType.Message, {
payload,
metadata,
})

@@ -202,0 +194,0 @@

import { ChildFrame } from "./child"
import { ActionSubscriptionFn, ParentFrame } from "./parent"
import { MessageType } from "./utils/messaging"
import type {
Message,
MessagePayloadType,
MessageMetadataType,
} from "./utils/messaging"
import type { MessagePayloadType } from "./utils/messaging"

@@ -26,7 +22,2 @@ export class Vessel {

export type {
ActionSubscriptionFn,
Message,
MessagePayloadType,
MessageMetadataType,
}
export type { ActionSubscriptionFn, MessagePayloadType }

@@ -158,3 +158,3 @@ import { ParentFrame } from "./parent"

const promise = pf.send({ test: "test" }, undefined, 100)
const promise = pf.send({ test: "test" }, 100)
clock.advanceTimersByTime(100)

@@ -161,0 +161,0 @@

@@ -9,3 +9,2 @@ import {

Message,
MessageMetadataType,
MessagePayloadType,

@@ -26,7 +25,7 @@ MessageType,

export type ActionSubscriptionFn = (
message: Message<any, any>,
reply: (payload: MessagePayloadType, metadata?: MessageMetadataType) => void,
message: Message<any>,
reply: (payload: MessagePayloadType) => void,
) => void
export type CloseSubscriptionFn = (message: Message<any, any>) => void
export type CloseSubscriptionFn = (message: Message<any>) => void

@@ -126,3 +125,3 @@ type ConnectOptions = {

type: MessageType.Message | MessageType.Close,
message: Message<any, any>,
message: Message<any>,
) {

@@ -138,3 +137,3 @@ const send = this.sendMessage.bind(this)

this.subscriptions[type].forEach(fn => {
fn(message, (payload, metadata) => {
fn(message, payload => {
send(

@@ -144,3 +143,2 @@ new Message(MessageType.MessageReply, {

payload,
metadata,
}),

@@ -152,3 +150,3 @@ )

private handleHandshakeReply(message: Message<any, any>) {
private handleHandshakeReply(message: Message<any>) {
this.log.info(`Received handshake reply from ${this.childUrl}`)

@@ -189,2 +187,6 @@

if (!message) {
return
}
switch (message.type) {

@@ -215,3 +217,3 @@ case MessageType.HandshakeReply:

private resolveReply(message: Message<any, any>) {
private resolveReply(message: Message<any>) {
this.log.info(`Received reply for action ${message.operation}`)

@@ -240,6 +242,3 @@

private sendMessage<
P extends MessagePayloadType,
M extends MessageMetadataType,
>(message: Message<P, M>) {
private sendMessage<P extends MessagePayloadType>(message: Message<P>) {
if (!this.child) {

@@ -260,15 +259,12 @@ throw new VesselError("Child frame not found.")

* @param payload The payload to send to the child frame
* @param metadata The metadata to send to the child frame
* @param timeout The timeout in milliseconds to wait for a reply, defaults to 5000
* @returns A promise that resolves with the reply payload. Rejects if the timeout is reached.
*/
async send<
P extends MessagePayloadType,
R extends MessagePayloadType,
M extends MessageMetadataType,
>(payload: P, metadata?: M, timeout: number = 5000) {
async send<P extends MessagePayloadType, R extends MessagePayloadType>(
payload: P,
timeout: number = 5000,
) {
return new Promise<R>((resolve, reject) => {
const message = new Message<P, M>(MessageType.Message, {
const message = new Message<P>(MessageType.Message, {
payload,
metadata,
})

@@ -290,11 +286,6 @@

* @param payload The payload to send to the parent frame
* @param metadata The metadata to send to the parent frame
*/
emit<P extends MessagePayloadType, M extends MessageMetadataType>(
payload: P,
metadata?: M,
) {
const message = new Message<P, M>(MessageType.Message, {
emit<P extends MessagePayloadType>(payload: P) {
const message = new Message<P>(MessageType.Message, {
payload,
metadata,
})

@@ -301,0 +292,0 @@

@@ -51,3 +51,2 @@ import { describe, expect, test } from "vitest"

payload: { foo: "bar" },
metadata: { baz: "qux" },
})

@@ -59,3 +58,2 @@

expect(message.payload).toEqual({ foo: "bar" })
expect(message.metadata).toEqual({ baz: "qux" })
})

@@ -70,3 +68,2 @@

expect(message.payload).toEqual(undefined)
expect(message.metadata).toEqual(undefined)
})

@@ -81,3 +78,2 @@ })

payload: { foo: "bar" },
metadata: { baz: "qux" },
})

@@ -91,3 +87,2 @@

payload: { foo: "bar" },
metadata: { baz: "qux" },
})

@@ -105,3 +100,2 @@ })

payload: undefined,
metadata: undefined,
})

@@ -119,3 +113,2 @@ })

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -130,3 +123,2 @@

expect(message.payload).toEqual({ foo: "bar" })
expect(message.metadata).toEqual({ baz: "qux" })
})

@@ -141,3 +133,2 @@

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -155,3 +146,2 @@

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -169,3 +159,2 @@

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -185,3 +174,2 @@

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -200,10 +188,9 @@

expect(message).toBeInstanceOf(Message)
expect(message.type).toBe(MessageType.Message)
expect(message.id).toBe("msg-123")
expect(message.operation).toBe("op-123")
expect(message.payload).toEqual({ foo: "bar" })
expect(message.metadata).toEqual({ baz: "qux" })
expect(message?.type).toBe(MessageType.Message)
expect(message?.id).toBe("msg-123")
expect(message?.operation).toBe("op-123")
expect(message?.payload).toEqual({ foo: "bar" })
})
test("should throw an exception when MessageEvent origin doesn't match allowedOrigin", () => {
test("should ignore message when origin doesn't match allowedOrigin", () => {
const input = {

@@ -215,3 +202,2 @@ from: DEFAULT_FROM,

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -221,3 +207,3 @@

expect(() =>
expect(
parseMessageFromMessageEvent(

@@ -230,3 +216,3 @@ new MessageEvent("message", {

),
).toThrow()
).toBeUndefined()
})

@@ -241,3 +227,2 @@ })

payload: { foo: "bar" },
metadata: { baz: "qux" },
})

@@ -252,3 +237,2 @@

expect(parsedMessage.payload).toEqual({ foo: "bar" })
expect(parsedMessage.metadata).toEqual({ baz: "qux" })
})

@@ -263,3 +247,2 @@

payload: { foo: "bar" },
metadata: { baz: "qux" },
}

@@ -277,3 +260,3 @@

const parsedMessage = parseMessage(message.toObject())
const parsedMessage = parseMessage(message?.toObject())

@@ -285,4 +268,3 @@ expect(parsedMessage).toBeInstanceOf(Message)

expect(parsedMessage.payload).toEqual({ foo: "bar" })
expect(parsedMessage.metadata).toEqual({ baz: "qux" })
})
})

@@ -19,15 +19,10 @@ import { nanoid } from "nanoid"

export type MessageObject = Record<
string,
string | number | boolean | undefined
>
export type MessagePayloadType =
| { [key: string]: string | number | boolean | MessagePayloadType }
| string
| number
| boolean
| undefined
| { [key: string]: MessagePayloadType }
| MessagePayloadType[]
export type MessageMetadataType =
| Record<string, string | number | boolean>
| undefined
export enum MessageType {

@@ -41,6 +36,3 @@ Handshake = "handshake",

export class Message<
P extends MessagePayloadType,
M extends MessageMetadataType,
> {
export class Message<P extends MessagePayloadType> {
type: MessageType

@@ -51,3 +43,2 @@ id: string

payload: P
metadata: M

@@ -58,3 +49,2 @@ constructor(

payload?: P
metadata?: M
id?: string

@@ -70,3 +60,2 @@ from?: string

this.payload = params?.payload as P
this.metadata = params?.metadata as M
}

@@ -81,3 +70,2 @@

payload: this.payload,
metadata: this.metadata,
}

@@ -87,6 +75,6 @@ }

export function parseMessage<
P extends MessagePayloadType,
M extends MessageMetadataType,
>(message: any, from: string = DEFAULT_FROM): Message<P, M> {
export function parseMessage<P extends MessagePayloadType>(
message: any,
from: string = DEFAULT_FROM,
): Message<P> {
if (

@@ -102,3 +90,3 @@ message &&

) {
return new Message<P, M>(message.type, {
return new Message<P>(message.type, {
id: message.id,

@@ -108,3 +96,2 @@ from: message.from,

payload: message.payload,
metadata: message.metadata,
})

@@ -125,3 +112,4 @@ }

throw new VesselError("Invalid message event origin.")
// Ignore messages from other origins
return undefined
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc