@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 +19 -0
- package/README.md +76 -0
- package/build/MMLWebRunnerClient.d.ts +20 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +58 -0
- package/build/index.js.map +7 -0
- package/package.json +33 -0
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
|
+
[](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
|
+
}
|
package/build/index.d.ts
ADDED
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
|
+
}
|