@gemigo/extension-sdk 0.1.1 → 0.2.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/gemigo-extension-sdk.es.js +11 -15
- package/dist/gemigo-extension-sdk.umd.js +1 -1
- package/dist/index.d.ts +40 -39
- package/package.json +3 -1
|
@@ -223,25 +223,21 @@ function getHost() {
|
|
|
223
223
|
}
|
|
224
224
|
var sdkInstance = {
|
|
225
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
226
|
notify: (e, f) => getHost().then((p) => p.notify({
|
|
231
227
|
title: e,
|
|
232
228
|
message: f
|
|
233
229
|
})),
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
230
|
+
extension: {
|
|
231
|
+
getPageHTML: () => getHost().then((e) => e.getPageHTML()),
|
|
232
|
+
getPageText: () => getHost().then((e) => e.getPageText()),
|
|
233
|
+
getSelection: () => getHost().then((e) => e.getSelection()),
|
|
234
|
+
highlight: (e, f) => getHost().then((p) => p.highlight(e, f)),
|
|
235
|
+
extractArticle: () => getHost().then((e) => e.extractArticle()),
|
|
236
|
+
captureVisible: () => getHost().then((e) => e.captureVisible()),
|
|
237
|
+
getContextMenuEvent: () => getHost().then((e) => e.getContextMenuEvent()),
|
|
238
|
+
onContextMenu(e) {
|
|
239
|
+
getHost(), eventHandlers.contextMenu.push(e);
|
|
240
|
+
}
|
|
245
241
|
}
|
|
246
242
|
};
|
|
247
243
|
getHost().catch((e) => {
|
|
@@ -1 +1 @@
|
|
|
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.
|
|
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.gemigo=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()),notify:(e,t)=>D().then(n=>n.notify({title:e,message:t})),extension:{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)),extractArticle:()=>D().then(e=>e.extractArticle()),captureVisible:()=>D().then(e=>e.captureVisible()),getContextMenuEvent:()=>D().then(e=>e.getContextMenuEvent()),onContextMenu(e){D(),w.contextMenu.push(e)}}}});
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Usage (CDN):
|
|
7
7
|
* <script src="https://unpkg.com/@gemigo/extension-sdk/dist/gemigo-extension-sdk.umd.js"></script>
|
|
8
8
|
* <script>
|
|
9
|
-
* // No connect() needed - just use the global gemigo object
|
|
9
|
+
* // No connect() needed - just use the global gemigo object directly
|
|
10
10
|
* gemigo.getPageInfo().then(console.log);
|
|
11
11
|
*
|
|
12
12
|
* gemigo.on('contextMenu', (event) => {
|
|
@@ -31,48 +31,49 @@ export interface GemigoSDK {
|
|
|
31
31
|
title: string;
|
|
32
32
|
favIconUrl?: string;
|
|
33
33
|
}>;
|
|
34
|
-
/** Get full page HTML */
|
|
35
|
-
getPageHTML(): Promise<string>;
|
|
36
|
-
/** Get page text content */
|
|
37
|
-
getPageText(): Promise<string>;
|
|
38
|
-
/** Get selected text on page */
|
|
39
|
-
getSelection(): Promise<string>;
|
|
40
|
-
/** Highlight elements matching selector */
|
|
41
|
-
highlight(selector: string, color?: string): Promise<{
|
|
42
|
-
success: boolean;
|
|
43
|
-
count?: number;
|
|
44
|
-
}>;
|
|
45
34
|
/** Send system notification */
|
|
46
35
|
notify(title: string, message: string): Promise<{
|
|
47
36
|
success: boolean;
|
|
48
37
|
}>;
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
38
|
+
/** Extension-specific APIs */
|
|
39
|
+
extension: {
|
|
40
|
+
/** Get full page HTML */
|
|
41
|
+
getPageHTML(): Promise<string>;
|
|
42
|
+
/** Get page text content */
|
|
43
|
+
getPageText(): Promise<string>;
|
|
44
|
+
/** Get selected text on page */
|
|
45
|
+
getSelection(): Promise<string>;
|
|
46
|
+
/** Highlight elements matching selector */
|
|
47
|
+
highlight(selector: string, color?: string): Promise<{
|
|
48
|
+
success: boolean;
|
|
49
|
+
count?: number;
|
|
50
|
+
}>;
|
|
51
|
+
/** Extract article content from page */
|
|
52
|
+
extractArticle(): Promise<{
|
|
53
|
+
success: boolean;
|
|
54
|
+
title?: string;
|
|
55
|
+
content?: string;
|
|
56
|
+
excerpt?: string;
|
|
57
|
+
url?: string;
|
|
58
|
+
}>;
|
|
59
|
+
/** Capture visible tab screenshot */
|
|
60
|
+
captureVisible(): Promise<{
|
|
61
|
+
success: boolean;
|
|
62
|
+
dataUrl?: string;
|
|
63
|
+
error?: string;
|
|
64
|
+
}>;
|
|
65
|
+
/** Get pending context menu event (if any) */
|
|
66
|
+
getContextMenuEvent(): Promise<{
|
|
67
|
+
success: boolean;
|
|
68
|
+
event?: {
|
|
69
|
+
menuId: string;
|
|
70
|
+
selectionText?: string;
|
|
71
|
+
pageUrl?: string;
|
|
72
|
+
};
|
|
73
|
+
}>;
|
|
74
|
+
/** Register context menu event handler */
|
|
75
|
+
onContextMenu(handler: ContextMenuEventHandler): void;
|
|
76
|
+
};
|
|
76
77
|
}
|
|
77
78
|
/**
|
|
78
79
|
* Proxy handler to auto-connect on method calls
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gemigo/extension-sdk",
|
|
3
|
-
"
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"type": "module",
|
|
4
6
|
"description": "GemiGo Extension SDK for browser extension apps",
|
|
5
7
|
"main": "dist/gemigo-extension-sdk.umd.js",
|
|
6
8
|
"module": "dist/gemigo-extension-sdk.es.js",
|