microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.20.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/npm/qsharp/src/workers/browser.ts

111lines · modeblame

c23c2ae4Mine Starks2 years ago1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4import * as wasm from "../../lib/web/qsc_wasm.js";
5import { log } from "../log.js";
6import {
7IServiceEventMessage,
8IServiceProxy,
9RequestMessage,
10ServiceMethods,
11ServiceProtocol,
12createProxyInternal,
13initService,
14} from "./common.js";
15
16/**
17* Creates an initializes a service, setting it up to receive requests.
18* This function to be is used in the worker.
19*
20* @param serviceProtocol An object that describes the service: its constructor, methods and events
21* @returns A message handler to be assigned to the `self.onmessage` handler in a web worker
22*/
23export function createWorker<
24TService extends ServiceMethods<TService>,
25TServiceEventMsg extends IServiceEventMessage,
26>(
27serviceProtocol: ServiceProtocol<TService, TServiceEventMsg>,
28): (e: MessageEvent) => void {
29let invokeService: ((req: RequestMessage<TService>) => Promise<void>) | null =
30null;
31
32// This export should be assigned to 'self.onmessage' in a WebWorker
33return function messageHandler(e: MessageEvent) {
34const data = e.data;
35
36if (!data.type || typeof data.type !== "string") {
37log.error(`Unrecognized msg: ${data}`);
38return;
39}
40
41switch (data.type) {
42case "init":
43{
f383f753Mine Starks1 years ago44wasm.initSync({ module: data.wasmModule });
c23c2ae4Mine Starks2 years ago45
46invokeService = initService<TService, TServiceEventMsg>(
47self.postMessage.bind(self),
48serviceProtocol,
49wasm,
50data.qscLogLevel,
51);
52}
53break;
54default:
55if (!invokeService) {
56log.error(
57`Received message before the service was initialized: %o`,
58data,
59);
60} else {
61invokeService(data);
62}
63}
64};
65}
66
67/**
68* Creates and initializes a service in a web worker, and returns a proxy for the service
69* to be used from the main thread.
70*
71* @param workerArg The service web worker or the URL of the web worker script.
72* @param wasmModule The wasm module to initialize the service with
73* @param serviceProtocol An object that describes the service: its constructor, methods and events
74* @returns A proxy object that implements the service interface.
75* This interface can now be used as if calling into the real service,
76* and the calls will be proxied to the web worker.
77*/
78export function createProxy<
79TService extends ServiceMethods<TService>,
80TServiceEventMsg extends IServiceEventMessage,
81>(
82workerArg: string | Worker,
83wasmModule: WebAssembly.Module,
84serviceProtocol: ServiceProtocol<TService, TServiceEventMsg>,
85): TService & IServiceProxy {
86// Create or use the WebWorker
87const worker =
88typeof workerArg === "string" ? new Worker(workerArg) : workerArg;
89
90// Send it the Wasm module to instantiate
91worker.postMessage({
92type: "init",
93wasmModule,
94qscLogLevel: log.getLogLevel(),
95});
96
97// If you lose the 'this' binding, some environments have issues
98const postMessage = worker.postMessage.bind(worker);
99const onTerminate = () => worker.terminate();
100
101// Create the proxy which will forward method calls to the worker
102const proxy = createProxyInternal<TService, TServiceEventMsg>(
103postMessage,
104onTerminate,
105serviceProtocol.methods,
106);
107
108// Let proxy handle response and event messages from the worker
109worker.onmessage = (ev) => proxy.onMsgFromWorker(ev.data);
110return proxy;
111}