diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4949124..d067ac9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+
+# [2.0.0-beta.3](https://github.com/kwonoj/cld3-asm/compare/v2.0.0-beta.2...v2.0.0-beta.3) (2018-10-24)
+
+
+### Features
+
+* **loadmodule:** expose locatebinary ([606ff1b](https://github.com/kwonoj/cld3-asm/commit/606ff1b))
+
+
+
# [2.0.0-beta.2](https://github.com/kwonoj/cld3-asm/compare/v2.0.0-beta.1...v2.0.0-beta.2) (2018-10-23)
diff --git a/README.md b/README.md
index 04c8658..88a9ea2 100644
--- a/README.md
+++ b/README.md
@@ -30,10 +30,10 @@ const cldFactory = await loadModule();
`loadModule` loads wasm binary, initialize it, and returns factory function to create instance of cld3 [language identifier.](https://github.com/kwonoj/cld3-asm/blob/1a86bb67abcebc2cd0e90a83149292eb044e4122/src/cldAsmModule.ts#L70-L97)
```js
-loadModule(environment?: ENVIRONMENT): Promise
+loadModule({timeout?: number, locateBinary?: (wasmPath: string) => string | object}): Promise
```
-It accepts `environment` as option, allow to override running environment and ignores internal runtime detection. This is mostly for [Electron](https://electron.atom.io/)'s renderer process where node.js and `fetch` are available both, to selectively opt-in which way to use. It is important to note `loadModule` doesn't interop incorrect option value matching, like try to load correct binary when supply endpoint to file path with set env to browser.
+It allows to specify timeout to wait until wasm binary compliation & load, also allows to override to lookup binary of wasm. Based on environment & bundling configurations, it is not sufficient to rely on default resolution logic. `locateBinary` expects to return path of binary (i.e remote endpoint url) or loader-specific object if it's bundled by bundler. Check [examples](https://github.com/kwonoj/cld3-asm/tree/master/examples) for usecases.
## Creating language identifier
diff --git a/examples/browser_remote/index.ts b/examples/browser_remote/index.ts
index cab82d4..49e1880 100644
--- a/examples/browser_remote/index.ts
+++ b/examples/browser_remote/index.ts
@@ -1,4 +1,4 @@
-//tslint:disable:no-console
+//tslint:disable:no-console no-require-imports
import { loadModule } from '../../src/index';
import { enableLogger } from '../../src/util/logger';
import { runCld } from '../runCld';
@@ -7,7 +7,8 @@ enableLogger(console.log.bind(console));
const runBrowserCld = async () => {
const cldFactory = await loadModule({
- binaryRemoteEndpoint: `http://localhost:8888`
+ //let file-loader resolves wasm binary when bundling
+ locateBinary: (_wasmPath: string) => require('../../src/lib/cld3_web.wasm')
});
runCld(cldFactory);
diff --git a/examples/browser_remote/webpack.config.js b/examples/browser_remote/webpack.config.js
index 483828b..413d5aa 100644
--- a/examples/browser_remote/webpack.config.js
+++ b/examples/browser_remote/webpack.config.js
@@ -32,10 +32,7 @@ module.exports = {
{
test: /.wasm$/,
type: 'javascript/auto',
- loader: 'file-loader',
- options: {
- name: '[name].[ext]'
- }
+ loader: 'file-loader'
}
]
},
diff --git a/package-lock.json b/package-lock.json
index c1a0fca..3fe1085 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "cld3-asm",
- "version": "2.0.0-beta.2",
+ "version": "2.0.0-beta.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index a26a84d..ca5cd4f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cld3-asm",
- "version": "2.0.0-beta.2",
+ "version": "2.0.0-beta.3",
"description": "WebAssembly based Javascript bindings for google compact language detector 3",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
diff --git a/spec/cld-asm/loadModule-spec.ts b/spec/cld-asm/loadModule-spec.ts
index 5f2b225..609308e 100644
--- a/spec/cld-asm/loadModule-spec.ts
+++ b/spec/cld-asm/loadModule-spec.ts
@@ -12,17 +12,13 @@ jest.mock('../../src/cldLoader');
jest.mock('emscripten-wasm-loader', () => ({
isWasmEnabled: jest.fn(),
isNode: jest.fn(),
- getModuleLoader: jest.fn(),
- ENVIRONMENT: {
- WEB: 'WEB',
- NODE: 'NODE'
- }
+ getModuleLoader: jest.fn()
}));
describe('loadModule', () => {
it('should create moduleLoader on browser', async () => {
const mockModuleLoader = jest.fn();
- (isNode as jest.Mock).mockReturnValueOnce(false);
+ (isNode as jest.Mock).mockReturnValue(false);
(getModuleLoaderMock as jest.Mock).mockImplementationOnce((cb: Function) => {
cb();
@@ -35,7 +31,7 @@ describe('loadModule', () => {
it('should create module on node', async () => {
const mockModuleLoader = jest.fn();
- (isNode as jest.Mock).mockReturnValueOnce(true);
+ (isNode as jest.Mock).mockReturnValue(true);
(getModuleLoaderMock as jest.Mock).mockReturnValueOnce(mockModuleLoader);
await loadModule();
@@ -43,20 +39,43 @@ describe('loadModule', () => {
expect((getModuleLoaderMock as jest.Mock).mock.calls[0][1]).to.equal(nodecld3Mock);
});
- it('should use remoteEndpoint on browser', async () => {
+ it('should use lookupBinary on browser', async () => {
const mockModuleLoader = jest.fn();
- (isNode as jest.Mock).mockReturnValueOnce(false);
+ (isNode as jest.Mock).mockReturnValue(false);
(getModuleLoaderMock as jest.Mock).mockReturnValueOnce(mockModuleLoader);
- await loadModule({ binaryRemoteEndpoint: 'dummy' });
+ await loadModule({ locateBinary: () => 'dummy' });
+
+ expect((getModuleLoaderMock as jest.Mock).mock.calls[0][2].locateFile('test.wasm')).to.equal('dummy');
+ });
+
+ it('should use lookupBinary on node', async () => {
+ const mockModuleLoader = jest.fn();
+ (isNode as jest.Mock).mockReturnValue(true);
+
+ (getModuleLoaderMock as jest.Mock).mockReturnValueOnce(mockModuleLoader);
+ await loadModule({ locateBinary: () => 'dummy' });
+
+ const { locateFile } = (getModuleLoaderMock as jest.Mock).mock.calls[0][2];
+ expect(locateFile('test.wasm')).to.equal('dummy');
+ });
+
+ it('should not override path for wasm binary on node', async () => {
+ const mockModuleLoader = jest.fn();
+ (isNode as jest.Mock).mockReturnValue(true);
+
+ (getModuleLoaderMock as jest.Mock).mockImplementationOnce((cb: Function) => {
+ cb();
+ return mockModuleLoader;
+ });
+ await loadModule();
expect((getModuleLoaderMock as jest.Mock).mock.calls[0][2]).to.be.undefined;
- expect((getModuleLoaderMock as jest.Mock).mock.calls[0][3]).to.deep.equal({ binaryRemoteEndpoint: 'dummy' });
});
- it('should override path for wasm binary on browser without remote endpoint', async () => {
+ it('should override path for wasm binary on browser', async () => {
const mockModuleLoader = jest.fn();
- (isNode as jest.Mock).mockReturnValueOnce(false);
+ (isNode as jest.Mock).mockReturnValue(false);
(getModuleLoaderMock as jest.Mock).mockImplementationOnce((cb: Function) => {
cb();
diff --git a/src/index.ts b/src/index.ts
index bef2c87..211c627 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,6 +1,5 @@
export { loadModule } from './loadModule';
export { log, enableLogger } from './util/logger';
-export { ENVIRONMENT } from 'emscripten-wasm-loader';
export { LanguageIdentifier, CldFactory } from './cldFactory';
export { LanguageResult } from './cldAsmModule';
export { LanguageCode } from './languageCode';
diff --git a/src/loadModule.ts b/src/loadModule.ts
index 3f1f446..8111f5d 100644
--- a/src/loadModule.ts
+++ b/src/loadModule.ts
@@ -1,5 +1,4 @@
import { getModuleLoader, isNode } from 'emscripten-wasm-loader';
-import { ModuleInitOption } from 'emscripten-wasm-loader/dist/types/getModuleLoader';
import { CldAsmModule } from './cldAsmModule';
import { CldFactory } from './cldFactory';
import { cldLoader } from './cldLoader';
@@ -8,34 +7,41 @@ import { log } from './util/logger';
/**
* Load, initialize wasm / asm.js binary to use actual cld wasm instances.
*
- * @param {moduleInitOption} [ModuleInitOption] additional option to configure module loader
+ * @param [InitOptions] Options to initialize cld3 wasm binary.
+ * @param {number} [InitOptions.timeout] - timeout to wait wasm binary compilation & load.
+ * @param {string | object} [InitOptions.locateBinary] - custom resolution logic for wasm binary.
+ * It could be either remote endpoint url, or loader-returned object for bundler. Check examples/browser_* for references.
*
* @returns {() => Promise} Function to load module
*/
-const loadModule = async (moduleInitOption?: Partial) => {
+const loadModule = async ({
+ timeout,
+ locateBinary
+}: Partial<{ timeout: number; locateBinary: (filePath: string) => string | object }> = {}) => {
log(`loadModule: loading cld3 module`);
//imports MODULARIZED emscripten preamble
const runtimeModule = isNode() ? require(`./lib/cld3_node`) : require(`./lib/cld3_web`); //tslint:disable-line:no-require-imports no-var-requires
- // in Browser environment if remote endpoint is not specified cld3-asm overrides preamble's locateFile to provide wasm binary
- // instead of preamble triggers fetch to file:// resource paths.
- // Bundler (i.e webpack) should configure proper loader settings for this.
- const isPathOverrideRequired = !isNode() && (!moduleInitOption || !moduleInitOption.binaryRemoteEndpoint);
- const overriddenModule = !isPathOverrideRequired
- ? undefined
- : {
- locateFile: (filePath: string) =>
- filePath.endsWith('.wasm')
- ? require('./lib/cld3_web.wasm') //tslint:disable-line:no-require-imports no-var-requires
- : filePath
- };
+ //tslint:disable-next-line:no-require-imports no-var-requires
+ const lookupBinary = locateBinary || ((_filePath: string) => require('./lib/cld3_web.wasm'));
+
+ //Build module object to construct wasm binary module via emscripten preamble.
+ //This allows to override default wasm binary resolution in preamble.
+ //By default, cld3-asm overrides to direct require to binary on *browser* environment to allow bundler like webpack resolves it.
+ //On node, it relies on default resolution logic.
+ const overriddenModule =
+ isNode() && !locateBinary
+ ? undefined
+ : {
+ locateFile: (filePath: string) => (filePath.endsWith('.wasm') ? lookupBinary(filePath) : filePath)
+ };
const moduleLoader = await getModuleLoader(
(runtime: CldAsmModule) => cldLoader(runtime),
runtimeModule,
overriddenModule,
- moduleInitOption
+ { timeout }
);
return moduleLoader();