-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add library build that take worker instance
- Loading branch information
Showing
13 changed files
with
411 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Copyright 2018 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import compiler from '@ampproject/rollup-plugin-closure-compiler'; | ||
import { terser } from 'rollup-plugin-terser'; | ||
import replace from '@rollup/plugin-replace'; | ||
import { babelPlugin } from './rollup.plugins.js'; | ||
import path from 'path'; | ||
|
||
// Compile plugins should always be added at the end of the plugin list. | ||
const compilePlugins = [ | ||
compiler({ | ||
env: 'CUSTOM', | ||
}), | ||
terser(), | ||
]; | ||
|
||
export default [ | ||
{ | ||
input: path.join(__dirname, '../output/main-thread/lib.js'), | ||
output: { | ||
file: 'dist/lib/main.mjs', | ||
format: 'esm', | ||
sourcemap: true, | ||
}, | ||
plugins: [ | ||
replace({ | ||
WORKER_DOM_DEBUG: false, | ||
}), | ||
babelPlugin({ | ||
transpileToES5: false, | ||
allowConsole: false, | ||
}), | ||
...compilePlugins, | ||
], | ||
}, | ||
{ | ||
input: path.join(__dirname, '../output/worker-thread/lib.js'), | ||
output: { | ||
file: 'dist/lib/worker.mjs', | ||
format: 'esm', | ||
sourcemap: true, | ||
}, | ||
plugins: [ | ||
replace({ | ||
WORKER_DOM_DEBUG: false, | ||
}), | ||
babelPlugin({ | ||
transpileToES5: false, | ||
allowConsole: false, | ||
}), | ||
...compilePlugins, | ||
], | ||
}, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# worker-dom as package with webpack | ||
|
||
## Webpack settings | ||
|
||
- Add `@ampproject/worker-dom` | ||
- Add `worker-plugin` or `worker-loader` to create worker on webpack | ||
|
||
In this README, we use `worker-plugin`. | ||
|
||
```js | ||
// webpack.config.js | ||
const WorkerPlugin = require("worker-plugin"); | ||
module.exports = { | ||
// ... | ||
plugins: [new WorkerPlugin()] | ||
} | ||
``` | ||
|
||
## Example | ||
|
||
```js | ||
// worker.js | ||
import { ready } from "@ampproject/worker-dom/dist/lib/worker"; | ||
|
||
ready.then(() =>{ | ||
document.body.firstChild.textContent = 'hello from worker mutate'; | ||
}); | ||
``` | ||
|
||
```js | ||
// main.js | ||
import { attachWorker } from "@ampproject/worker-dom/dist/lib/main"; | ||
|
||
// Create worker by your own way | ||
// This code uses worker-plugin | ||
const worker = new Worker("./worker.js", { type: "module" }); | ||
|
||
// attach worker to dom | ||
attachWorker(document.querySelector('#root'), worker); | ||
``` | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"build": "webpack --mode development" | ||
}, | ||
"devDependencies": { | ||
"html-webpack-plugin": "^4.2.1", | ||
"webpack": "^4.43.0", | ||
"webpack-cli": "^3.3.11", | ||
"webpack-dev-server": "^3.10.3", | ||
"worker-plugin": "^4.0.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Document</title> | ||
</head> | ||
<body> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { attachWorker } from '@ampproject/worker-dom/dist/lib/main.mjs'; | ||
|
||
const el = document.createElement('main'); | ||
el.innerHTML = ` | ||
<div> | ||
<h1>main</h1> | ||
<button>click</button> | ||
</div> | ||
`; | ||
document.body.appendChild(el); | ||
|
||
const worker = new Worker('./worker.js', { type: 'module' }); | ||
|
||
attachWorker(el, worker); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { ready } from '@ampproject/worker-dom/dist/lib/worker.mjs'; | ||
|
||
async function run() { | ||
await ready; | ||
|
||
// dom mutation | ||
const el = document.createElement('h2'); | ||
el.textContent = 'hello from worker'; | ||
document.body.appendChild(el); | ||
|
||
// handler | ||
const button = document.querySelector('button'); | ||
button.onclick = (ev) => { | ||
console.log('button:onclick', ev); | ||
}; | ||
} | ||
|
||
run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Copyright 2018 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
const path = require('path'); | ||
const HTMLPlugin = require('html-webpack-plugin'); | ||
const WorkerPlugin = require('worker-plugin'); | ||
|
||
module.exports = { | ||
mode: 'development', | ||
resolve: { | ||
alias: { | ||
'@ampproject/worker-dom': path.join(__dirname, '../../'), | ||
}, | ||
}, | ||
plugins: [ | ||
new WorkerPlugin(), | ||
new HTMLPlugin({ | ||
template: path.join(__dirname, 'src/index.html'), | ||
}), | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { HydrateableNode } from '../transfer/TransferrableNodes'; | ||
import { TransferrableKeys } from '../transfer/TransferrableKeys'; | ||
|
||
export function buildWorkerString( | ||
workerDOMScript: string, | ||
authorScript: string, | ||
authorURL: string, | ||
strings: string[], | ||
skeleton: HydrateableNode, | ||
cssKeys: string[], | ||
globalEventHandlerKeys: string[], | ||
size: [number, number], | ||
localStorageData: { [key: string]: string }, | ||
sessionStorageData: { [key: string]: string }, | ||
): string { | ||
return `'use strict'; | ||
(function(){ | ||
${workerDOMScript} | ||
self['window'] = self; | ||
var workerDOM = WorkerThread.workerDOM; | ||
WorkerThread.hydrate( | ||
workerDOM.document, | ||
${JSON.stringify(strings)}, | ||
${JSON.stringify(skeleton)}, | ||
${JSON.stringify(cssKeys)}, | ||
${JSON.stringify(globalEventHandlerKeys)}, | ||
${JSON.stringify(size)}, | ||
${JSON.stringify(localStorageData)}, | ||
${JSON.stringify(sessionStorageData)} | ||
); | ||
workerDOM.document[${TransferrableKeys.observe}](this); | ||
Object.keys(workerDOM).forEach(function(k){self[k]=workerDOM[k]}); | ||
}).call(self); | ||
${authorScript} | ||
//# sourceURL=${encodeURI(authorURL)}`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/** | ||
* Copyright 2018 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import { MutationFromWorker, MessageType, MessageFromWorker, MessageToWorker } from '../transfer/Messages'; | ||
import { MutatorProcessor } from './mutator'; | ||
import { NodeContext } from './nodes'; | ||
import { StringContext } from './strings'; | ||
import { TransferrableKeys } from '../transfer/TransferrableKeys'; | ||
import { InboundWorkerDOMConfiguration, normalizeConfiguration, WorkerDOMConfiguration } from './configuration'; | ||
import { WorkerContext } from './worker'; | ||
import { ObjectContext } from './object-context'; | ||
import { readableMessageToWorker, readableHydrateableRootNode } from './debugging'; | ||
import { createHydrateableRootNode } from './serialize'; | ||
|
||
const ALLOWABLE_MESSAGE_TYPES = [MessageType.MUTATE, MessageType.HYDRATE]; | ||
|
||
export function attachWorker( | ||
baseElement: HTMLElement, | ||
worker: Worker, | ||
config: InboundWorkerDOMConfiguration = { | ||
authorURL: '[external-instance]', | ||
domURL: '[external-instance]', | ||
}, | ||
) { | ||
const stringContext = new StringContext(); | ||
const objectContext = new ObjectContext(); | ||
const nodeContext = new NodeContext(stringContext, baseElement); | ||
const normalizedConfig = normalizeConfiguration(config); | ||
const workerContext = (new WorkerContextFromInstance(baseElement as HTMLElement, nodeContext, worker, normalizedConfig) as any) as WorkerContext; | ||
const mutatorContext = new MutatorProcessor(stringContext, nodeContext, workerContext, normalizedConfig, objectContext); | ||
|
||
workerContext.worker.onmessage = (message: MessageFromWorker) => { | ||
const { data } = message; | ||
if (!ALLOWABLE_MESSAGE_TYPES.includes(data[TransferrableKeys.type])) { | ||
return; | ||
} | ||
mutatorContext.mutate( | ||
(data as MutationFromWorker)[TransferrableKeys.phase], | ||
(data as MutationFromWorker)[TransferrableKeys.nodes], | ||
(data as MutationFromWorker)[TransferrableKeys.strings], | ||
new Uint16Array(data[TransferrableKeys.mutations]), | ||
); | ||
|
||
if (config.onReceiveMessage) { | ||
config.onReceiveMessage(message); | ||
} | ||
}; | ||
} | ||
|
||
// TODO: Refactor with original | ||
class WorkerContextFromInstance { | ||
private [TransferrableKeys.worker]: Worker; | ||
private nodeContext: NodeContext; | ||
private config: WorkerDOMConfiguration; | ||
|
||
/** | ||
* @param baseElement | ||
* @param nodeContext | ||
* @param workerDOMScript | ||
* @param authorScript | ||
* @param config | ||
*/ | ||
constructor(baseElement: HTMLElement, nodeContext: NodeContext, worker: Worker, config: WorkerDOMConfiguration) { | ||
const selfAsWorkerContext = (this as any) as WorkerContext; | ||
this.nodeContext = nodeContext; | ||
this.config = config; | ||
|
||
const { skeleton, strings } = createHydrateableRootNode(baseElement, config, selfAsWorkerContext); | ||
const cssKeys: Array<string> = []; | ||
const globalEventHandlerKeys: Array<string> = []; | ||
// TODO(mizchi): Can not serialize on postMessage | ||
// TODO(choumx): Sync read of all localStorage and sessionStorage a possible performance bottleneck? | ||
// const localStorageData = config.sanitizer ? config.sanitizer.getStorage(StorageLocation.Local) : window.localStorage; | ||
// const sessionStorageData = config.sanitizer ? config.sanitizer.getStorage(StorageLocation.Session) : window.sessionStorage; | ||
|
||
for (const key in baseElement.style) { | ||
cssKeys.push(key); | ||
} | ||
for (const key in baseElement) { | ||
if (key.startsWith('on')) { | ||
globalEventHandlerKeys.push(key); | ||
} | ||
} | ||
|
||
this[TransferrableKeys.worker] = worker; | ||
worker.postMessage({ | ||
__init__: [ | ||
strings, | ||
skeleton, | ||
cssKeys, | ||
globalEventHandlerKeys, | ||
[window.innerWidth, window.innerHeight], | ||
{}, // localStorage | ||
{}, // sessionStorage | ||
], | ||
}); | ||
|
||
if (WORKER_DOM_DEBUG) { | ||
console.info('debug', 'hydratedNode', readableHydrateableRootNode(baseElement, config, selfAsWorkerContext)); | ||
} | ||
if (config.onCreateWorker) { | ||
config.onCreateWorker(baseElement, strings, skeleton, cssKeys); | ||
} | ||
} | ||
|
||
/** | ||
* Returns the private worker. | ||
*/ | ||
get worker(): Worker { | ||
return this[TransferrableKeys.worker]; | ||
} | ||
|
||
/** | ||
* @param message | ||
*/ | ||
messageToWorker(message: MessageToWorker, transferables?: Transferable[]) { | ||
if (WORKER_DOM_DEBUG) { | ||
console.info('debug', 'messageToWorker', readableMessageToWorker(this.nodeContext, message)); | ||
} | ||
if (this.config.onSendMessage) { | ||
this.config.onSendMessage(message); | ||
} | ||
this.worker.postMessage(message, transferables || []); | ||
} | ||
} |
Oops, something went wrong.