Skip to content

Commit

Permalink
refactor w/ tasks array
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Sep 20, 2021
1 parent c5fa8ef commit 811a2af
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 117 deletions.
5 changes: 4 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ function managlePropsPlugin() {
$documentReadyState$: '',
$documentReferrer$: '',
$documentTitle$: '',
$error$: '',
$errors$: '',
$extraInstructions$: '',
$firstScriptId$: '',
$importScripts$: '',
Expand All @@ -399,6 +399,7 @@ function managlePropsPlugin() {
$instances$: '',
$interfaces$: '',
$interfaceType$: '',
$items: '',
$isInitialized$: '',
$isPromise$: '',
$location$: '',
Expand All @@ -410,6 +411,8 @@ function managlePropsPlugin() {
$postMessage$: '',
$rtnValue$: '',
$scopePath$: '',
$stateProp$: '',
$tasks$: '',
$url$: '',
$window$: '',
$winId$: '',
Expand Down
120 changes: 61 additions & 59 deletions src/lib/sandbox/main-access-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,78 +14,80 @@ export const mainAccessHandler = async (
winCtx: MainWindowContext,
accessReq: MainAccessRequest
) => {
let instanceId = accessReq.$instanceId$;
let accessType = accessReq.$accessType$;
let memberPath = accessReq.$memberPath$;
let memberPathLength = len(memberPath);
let lastMemberName = memberPath[memberPathLength - 1];
let extraInstructions = accessReq.$extraInstructions$ || EMPTY_ARRAY;
let accessRsp: MainAccessResponse = {
$winId$: accessReq.$winId$,
if (accessReq.$forwardToWin$) {
return forwardToWinAccessHandler(winCtx.$worker$!, accessReq);
}

const accessRsp: MainAccessResponse = {
$msgId$: accessReq.$msgId$,
$instanceId$: instanceId,
$winId$: accessReq.$winId$,
$errors$: [],
};
let instance: any;
let rtnValue: any;
let data: any;
let i: number;
let count: number;
let tmr: any;

try {
if (accessReq.$forwardToWin$) {
return forwardToWinAccessHandler(winCtx.$worker$!, accessReq);
}
for (const accessReqTask of accessReq.$tasks$) {
let instanceId = accessReqTask.$instanceId$;
let accessType = accessReqTask.$accessType$;
let memberPath = accessReqTask.$memberPath$;
let memberPathLength = len(memberPath);
let lastMemberName = memberPath[memberPathLength - 1];
let extraInstructions = accessReqTask.$extraInstructions$ || EMPTY_ARRAY;
let instance: any;
let rtnValue: any;
let data: any;
let i: number;
let count: number;
let tmr: any;

instance = getInstance(winCtx, instanceId);
try {
instance = getInstance(winCtx, instanceId);

if (instance) {
for (i = 0; i < memberPathLength - 1; i++) {
instance = instance[memberPath[i]];
}
if (instance) {
for (i = 0; i < memberPathLength - 1; i++) {
instance = instance[memberPath[i]];
}

data = deserializeFromWorker(winCtx, instanceId, accessReq.$data$);
data = deserializeFromWorker(winCtx, instanceId, accessReqTask.$data$);

if (accessType === AccessType.Get) {
if (extraInstructions.includes(ExtraInstruction.WAIT_FOR_INSTANCE_MEMBER)) {
await new Promise<void>((resolve) => {
count = 0;
tmr = setInterval(() => {
if (isMemberInInstance(instance, memberPath) || count > 99) {
clearInterval(tmr);
resolve();
}
count++;
}, 40);
if (accessType === AccessType.Get) {
if (extraInstructions.includes(ExtraInstruction.WAIT_FOR_INSTANCE_MEMBER)) {
await new Promise<void>((resolve) => {
count = 0;
tmr = setInterval(() => {
if (isMemberInInstance(instance, memberPath) || count > 99) {
clearInterval(tmr);
resolve();
}
count++;
}, 40);
});
}
rtnValue = instance[lastMemberName];
} else if (accessType === AccessType.Set) {
instance[lastMemberName] = data;
} else if (accessType === AccessType.CallMethod) {
rtnValue = instance[lastMemberName].apply(instance, data);
extraInstructions.forEach((extra, i) => {
if (extra === ExtraInstruction.SET_INERT_SCRIPT) {
(rtnValue as HTMLScriptElement).type = PT_SCRIPT_TYPE;
}
if (extra === ExtraInstruction.SET_IFRAME_SRCDOC) {
(rtnValue as HTMLIFrameElement).srcdoc = extraInstructions[i + 1] as any;
}
});
}
rtnValue = instance[lastMemberName];
} else if (accessType === AccessType.Set) {
instance[lastMemberName] = data;
} else if (accessType === AccessType.CallMethod) {
rtnValue = instance[lastMemberName].apply(instance, data);
extraInstructions.forEach((extra, i) => {
if (extra === ExtraInstruction.SET_INERT_SCRIPT) {
(rtnValue as HTMLScriptElement).type = PT_SCRIPT_TYPE;
}
if (extra === ExtraInstruction.SET_IFRAME_SRCDOC) {
(rtnValue as HTMLIFrameElement).srcdoc = extraInstructions[i + 1] as any;
}
});
}

if (isPromise(rtnValue)) {
rtnValue = await rtnValue;
accessRsp.$isPromise$ = true;
if (isPromise(rtnValue)) {
rtnValue = await rtnValue;
accessRsp.$isPromise$ = true;
}
accessRsp.$rtnValue$ = serializeForWorker(winCtx, rtnValue, new Set());
} else {
accessRsp.$errors$.push(`Instance ${instanceId} not found`);
}
accessRsp.$rtnValue$ = serializeForWorker(winCtx, rtnValue, new Set());
} else {
accessRsp.$error$ = `Instance ${instanceId} not found`;
} catch (e: any) {
accessRsp.$errors$.push(String(e.stack || e));
}
} catch (e: any) {
accessRsp.$error$ = String(e.stack || e);
}

return accessRsp;
};

Expand Down
21 changes: 9 additions & 12 deletions src/lib/service-worker/sw-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,23 @@ const sendMessageToSandboxFromServiceWorker = (
resolve,
setTimeout(() => {
resolves.delete(accessReq.$msgId$);
resolve({
$winId$: accessReq.$winId$,
$msgId$: accessReq.$msgId$,
$instanceId$: accessReq.$instanceId$,
$error$: `Timeout`,
});
resolve(swMessageError(accessReq, `Timeout`));
}, timeout),
];
resolves.set(accessReq.$msgId$, msgResolve);
client.postMessage(accessReq);
} else {
resolve({
$winId$: accessReq.$winId$,
$msgId$: accessReq.$msgId$,
$instanceId$: accessReq.$instanceId$,
$error$: `No Partytown: ${accessReq}`,
});
resolve(swMessageError(accessReq, `No Party`));
}
});

const swMessageError = (accessReq: MainAccessRequest, err: string) => ({
$winId$: accessReq.$winId$,
$msgId$: accessReq.$msgId$,
$tasks$: [],
$errors$: [err],
});

export const httpRequestFromWebWorker = (self: ServiceWorkerGlobalScope, req: Request) =>
new Promise<Response>(async (resolve) => {
const accessReq: MainAccessRequest = await req.clone().json();
Expand Down
11 changes: 7 additions & 4 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,14 @@ export const enum AccessType {
export interface MainAccessRequest {
$msgId$: number;
$winId$: number;
$forwardToWin$: boolean;
$tasks$: MainAccessRequestTask[];
}

export interface MainAccessRequestTask {
$instanceId$: number;
$interfaceType$: InterfaceType;
$nodeName$?: string;
$forwardToWin$: boolean;
$accessType$: AccessType;
$memberPath$: string[];
$data$?: SerializedTransfer;
Expand All @@ -161,12 +165,11 @@ export const enum ExtraInstruction {
}

export interface MainAccessResponse {
$winId$: number;
$msgId$: number;
$instanceId$: number;
$winId$: number;
$errors$: string[];
$rtnValue$?: SerializedTransfer;
$isPromise$?: any;
$error$?: string;
}

export const enum SerializedType {
Expand Down
60 changes: 31 additions & 29 deletions src/lib/web-worker/worker-access-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,44 @@ import { len } from '../utils';
import { webWorkerCtx } from './worker-constants';

export const workerAccessHandler = (accessReq: MainAccessRequest) => {
let $winId$ = accessReq.$winId$;
let $instanceId$ = accessReq.$instanceId$;
let accessType = accessReq.$accessType$;
let memberPath = accessReq.$memberPath$;
let memberPathLength = len(memberPath);
let lastMemberName = memberPath[memberPathLength - 1];
let accessRsp: MainAccessResponse = {
const accessRsp: MainAccessResponse = {
$msgId$: accessReq.$msgId$,
$winId$,
$instanceId$,
$winId$: accessReq.$winId$,
$errors$: [],
};
let instance: any;
let rtnValue: any;
let data: any;
let i: number;

try {
instance = constructSerializedInstance(accessReq);
for (const accessReqTask of accessReq.$tasks$) {
let accessType = accessReqTask.$accessType$;
let memberPath = accessReqTask.$memberPath$;
let memberPathLength = len(memberPath);
let lastMemberName = memberPath[memberPathLength - 1];

for (i = 0; i < memberPathLength - 1; i++) {
instance = instance[memberPath[i]];
}
let instance: any;
let rtnValue: any;
let data: any;
let i: number;

data = deserializeFromMain(self, memberPath, accessReq.$data$);
try {
instance = constructSerializedInstance({ ...accessReqTask, $winId$: accessReq.$winId$ });

if (accessType === AccessType.Get) {
rtnValue = instance[lastMemberName];
} else if (accessType === AccessType.Set) {
instance[lastMemberName] = data;
} else if (accessType === AccessType.CallMethod) {
rtnValue = instance[lastMemberName].apply(instance, data);
}
for (i = 0; i < memberPathLength - 1; i++) {
instance = instance[memberPath[i]];
}

data = deserializeFromMain(self, memberPath, accessReqTask.$data$);

accessRsp.$rtnValue$ = serializeForMain(rtnValue, new Set());
} catch (e: any) {
accessRsp.$error$ = String(e.stack || e);
if (accessType === AccessType.Get) {
rtnValue = instance[lastMemberName];
} else if (accessType === AccessType.Set) {
instance[lastMemberName] = data;
} else if (accessType === AccessType.CallMethod) {
rtnValue = instance[lastMemberName].apply(instance, data);
}

accessRsp.$rtnValue$ = serializeForMain(rtnValue, new Set());
} catch (e: any) {
accessRsp.$errors$.push(String(e.stack || e));
}
}

webWorkerCtx.$postMessage$([WorkerMessageType.ForwardMainDataResponse, accessRsp]);
Expand Down
26 changes: 16 additions & 10 deletions src/lib/web-worker/worker-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
ExtraInstruction,
InterfaceType,
MainAccessRequest,
MainAccessRequestTask,
MainAccessResponse,
SerializedTransfer,
} from '../types';
import {
debug,
Expand Down Expand Up @@ -33,19 +33,25 @@ const syncRequestToServiceWorker = (
) => {
const $winId$ = target[WinIdKey];
const $instanceId$ = target[InstanceIdKey];
const accessReq: MainAccessRequest = {
$winId$,

const accessReqTask: MainAccessRequestTask = {
$instanceId$,
$interfaceType$: target[InterfaceTypeKey],
$nodeName$: target[NodeNameKey],
$forwardToWin$: webWorkerCtx.$winId$ !== target[WinIdKey],
$msgId$: Math.random(),

$accessType$,
$memberPath$: memberPath,
$data$: serializeForMain(data, new Set()),
$extraInstructions$,
};

const accessReq: MainAccessRequest = {
$msgId$: Math.random(),
$winId$,
$forwardToWin$: webWorkerCtx.$winId$ !== target[WinIdKey],
$tasks$: [accessReqTask],
};

if (debug && typeof accessReq.$winId$ !== 'number') {
console.error(`Target missing winId`, accessReq);
}
Expand All @@ -57,16 +63,16 @@ const syncRequestToServiceWorker = (
// look ma, i'm synchronous (•‿•)

const accessRsp: MainAccessResponse = JSON.parse(xhr.responseText);
const error = accessRsp.$error$;
const errors = accessRsp.$errors$.join();
const isPromise = accessRsp.$isPromise$;
if (error) {
const rtn = deserializeFromMain(target, memberPath, accessRsp.$rtnValue$!);
if (errors) {
if (isPromise) {
return Promise.reject(error);
return Promise.reject(errors);
}
throw new Error(error);
throw new Error(errors);
}

const rtn = deserializeFromMain(target, memberPath, accessRsp.$rtnValue$!);
if (isPromise) {
return Promise.resolve(rtn);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/iframe/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ <h1>Iframe</h1>
</script>
</li>

<li>
<!-- <li>
<strong>parent call, one.two.three.fn(1955)</strong>
<code id="testMemberNames"></code>
<script type="text/partytown">
Expand Down Expand Up @@ -347,7 +347,7 @@ <h1>Iframe</h1>
elm.textContent = iframe.contentDocument.getElementById('output').textContent;
elm.className = 'testMemberNames';
</script>
</li>
</li> -->
</ul>

<hr />
Expand Down

1 comment on commit 811a2af

@vercel
Copy link

@vercel vercel bot commented on 811a2af Sep 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.