@pbkit/wrp
Advanced tools
Comparing version 0.0.13 to 0.1.0
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createAndroidSocket = void 0; | ||
const misc_1 = require("./misc"); | ||
const util_1 = require("./misc/util"); | ||
const index_1 = require("./index"); | ||
@@ -14,3 +14,3 @@ // https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String) | ||
async write(data) { | ||
androidGlue.recv((0, misc_1.u8s2str)(data)); | ||
androidGlue.recv((0, util_1.u8s2str)(data)); | ||
return data.byteLength; | ||
@@ -22,3 +22,3 @@ }, | ||
async function getAndroidGlue() { | ||
return await (0, misc_1.checkAndRetryUntilSuccess)(() => globalThis[key] || undefined); | ||
return await (0, util_1.checkAndRetryUntilSuccess)(() => globalThis[key] || undefined); | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createIframeSocket = void 0; | ||
const misc_1 = require("./misc"); | ||
const index_1 = require("./index"); | ||
const key = "<glue>"; | ||
const util_1 = require("./misc/util"); | ||
const child_window_1 = require("./child-window"); | ||
async function createIframeSocket(config) { | ||
const { iframeElement, iframeOrigin, onClosed } = config; | ||
await handshake(iframeElement); | ||
const glue = (0, index_1.createGlue)(); | ||
globalThis.addEventListener("message", messageHandler); | ||
onceIframeReloaded(iframeElement, close); | ||
return { | ||
close, | ||
read: glue.read, | ||
async write(data) { | ||
const { contentWindow } = iframeElement; | ||
if (!contentWindow) | ||
throw new Error("Iframe has been unloaded."); | ||
const length = data.byteLength; | ||
contentWindow.postMessage([key, false, data], iframeOrigin, [data.buffer]); | ||
return length; | ||
}, | ||
}; | ||
function messageHandler(event) { | ||
if (event.source !== iframeElement.contentWindow) | ||
return; | ||
if (!(0, index_1.isGlueEvent)(event)) | ||
return; | ||
const [, isHandshakeMessage, payload] = event.data; | ||
if (isHandshakeMessage) | ||
return; | ||
glue.recv(payload); | ||
} | ||
function close() { | ||
globalThis.removeEventListener("message", messageHandler); | ||
glue.close(); | ||
onClosed === null || onClosed === void 0 ? void 0 : onClosed(); | ||
} | ||
const iframeWindow = await (0, util_1.checkAndRetryUntilSuccess)(() => iframeElement.contentWindow || undefined); | ||
const childWindowSocket = await (0, child_window_1.createChildWindowSocket)({ | ||
child: iframeWindow, | ||
childOrigin: iframeOrigin, | ||
onClosed, | ||
}); | ||
onceIframeReloaded(iframeElement, childWindowSocket.close); | ||
return childWindowSocket; | ||
} | ||
exports.createIframeSocket = createIframeSocket; | ||
async function handshake(iframeElement) { | ||
let done; | ||
globalThis.addEventListener("message", handshakeHandler); | ||
ping(); | ||
await (0, misc_1.checkAndRetryUntilSuccess)(() => done, ping, 100, 100); | ||
function ping() { | ||
var _a; | ||
(_a = iframeElement.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage([key, true, "ping"], "*"); | ||
} | ||
function handshakeHandler(event) { | ||
if (event.source !== iframeElement.contentWindow) | ||
return; | ||
if (!(0, index_1.isGlueEvent)(event)) | ||
return; | ||
const [, isHandshakeMessage, payload] = event.data; | ||
if (!isHandshakeMessage) | ||
return; | ||
if (payload === "pong") { | ||
done = true; | ||
globalThis.removeEventListener("message", handshakeHandler); | ||
} | ||
} | ||
} | ||
function onceIframeReloaded(iframeElement, fn) { | ||
@@ -66,0 +19,0 @@ iframeElement.addEventListener("load", loadHandler); |
import { Closer, Reader } from "../socket"; | ||
declare const key = "<glue>"; | ||
export interface Glue extends Closer, Reader { | ||
@@ -8,11 +7,1 @@ recv(data: Uint8Array | string): void; | ||
export declare function createGlue(): Glue; | ||
export interface GlueEvent { | ||
data: [ | ||
glueKey: typeof key, | ||
isHandshakeMessage: boolean, | ||
payload: Uint8Array | string | ||
]; | ||
source: typeof globalThis | Window; | ||
} | ||
export declare function isGlueEvent(event: any): event is GlueEvent; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isGlueEvent = exports.createGlue = exports.getGlue = void 0; | ||
exports.createGlue = exports.getGlue = void 0; | ||
const observer_1 = require("@pbkit/runtime/async/observer"); | ||
const misc_1 = require("../misc"); | ||
const misc_2 = require("./misc"); | ||
const util_1 = require("./misc/util"); | ||
const key = "<glue>"; | ||
@@ -27,3 +27,3 @@ function getGlue() { | ||
throw new Error("Glue has been closed."); | ||
queue.push(typeof data === "string" ? (0, misc_2.str2u8s)(data) : data); | ||
queue.push(typeof data === "string" ? (0, util_1.str2u8s)(data) : data); | ||
wait === null || wait === void 0 ? void 0 : wait.resolve(); | ||
@@ -51,11 +51,1 @@ }, | ||
exports.createGlue = createGlue; | ||
function isGlueEvent(event) { | ||
if (!Array.isArray(event.data)) | ||
return false; | ||
if (event.data.length < 3) | ||
return false; | ||
if (event.data[0] !== key) | ||
return false; | ||
return true; | ||
} | ||
exports.isGlueEvent = isGlueEvent; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createIosSocket = void 0; | ||
const misc_1 = require("./misc"); | ||
const util_1 = require("./misc/util"); | ||
const index_1 = require("./index"); | ||
@@ -12,3 +12,3 @@ // https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537172-add | ||
async write(data) { | ||
return iosGlue.postMessage((0, misc_1.u8s2str)(data)).then(() => data.byteLength); | ||
return iosGlue.postMessage((0, util_1.u8s2str)(data)).then(() => data.byteLength); | ||
}, | ||
@@ -19,3 +19,3 @@ }; | ||
async function getIosGlue() { | ||
return await (0, misc_1.checkAndRetryUntilSuccess)(() => { var _a, _b; return ((_b = (_a = globalThis.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.glue) || undefined; }); | ||
return await (0, util_1.checkAndRetryUntilSuccess)(() => { var _a, _b; return ((_b = (_a = globalThis.webkit) === null || _a === void 0 ? void 0 : _a.messageHandlers) === null || _b === void 0 ? void 0 : _b.glue) || undefined; }); | ||
} |
@@ -1,6 +0,7 @@ | ||
import { Socket } from "../socket"; | ||
import { Closer, Socket } from "../socket"; | ||
export interface CreateParentWindowSocketConfig { | ||
parent?: Window | null; | ||
parentWindowOrigin: string; | ||
parentOrigin: string; | ||
onClosed?: () => void; | ||
} | ||
export declare function createParentWindowSocket(config: CreateParentWindowSocketConfig): Promise<Socket>; | ||
export declare function createParentWindowSocket(config: CreateParentWindowSocketConfig): Promise<Closer & Socket>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createParentWindowSocket = void 0; | ||
const observer_1 = require("@pbkit/runtime/async/observer"); | ||
const index_1 = require("./index"); | ||
// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API | ||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage | ||
const key = "<glue>"; | ||
const web_1 = require("./misc/web"); | ||
async function createParentWindowSocket(config) { | ||
const { parent = globalThis.parent, parentWindowOrigin } = config; | ||
const { parent = globalThis.parent, parentOrigin, onClosed } = config; | ||
if (!(parent === null || parent === void 0 ? void 0 : parent.postMessage)) | ||
@@ -15,24 +12,8 @@ throw new Error("There is no parent window."); | ||
throw new Error("Invalid parent window."); | ||
const wait = (0, observer_1.defer)(); | ||
let handshakeIsDone = false; | ||
globalThis.addEventListener("message", messageHandler); | ||
globalThis.addEventListener("message", handshakeHandler); | ||
const glue = (0, index_1.getGlue)(); | ||
globalThis.addEventListener("message", (event) => { | ||
if (event.source !== parent) | ||
return; | ||
if (!(0, index_1.isGlueEvent)(event)) | ||
return; | ||
const [, isHandshakeMessage, payload] = event.data; | ||
if (isHandshakeMessage) { | ||
if (payload === "ping") { | ||
parent.postMessage([key, true, "pong"], "*"); | ||
wait.resolve(); | ||
} | ||
} | ||
else { | ||
glue.recv(payload); | ||
} | ||
}); | ||
setTimeout(() => { | ||
wait.reject(new Error("Handshake timeout.")); | ||
}, 500); | ||
await wait; | ||
const connId = setInterval(syn, 100); | ||
syn(); | ||
return { | ||
@@ -42,8 +23,61 @@ read: glue.read, | ||
const length = data.byteLength; | ||
const { postMessage } = parent; | ||
postMessage([key, false, data], parentWindowOrigin, [data.buffer]); | ||
return length; | ||
const success = (0, web_1.postGlueMessage)({ | ||
target: parent, | ||
targetOrigin: parentOrigin, | ||
payload: data, | ||
}); | ||
if (!success) | ||
close(); | ||
return success ? length : 0; | ||
}, | ||
close, | ||
}; | ||
function close() { | ||
clearInterval(connId); | ||
globalThis.removeEventListener("message", messageHandler); | ||
globalThis.removeEventListener("message", handshakeHandler); | ||
glue.close(); | ||
onClosed === null || onClosed === void 0 ? void 0 : onClosed(); | ||
} | ||
function syn() { | ||
const success = (0, web_1.postGlueHandshakeMessage)({ | ||
target: parent, | ||
targetOrigin: parentOrigin, | ||
payload: "syn", | ||
}); | ||
if (!success) | ||
close(); | ||
} | ||
function ack() { | ||
handshakeIsDone = true; | ||
const success = (0, web_1.postGlueHandshakeMessage)({ | ||
target: parent, | ||
targetOrigin: parentOrigin, | ||
payload: "ack", | ||
}); | ||
if (!success) | ||
close(); | ||
} | ||
function messageHandler(e) { | ||
if (e.source !== parent) | ||
return; | ||
if (!(0, web_1.isGlueEvent)(e)) | ||
return; | ||
const [, data] = e.data; | ||
glue.recv(data); | ||
} | ||
function handshakeHandler(event) { | ||
if (event.source !== parent) | ||
return; | ||
if (!(0, web_1.isGlueHandshakeEvent)(event)) | ||
return; | ||
const [, payload] = event.data; | ||
if (payload === "syn-ack") { | ||
if (handshakeIsDone) | ||
close(); | ||
else | ||
ack(); | ||
} | ||
} | ||
} | ||
exports.createParentWindowSocket = createParentWindowSocket; |
{ | ||
"name": "@pbkit/wrp", | ||
"version": "0.0.13", | ||
"version": "0.1.0", | ||
"author": "JongChan Choi <jong@chan.moe>", | ||
@@ -5,0 +5,0 @@ "license": "(MIT OR Apache-2.0)", |
137281
76
2904