microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
source/npm/qsharp/README.md
70lines · modecode
| 1 | # qsharp npm module |
| 2 | |
| 3 | This package contains the qsharp compiler and language service functionality shipped for consumption via npm. |
| 4 | |
| 5 | The source is written in TypeScript, which is compiled to ECMAScript modules in the ./dist directory. |
| 6 | The wasm binaries from the Rust builds are copied to the ./lib directory. |
| 7 | |
| 8 | Consuming browser projects should import from this module and use a bundler to create their |
| 9 | own JavaScript bundle, and also copy the wasm file to their project and provide the URL |
| 10 | to it when calling the `loadWasmModule` method so it may be located and loaded. |
| 11 | |
| 12 | ## Node and browser support |
| 13 | |
| 14 | wasm-bindgen generates different files for the browser and Node.js environments. The wasm is slightly |
| 15 | different, and the loader code is quite different. This can be seen in `./lib/web/qsc_wasm.cjs` |
| 16 | and `./lib/nodejs/qsc_wasm.js` files respectively. Specifically, the web environment loads the wasm |
| 17 | file using async web APIs such as `fetch` with a URI, and Node.js uses `require` to load the `fs` module |
| 18 | and calls to `readFileSync`. Once the wasm module is loaded however, the exported APIs are used |
| 19 | in a similar manner. |
| 20 | |
| 21 | To support using this npm package from both environments, the package uses "conditional exports" |
| 22 | <https://nodejs.org/dist/latest-v18.x/docs/api/packages.html#conditional-exports> to expose one |
| 23 | entry point for Node.js, and another for browsers. The distinct entry points uses their respective |
| 24 | loader to load the wasm module for the platform, and then expose functionality that uses the |
| 25 | loaded module via common code. |
| 26 | |
| 27 | When bundling for the web, bundlers such as esbuild will automatically use the default entry point, |
| 28 | whereas when loaded as a Node.js module, it will use the "node" entry point. |
| 29 | |
| 30 | Note that TypeScript seems to add the ['import', 'types', 'node'] conditions by default when |
| 31 | searching the Node.js `exports`, and so will always find the 'node' export before the 'default' |
| 32 | export. To resolve this, a 'browser' condition was added (which is same as 'default' but earlier |
| 33 | than 'node') and the tsconfig compiler option `"customConditions": ["browser"]` should be added |
| 34 | (requires TypeScript 5.0 or later). esbuild also adds the 'browser' condition when bundling for |
| 35 | the browser (see <https://esbuild.github.io/api/#how-conditions-work>). |
| 36 | |
| 37 | ## Design |
| 38 | |
| 39 | This package provides two services, the compiler and the language service. |
| 40 | |
| 41 | The API for using these services is similar whether using a browser or Node.js, |
| 42 | and whether running in the main thread or a worker thread. You instantiate the service |
| 43 | and call operations on it which complete in the order called. |
| 44 | |
| 45 | All operations return a Promise which resolves then the operation is complete. Some operations |
| 46 | may also emit events, such as debug messages or state dumps as they are processed. The service |
| 47 | itself can also emit events which can be subscribed to using `addEventListener`. |
| 48 | |
| 49 | See the Q# playground code at <https://github.com/microsoft/qsharp/tree/main/source/playground> for |
| 50 | an example of code that uses this package. The unit tests at |
| 51 | <https://github.com/microsoft/qsharp/tree/main/source/npm/test> are also a good reference. |
| 52 | |
| 53 | Promises, Events, and Cancellation are based on JavaScript or Web standards, or the VS Code API: |
| 54 | |
| 55 | - Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises> |
| 56 | - EventTarget <https://developer.mozilla.org/en-US/docs/Web/API/EventTarget> |
| 57 | - Event <https://developer.mozilla.org/en-US/docs/Web/API/Event/Event> |
| 58 | - VS Code API for CancellationToken <https://code.visualstudio.com/api/references/vscode-api#CancellationToken> |
| 59 | |
| 60 | The standard Web APIs for custom events were added to Node.js in v16.17. <https://nodejs.org/dist/v16.17.0/docs/api/events.html>, but behind an experimental flag. As CustomEvent is not on |
| 61 | the global by default until v19 or later, the code will use Event with a 'detail' |
| 62 | property manually set until v20 is in common use. |
| 63 | |
| 64 | The VS Code implementation for cancellation tokens is viewable in their source code |
| 65 | at <src/vs/base/common/cancellation.ts>. This code uses a simplified version of that API. |
| 66 | |
| 67 | ## Testing |
| 68 | |
| 69 | Node.js tests can be run via `node --test` (see |
| 70 | <https://nodejs.org/dist/latest-v18.x/docs/api/test.html#test-runner-execution-model>). |
| 71 | |