@gemigo/extension-sdk 0.1.0 → 0.1.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/dist/gemigo-extension-sdk.es.js +39 -31
- package/dist/gemigo-extension-sdk.umd.js +1 -1
- package/dist/index.d.ts +12 -15
- package/package.json +1 -1
|
@@ -202,9 +202,16 @@ var connectCallSender_default = (m, g, _, v, b) => {
|
|
|
202
202
|
S();
|
|
203
203
|
}
|
|
204
204
|
};
|
|
205
|
-
}, eventHandlers = { contextMenu: [] },
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
}, eventHandlers = { contextMenu: [] }, connectionPromise = null;
|
|
206
|
+
function isInIframe() {
|
|
207
|
+
try {
|
|
208
|
+
return window.self !== window.top;
|
|
209
|
+
} catch {
|
|
210
|
+
return !0;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function getHost() {
|
|
214
|
+
return connectionPromise || (isInIframe() || console.warn("[GemiGo SDK] Not running in iframe. SDK calls will verify connection forever."), connectionPromise = connectToParent_default({ methods: { onContextMenuEvent(e) {
|
|
208
215
|
eventHandlers.contextMenu.forEach((f) => {
|
|
209
216
|
try {
|
|
210
217
|
f(e);
|
|
@@ -212,32 +219,33 @@ async function connect() {
|
|
|
212
219
|
console.error("[GemiGo SDK] Error in contextMenu handler:", e);
|
|
213
220
|
}
|
|
214
221
|
});
|
|
215
|
-
} } })
|
|
216
|
-
}
|
|
217
|
-
function createSDKInstance(e) {
|
|
218
|
-
return {
|
|
219
|
-
getPageInfo: () => e.getPageInfo(),
|
|
220
|
-
getPageHTML: () => e.getPageHTML(),
|
|
221
|
-
getPageText: () => e.getPageText(),
|
|
222
|
-
getSelection: () => e.getSelection(),
|
|
223
|
-
highlight: (f, p) => e.highlight(f, p),
|
|
224
|
-
notify: (f, p) => e.notify({
|
|
225
|
-
title: f,
|
|
226
|
-
message: p
|
|
227
|
-
}),
|
|
228
|
-
captureVisible: () => e.captureVisible(),
|
|
229
|
-
extractArticle: () => e.extractArticle(),
|
|
230
|
-
getContextMenuEvent: () => e.getContextMenuEvent(),
|
|
231
|
-
on(e, f) {
|
|
232
|
-
e === "contextMenu" && eventHandlers.contextMenu.push(f);
|
|
233
|
-
},
|
|
234
|
-
off(e, f) {
|
|
235
|
-
if (e === "contextMenu") if (f) {
|
|
236
|
-
let e = eventHandlers.contextMenu.indexOf(f);
|
|
237
|
-
e > -1 && eventHandlers.contextMenu.splice(e, 1);
|
|
238
|
-
} else eventHandlers.contextMenu = [];
|
|
239
|
-
}
|
|
240
|
-
};
|
|
222
|
+
} } }).promise, connectionPromise);
|
|
241
223
|
}
|
|
242
|
-
var
|
|
243
|
-
|
|
224
|
+
var sdkInstance = {
|
|
225
|
+
getPageInfo: () => getHost().then((e) => e.getPageInfo()),
|
|
226
|
+
getPageHTML: () => getHost().then((e) => e.getPageHTML()),
|
|
227
|
+
getPageText: () => getHost().then((e) => e.getPageText()),
|
|
228
|
+
getSelection: () => getHost().then((e) => e.getSelection()),
|
|
229
|
+
highlight: (e, f) => getHost().then((p) => p.highlight(e, f)),
|
|
230
|
+
notify: (e, f) => getHost().then((p) => p.notify({
|
|
231
|
+
title: e,
|
|
232
|
+
message: f
|
|
233
|
+
})),
|
|
234
|
+
captureVisible: () => getHost().then((e) => e.captureVisible()),
|
|
235
|
+
extractArticle: () => getHost().then((e) => e.extractArticle()),
|
|
236
|
+
getContextMenuEvent: () => getHost().then((e) => e.getContextMenuEvent()),
|
|
237
|
+
on(e, f) {
|
|
238
|
+
getHost(), e === "contextMenu" && eventHandlers.contextMenu.push(f);
|
|
239
|
+
},
|
|
240
|
+
off(e, f) {
|
|
241
|
+
if (e === "contextMenu") if (f) {
|
|
242
|
+
let e = eventHandlers.contextMenu.indexOf(f);
|
|
243
|
+
e > -1 && eventHandlers.contextMenu.splice(e, 1);
|
|
244
|
+
} else eventHandlers.contextMenu = [];
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
getHost().catch((e) => {
|
|
248
|
+
console.debug("[GemiGo SDK] Auto-connect waiting...", e);
|
|
249
|
+
});
|
|
250
|
+
var src_default = sdkInstance;
|
|
251
|
+
export { src_default as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?module.exports=t():typeof define==`function`&&define.amd?define([],t):(e=typeof globalThis<`u`?globalThis:e||self,e.GemigoExtensionSDK=t())})(this,function(){var e;(function(e){e.Call=`call`,e.Reply=`reply`,e.Syn=`syn`,e.SynAck=`synAck`,e.Ack=`ack`})(e||={});var t;(function(e){e.Fulfilled=`fulfilled`,e.Rejected=`rejected`})(t||={});var n;(function(e){e.ConnectionDestroyed=`ConnectionDestroyed`,e.ConnectionTimeout=`ConnectionTimeout`,e.NoIframeSrc=`NoIframeSrc`})(n||={});var r;(function(e){e.DataCloneError=`DataCloneError`})(r||={});var i;(function(e){e.Message=`message`})(i||={});var a=(e,t)=>{let n=[],r=!1;return{destroy(i){r||(r=!0,t(`${e}: Destroying connection`),n.forEach(e=>{e(i)}))},onDestroy(e){r?e():n.push(e)}}},o=e=>(...t)=>{e&&console.log(`[Penpal]`,...t)};let s=({name:e,message:t,stack:n})=>({name:e,message:t,stack:n}),c=e=>{let t=Error();return Object.keys(e).forEach(n=>t[n]=e[n]),t};var l=(n,a,o)=>{let{localName:c,local:l,remote:u,originForSending:d,originForReceiving:f}=n,p=!1,m=n=>{if(n.source!==u||n.data.penpal!==e.Call)return;if(f!==`*`&&n.origin!==f){o(`${c} received message from origin ${n.origin} which did not match expected origin ${f}`);return}let{methodName:i,args:l,id:m}=n.data;o(`${c}: Received ${i}() call`);let h=n=>a=>{if(o(`${c}: Sending ${i}() reply`),p){o(`${c}: Unable to send ${i}() reply due to destroyed connection`);return}let l={penpal:e.Reply,id:m,resolution:n,returnValue:a};n===t.Rejected&&a instanceof Error&&(l.returnValue=s(a),l.returnValueIsError=!0);try{u.postMessage(l,d)}catch(n){if(n.name===r.DataCloneError){let r={penpal:e.Reply,id:m,resolution:t.Rejected,returnValue:s(n),returnValueIsError:!0};u.postMessage(r,d)}throw n}};new Promise(e=>e(a[i].apply(a,l))).then(h(t.Fulfilled),h(t.Rejected))};return l.addEventListener(i.Message,m),()=>{p=!0,l.removeEventListener(i.Message,m)}},u=0,d=()=>++u,f=`.`,p=e=>e?e.split(f):[],m=e=>e.join(f),h=(e,t)=>{let n=p(t||``);return n.push(e),m(n)};let g=(e,t,n)=>{let r=p(t);return r.reduce((e,t,i)=>(e[t]===void 0&&(e[t]={}),i===r.length-1&&(e[t]=n),e[t]),e),e},_=(e,t)=>{let n={};return Object.keys(e).forEach(r=>{let i=e[r],a=h(r,t);typeof i==`object`&&Object.assign(n,_(i,a)),typeof i==`function`&&(n[a]=i)}),n},v=e=>{let t={};for(let n in e)g(t,n,e[n]);return t};var y=(r,a,o,s,l)=>{let{localName:u,local:f,remote:p,originForSending:m,originForReceiving:h}=a,g=!1;l(`${u}: Connecting call sender`);let _=r=>(...a)=>{l(`${u}: Sending ${r}() call`);let o;try{p.closed&&(o=!0)}catch{o=!0}if(o&&s(),g){let e=Error(`Unable to send ${r}() call due to destroyed connection`);throw e.code=n.ConnectionDestroyed,e}return new Promise((n,o)=>{let s=d(),g=a=>{if(a.source!==p||a.data.penpal!==e.Reply||a.data.id!==s)return;if(h!==`*`&&a.origin!==h){l(`${u} received message from origin ${a.origin} which did not match expected origin ${h}`);return}let d=a.data;l(`${u}: Received ${r}() reply`),f.removeEventListener(i.Message,g);let m=d.returnValue;d.returnValueIsError&&(m=c(m)),(d.resolution===t.Fulfilled?n:o)(m)};f.addEventListener(i.Message,g);let _={penpal:e.Call,id:s,methodName:r,args:a};p.postMessage(_,m)})},y=o.reduce((e,t)=>(e[t]=_(t),e),{});return Object.assign(r,v(y)),()=>{g=!0}},b=(e,t)=>{let r;return e!==void 0&&(r=window.setTimeout(()=>{let r=Error(`Connection timed out after ${e}ms`);r.code=n.ConnectionTimeout,t(r)},e)),()=>{clearTimeout(r)}},x=(t,n,r,i)=>{let{destroy:a,onDestroy:o}=r;return r=>{if(!(t instanceof RegExp?t.test(r.origin):t===`*`||t===r.origin)){i(`Child: Handshake - Received SYN-ACK from origin ${r.origin} which did not match expected origin ${t}`);return}i(`Child: Handshake - Received SYN-ACK, responding with ACK`);let s=r.origin===`null`?`*`:r.origin,c={penpal:e.Ack,methodNames:Object.keys(n)};window.parent.postMessage(c,s);let u={localName:`Child`,local:window,remote:window.parent,originForSending:s,originForReceiving:r.origin};o(l(u,n,i));let d={};return o(y(d,u,r.data.methodNames,a,i)),d}},S=()=>{try{clearTimeout()}catch{return!1}return!0},C=(t={})=>{let{parentOrigin:n=`*`,methods:r={},timeout:s,debug:c=!1}=t,l=o(c),u=a(`Child`,l),{destroy:d,onDestroy:f}=u,p=x(n,_(r),u,l),m=()=>{l(`Child: Handshake - Sending SYN`);let t={penpal:e.Syn},r=n instanceof RegExp?`*`:n;window.parent.postMessage(t,r)};return{promise:new Promise((t,n)=>{let r=b(s,d),a=n=>{if(S()&&!(n.source!==parent||!n.data)&&n.data.penpal===e.SynAck){let e=p(n);e&&(window.removeEventListener(i.Message,a),r(),t(e))}};window.addEventListener(i.Message,a),m(),f(e=>{window.removeEventListener(i.Message,a),e&&n(e)})}),destroy(){d()}}},w={contextMenu:[]},T=null;function E(){try{return window.self!==window.top}catch{return!0}}function D(){return T||(E()||console.warn(`[GemiGo SDK] Not running in iframe. SDK calls will verify connection forever.`),T=C({methods:{onContextMenuEvent(e){w.contextMenu.forEach(t=>{try{t(e)}catch(e){console.error(`[GemiGo SDK] Error in contextMenu handler:`,e)}})}}}).promise,T)}return D().catch(e=>{console.debug(`[GemiGo SDK] Auto-connect waiting...`,e)}),{getPageInfo:()=>D().then(e=>e.getPageInfo()),getPageHTML:()=>D().then(e=>e.getPageHTML()),getPageText:()=>D().then(e=>e.getPageText()),getSelection:()=>D().then(e=>e.getSelection()),highlight:(e,t)=>D().then(n=>n.highlight(e,t)),notify:(e,t)=>D().then(n=>n.notify({title:e,message:t})),captureVisible:()=>D().then(e=>e.captureVisible()),extractArticle:()=>D().then(e=>e.extractArticle()),getContextMenuEvent:()=>D().then(e=>e.getContextMenuEvent()),on(e,t){D(),e===`contextMenu`&&w.contextMenu.push(t)},off(e,t){if(e===`contextMenu`)if(t){let e=w.contextMenu.indexOf(t);e>-1&&w.contextMenu.splice(e,1)}else w.contextMenu=[]}}});
|
package/dist/index.d.ts
CHANGED
|
@@ -4,16 +4,19 @@
|
|
|
4
4
|
* SDK for building apps that run inside the GemiGo browser extension.
|
|
5
5
|
*
|
|
6
6
|
* Usage (CDN):
|
|
7
|
-
* <script src="https://
|
|
7
|
+
* <script src="https://unpkg.com/@gemigo/extension-sdk/dist/gemigo-extension-sdk.umd.js"></script>
|
|
8
8
|
* <script>
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* // No connect() needed - just use the global gemigo object
|
|
10
|
+
* gemigo.getPageInfo().then(console.log);
|
|
11
|
+
*
|
|
12
|
+
* gemigo.on('contextMenu', (event) => {
|
|
13
|
+
* console.log('Context menu clicked:', event);
|
|
11
14
|
* });
|
|
12
15
|
* </script>
|
|
13
16
|
*
|
|
14
17
|
* Usage (ES Module):
|
|
15
|
-
* import
|
|
16
|
-
*
|
|
18
|
+
* import gemigo from '@gemigo/extension-sdk';
|
|
19
|
+
*
|
|
17
20
|
* const pageInfo = await gemigo.getPageInfo();
|
|
18
21
|
*/
|
|
19
22
|
type ContextMenuEventHandler = (event: {
|
|
@@ -21,7 +24,7 @@ type ContextMenuEventHandler = (event: {
|
|
|
21
24
|
selectionText?: string;
|
|
22
25
|
pageUrl?: string;
|
|
23
26
|
}) => void;
|
|
24
|
-
export interface
|
|
27
|
+
export interface GemigoSDK {
|
|
25
28
|
/** Get current page information */
|
|
26
29
|
getPageInfo(): Promise<{
|
|
27
30
|
url: string;
|
|
@@ -72,13 +75,7 @@ export interface GemigoExtension {
|
|
|
72
75
|
off(event: 'contextMenu', handler?: ContextMenuEventHandler): void;
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
75
|
-
*
|
|
76
|
-
* Must be called before using any SDK methods.
|
|
77
|
-
*
|
|
78
|
-
* @returns Promise resolving to the GemiGo SDK instance
|
|
78
|
+
* Proxy handler to auto-connect on method calls
|
|
79
79
|
*/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
connect: typeof connect;
|
|
83
|
-
};
|
|
84
|
-
export default _default;
|
|
80
|
+
declare const sdkInstance: GemigoSDK;
|
|
81
|
+
export default sdkInstance;
|
package/package.json
CHANGED