@mml-io/mml-web-runner 0.0.0-experimental-edf5cd7-20250120

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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2023 Improbable MV Limited
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # MML Web Runner
2
+ #### `@mml-io/mml-web-runner`
3
+
4
+ [![npm version](https://img.shields.io/npm/v/@mml-io/mml-web-runner.svg?style=flat)](https://www.npmjs.com/package/@mml-io/mml-web-runner)
5
+
6
+ This package contains classes that provide a simple way to run a `NetworkedDOM | EditableNetworkedDOM` instance in a browser and connect it directly to an `MMLScene`.
7
+
8
+ This functionality allows running MML content directly in a browser as if it were on a server from the local client's perspective.
9
+
10
+ You can connect multiple `MMLWebRunnerClient`s to the same `NetworkedDOM | EditableNetworkedDOM` instance and they will all see the same content.
11
+
12
+ It directly exports the exports of the `@mml-io/networked-dom-web-runner` package to simplify the MML-based usage of what is otherwise NetworkedDOM functionality.
13
+
14
+ ## Example Usage
15
+
16
+ ```typescript
17
+ import { IframeWrapper, MMLScene, registerCustomElementsToWindow } from "@mml-io/mml-web";
18
+ import {
19
+ EditableNetworkedDOM,
20
+ IframeObservableDOMFactory,
21
+ MMLWebRunnerClient,
22
+ } from "@mml-io/mml-web-runner";
23
+ import {
24
+ StandaloneThreeJSAdapter,
25
+ StandaloneThreeJSAdapterControlsType,
26
+ } from "@mml-io/mml-web-threejs-standalone";
27
+
28
+ window.addEventListener("DOMContentLoaded", async () => {
29
+ // Create an iframe to isolate the MML content from the rest of the page
30
+ const { iframeWindow, iframeBody } = await IframeWrapper.create();
31
+
32
+ // Register the MML custom elements to the iframe window
33
+ registerCustomElementsToWindow(iframeWindow);
34
+
35
+ // Create a networked DOM document which acts as the "server" for the MML content
36
+ const networkedDOMDocument = new EditableNetworkedDOM(
37
+ "http://example.com/index.html",
38
+ IframeObservableDOMFactory,
39
+ true,
40
+ );
41
+ /*
42
+ Load MML content. It can run `<script>` tags and they'll execute in an
43
+ isolated iframe context.
44
+
45
+ `load()` can be called multiple times and the clients will be updated.
46
+ */
47
+ networkedDOMDocument.load(`
48
+ <m-cube color="red" id="my-cube"></m-cube>
49
+ <m-light x="1" y="2" z="3" intensity="50" type="point"></m-light>
50
+ `);
51
+
52
+ // Create an element to render the MML content
53
+ const clientElement = document.createElement("div");
54
+ clientElement.style.position = "relative";
55
+ clientElement.style.backgroundColor = "gray";
56
+ clientElement.style.width = "400px";
57
+ clientElement.style.height = "400px";
58
+ document.body.append(clientElement);
59
+
60
+ // Create an MML scene which will contain the MML content that the client will view
61
+ const mmlScene = new MMLScene(clientElement);
62
+
63
+ // Create a client that will connect to the NetworkedDOM document and synchronize it to the MML scene
64
+ const client = new MMLWebRunnerClient(iframeWindow, iframeBody, mmlScene);
65
+
66
+ // Create a graphics adapter that will render the MML content from the MMLScene using ThreeJS
67
+ const graphicsAdapter = await StandaloneThreeJSAdapter.create(clientElement, {
68
+ controlsType: StandaloneThreeJSAdapterControlsType.DragFly,
69
+ });
70
+ // Initialize the MML scene with the graphics adapter
71
+ mmlScene.init(graphicsAdapter);
72
+
73
+ // Connect the client to the NetworkedDOM document to get the MML content
74
+ client.connect(networkedDOMDocument);
75
+ });
76
+ ```
@@ -0,0 +1,20 @@
1
+ import { GraphicsAdapter, IMMLScene } from "@mml-io/mml-web";
2
+ import { EditableNetworkedDOM, NetworkedDOM } from "@mml-io/networked-dom-document";
3
+ /**
4
+ * The MMLWebRunnerClient class can be used to view and interact with a NetworkedDOM document instance that is available
5
+ * directly in the browser (rather than exposed over the network). This is useful for usage modes where the document
6
+ * does not need to be available to other clients, such as a single-user or an edit/preview mode.
7
+ *
8
+ * The class takes arguments for where the view of the document should be synchronized to in the DOM, and which window
9
+ * instance to use to create any other elements (to allow for using iframes to isolate the document from the rest of
10
+ * the page).
11
+ */
12
+ export declare class MMLWebRunnerClient {
13
+ private windowTarget;
14
+ private remoteHolderElement;
15
+ private mmlScene;
16
+ private connectedState;
17
+ constructor(windowTarget: Window, remoteHolderElement: HTMLElement, mmlScene: IMMLScene<GraphicsAdapter>);
18
+ dispose(): void;
19
+ connect(document: NetworkedDOM | EditableNetworkedDOM): void;
20
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./MMLWebRunnerClient";
2
+ export * from "@mml-io/networked-dom-web-runner";
package/build/index.js ADDED
@@ -0,0 +1,58 @@
1
+ // src/MMLWebRunnerClient.ts
2
+ import { RemoteDocumentWrapper } from "@mml-io/mml-web";
3
+ import { NetworkedDOMWebRunnerClient } from "@mml-io/networked-dom-web-runner";
4
+ var MMLWebRunnerClient = class {
5
+ constructor(windowTarget, remoteHolderElement, mmlScene) {
6
+ this.windowTarget = windowTarget;
7
+ this.remoteHolderElement = remoteHolderElement;
8
+ this.mmlScene = mmlScene;
9
+ this.connectedState = null;
10
+ }
11
+ dispose() {
12
+ if (!this.connectedState) {
13
+ return;
14
+ }
15
+ this.connectedState.networkedDOMWebRunnerClient.dispose();
16
+ this.connectedState = null;
17
+ }
18
+ connect(document) {
19
+ let overriddenHandler = null;
20
+ const eventHandler = (element, event) => {
21
+ if (!overriddenHandler) {
22
+ throw new Error("overriddenHandler not set");
23
+ }
24
+ overriddenHandler(element, event);
25
+ };
26
+ const remoteDocumentWrapper = new RemoteDocumentWrapper(
27
+ window.location.href,
28
+ this.windowTarget,
29
+ this.mmlScene,
30
+ eventHandler
31
+ );
32
+ this.remoteHolderElement.append(remoteDocumentWrapper.remoteDocument);
33
+ overriddenHandler = (element, event) => {
34
+ if (!networkedDOMWebRunnerClient.connectedState) {
35
+ throw new Error("connectedState not set");
36
+ }
37
+ networkedDOMWebRunnerClient.connectedState.domWebsocket.handleEvent(element, event);
38
+ };
39
+ const networkedDOMWebRunnerClient = new NetworkedDOMWebRunnerClient(
40
+ false,
41
+ remoteDocumentWrapper.remoteDocument
42
+ );
43
+ networkedDOMWebRunnerClient.connect(document, (time) => {
44
+ remoteDocumentWrapper.setDocumentTime(time);
45
+ });
46
+ this.connectedState = {
47
+ networkedDOMWebRunnerClient,
48
+ remoteDocumentWrapper
49
+ };
50
+ }
51
+ };
52
+
53
+ // src/index.ts
54
+ export * from "@mml-io/networked-dom-web-runner";
55
+ export {
56
+ MMLWebRunnerClient
57
+ };
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/MMLWebRunnerClient.ts", "../src/index.ts"],
4
+ "sourcesContent": ["import { GraphicsAdapter, IMMLScene, RemoteDocumentWrapper } from \"@mml-io/mml-web\";\nimport { EditableNetworkedDOM, NetworkedDOM } from \"@mml-io/networked-dom-document\";\nimport { NetworkedDOMWebRunnerClient } from \"@mml-io/networked-dom-web-runner\";\n\n/**\n * The MMLWebRunnerClient class can be used to view and interact with a NetworkedDOM document instance that is available\n * directly in the browser (rather than exposed over the network). This is useful for usage modes where the document\n * does not need to be available to other clients, such as a single-user or an edit/preview mode.\n *\n * The class takes arguments for where the view of the document should be synchronized to in the DOM, and which window\n * instance to use to create any other elements (to allow for using iframes to isolate the document from the rest of\n * the page).\n */\nexport class MMLWebRunnerClient {\n private connectedState: {\n networkedDOMWebRunnerClient: NetworkedDOMWebRunnerClient;\n remoteDocumentWrapper: RemoteDocumentWrapper<GraphicsAdapter>;\n } | null = null;\n\n constructor(\n private windowTarget: Window,\n private remoteHolderElement: HTMLElement,\n private mmlScene: IMMLScene<GraphicsAdapter>,\n ) {}\n\n public dispose() {\n if (!this.connectedState) {\n return;\n }\n this.connectedState.networkedDOMWebRunnerClient.dispose();\n this.connectedState = null;\n }\n\n public connect(document: NetworkedDOM | EditableNetworkedDOM) {\n let overriddenHandler: ((element: HTMLElement, event: CustomEvent) => void) | null = null;\n const eventHandler = (element: HTMLElement, event: CustomEvent) => {\n if (!overriddenHandler) {\n throw new Error(\"overriddenHandler not set\");\n }\n overriddenHandler(element, event);\n };\n const remoteDocumentWrapper = new RemoteDocumentWrapper(\n window.location.href,\n this.windowTarget,\n this.mmlScene,\n eventHandler,\n );\n this.remoteHolderElement.append(remoteDocumentWrapper.remoteDocument);\n overriddenHandler = (element: HTMLElement, event: CustomEvent) => {\n if (!networkedDOMWebRunnerClient.connectedState) {\n throw new Error(\"connectedState not set\");\n }\n networkedDOMWebRunnerClient.connectedState.domWebsocket.handleEvent(element, event);\n };\n\n const networkedDOMWebRunnerClient = new NetworkedDOMWebRunnerClient(\n false,\n remoteDocumentWrapper.remoteDocument,\n );\n networkedDOMWebRunnerClient.connect(document, (time: number) => {\n remoteDocumentWrapper.setDocumentTime(time);\n });\n this.connectedState = {\n networkedDOMWebRunnerClient,\n remoteDocumentWrapper,\n };\n }\n}\n", "export * from \"./MMLWebRunnerClient\";\nexport * from \"@mml-io/networked-dom-web-runner\";\n"],
5
+ "mappings": ";AAAA,SAAqC,6BAA6B;AAElE,SAAS,mCAAmC;AAWrC,IAAM,qBAAN,MAAyB;AAAA,EAM9B,YACU,cACA,qBACA,UACR;AAHQ;AACA;AACA;AARV,SAAQ,iBAGG;AAAA,EAMR;AAAA,EAEI,UAAU;AACf,QAAI,CAAC,KAAK,gBAAgB;AACxB;AAAA,IACF;AACA,SAAK,eAAe,4BAA4B,QAAQ;AACxD,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEO,QAAQ,UAA+C;AAC5D,QAAI,oBAAiF;AACrF,UAAM,eAAe,CAAC,SAAsB,UAAuB;AACjE,UAAI,CAAC,mBAAmB;AACtB,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AACA,wBAAkB,SAAS,KAAK;AAAA,IAClC;AACA,UAAM,wBAAwB,IAAI;AAAA,MAChC,OAAO,SAAS;AAAA,MAChB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACF;AACA,SAAK,oBAAoB,OAAO,sBAAsB,cAAc;AACpE,wBAAoB,CAAC,SAAsB,UAAuB;AAChE,UAAI,CAAC,4BAA4B,gBAAgB;AAC/C,cAAM,IAAI,MAAM,wBAAwB;AAAA,MAC1C;AACA,kCAA4B,eAAe,aAAa,YAAY,SAAS,KAAK;AAAA,IACpF;AAEA,UAAM,8BAA8B,IAAI;AAAA,MACtC;AAAA,MACA,sBAAsB;AAAA,IACxB;AACA,gCAA4B,QAAQ,UAAU,CAAC,SAAiB;AAC9D,4BAAsB,gBAAgB,IAAI;AAAA,IAC5C,CAAC;AACD,SAAK,iBAAiB;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AClEA,cAAc;",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@mml-io/mml-web-runner",
3
+ "version": "0.0.0-experimental-edf5cd7-20250120",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "main": "./build/index.js",
8
+ "types": "./build/index.d.ts",
9
+ "type": "module",
10
+ "files": [
11
+ "/build"
12
+ ],
13
+ "scripts": {
14
+ "type-check": "tsc --noEmit",
15
+ "build": "tsx ./build.ts --build",
16
+ "iterate": "tsx ./build.ts --watch",
17
+ "lint": "eslint \"./**/*.{js,jsx,ts,tsx}\" --max-warnings 0",
18
+ "lint-fix": "eslint \"./**/*.{js,jsx,ts,tsx}\" --fix",
19
+ "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
20
+ "test-iterate": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --watch"
21
+ },
22
+ "dependencies": {
23
+ "@mml-io/networked-dom-web-runner": "0.0.0-experimental-edf5cd7-20250120"
24
+ },
25
+ "devDependencies": {
26
+ "jest-canvas-mock": "2.5.2",
27
+ "jest-environment-jsdom": "29.7.0",
28
+ "jest-expect-message": "1.1.3",
29
+ "jest-fetch-mock": "3.0.3",
30
+ "resize-observer-polyfill": "1.5.1"
31
+ },
32
+ "gitHead": "4d1344cf69e44b65d059011cb66a564c47d23f2d"
33
+ }