Skip to content

Commit

Permalink
Load wasm via fetch rather than base64 embedding
Browse files Browse the repository at this point in the history
Requires splitting into two packages to make use of vite's externals until something like vitejs/vite#9734 lands
Gets rid of hack_myfetch.js
Replaces hack_exports.js with vite plugin options
Stops copying generated wasm-pack files around
Switches the packages to ESM
Simplifies scripts and updates some dependencies for necessary features
Fixes types and ditches a lot of ts disablements
  • Loading branch information
t3chguy committed Dec 4, 2024
1 parent 1bf6183 commit f624d6f
Show file tree
Hide file tree
Showing 27 changed files with 591 additions and 575 deletions.
11 changes: 2 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,8 @@ ios: targets-ios
web:
cd bindings/wysiwyg-wasm && \
npm install && \
npm run build && \
mkdir -p ../../platforms/web/generated && \
cp \
pkg/wysiwyg_bg.wasm \
pkg/wysiwyg_bg.wasm.d.ts \
pkg/wysiwyg.d.ts \
pkg/wysiwyg.js \
../../platforms/web/generated/
cd platforms/web && yarn install && yarn build
npm run build
cd platforms/web && yarn install --force && yarn build

web-format:
cd platforms/web && \
Expand Down
17 changes: 17 additions & 0 deletions bindings/wysiwyg-wasm/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Copyright 2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

export * from './pkg/wysiwyg.d';

/**
* Load the WebAssembly module in the background, if it has not already been loaded.
*
* Returns a promise which will resolve once the other methods are ready.
*
* @returns {Promise<void>}
*/
export default function initAsync(): Promise<void>;
83 changes: 83 additions & 0 deletions bindings/wysiwyg-wasm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Copyright 2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

// @ts-check

/**
* This is the entrypoint on non-node ESM environments (such as Element Web).
* `asyncLoad` will load the WASM module using a `fetch` call.
*/

import * as bindings from './pkg/wysiwyg_bg.js';

const moduleUrl = new URL(
'./pkg/wysiwyg_bg.wasm?url',
import.meta.url,
);

// We want to throw an error if the user tries to use the bindings before
// calling `initAsync`.
bindings.__wbg_set_wasm(
new Proxy(
{},
{
get() {
throw new Error(
'@element-hq/matrix-wysiwyg was used before it was initialized. Call `initAsync` first.',
);
},
},
),
);

/**
* Stores a promise of the `loadModule` call
* @type {Promise<void> | null}
*/
let modPromise = null;

/**
* Loads the WASM module asynchronously
*
* @returns {Promise<void>}
*/
async function loadModule() {
let mod;
if (typeof WebAssembly.compileStreaming === 'function') {
mod = await WebAssembly.compileStreaming(fetch(moduleUrl));
} else {
// Fallback to fetch and compile
const response = await fetch(moduleUrl);
if (!response.ok) {
throw new Error(`Failed to fetch wasm module: ${moduleUrl}`);
}
const bytes = await response.arrayBuffer();
mod = await WebAssembly.compile(bytes);
}

const instance = await WebAssembly.instantiate(mod, {
'./wysiwyg_bg.js': bindings,
});

bindings.__wbg_set_wasm(instance.exports);
instance.exports.__wbindgen_start();
}

/**
* Load the WebAssembly module in the background, if it has not already been loaded.
*
* Returns a promise which will resolve once the other methods are ready.
*
* @returns {Promise<void>}
*/
export default async function initAsync() {
if (!modPromise) modPromise = loadModule();
await modPromise;
}

// Re-export everything from the generated javascript wrappers
export * from './pkg/wysiwyg_bg.js';
21 changes: 15 additions & 6 deletions bindings/wysiwyg-wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "wysiwyg-wasm",
"name": "@vector-im/matrix-wysiwyg-wasm",
"version": "2.37.14",
"homepage": "https://gitlab.com/andybalaam/wysiwyg-rust",
"description": "WASM bindings for wysiwyg-rust",
"license": "AGPL-3.0",
"type": "module",
"collaborators": [
"Andy Balaam <[email protected]>"
],
Expand All @@ -17,13 +18,21 @@
"messaging",
"wysiwyg"
],
"main": "wysiwyg.js",
"types": "pkg/wysiwyg.d.ts",
"main": "index.js",
"types": "index.d.ts",
"exports": {
"." : {
"import": "./index.js",
"types": "./index.d.ts"
}
},
"files": [
"pkg/wysiwyg_bg.wasm",
"pkg/wysiwyg_bg.wasm.d.ts",
"pkg/wysiwyg.js",
"pkg/wysiwyg.d.ts"
"pkg/wysiwyg.d.ts",
"index.d.ts",
"index.js"
],
"devDependencies": {
"wasm-pack": "^0.13.0",
Expand All @@ -34,8 +43,8 @@
"node": ">= 10"
},
"scripts": {
"dev-build": "WASM_BINDGEN_WEAKREF=1 wasm-pack build --profiling --target web --out-name wysiwyg --out-dir ./pkg",
"build": "RUSTFLAGS='-C opt-level=s' WASM_BINDGEN_WEAKREF=1 wasm-pack build --release --target web --out-name wysiwyg --out-dir ./pkg",
"dev-build": "WASM_BINDGEN_WEAKREF=1 wasm-pack build --profiling --target bundler --out-name wysiwyg --out-dir ./pkg",
"build": "RUSTFLAGS='-C opt-level=s' WASM_BINDGEN_WEAKREF=1 wasm-pack build --release --target bundler --out-name wysiwyg --out-dir ./pkg",
"test": "jest --verbose",
"doc": "typedoc --tsconfig ."
}
Expand Down
2 changes: 1 addition & 1 deletion platforms/web/example-wysiwyg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ and open the URL that is printed on the console.
npm create vite@latest example-wysiwyg -- --template react-ts
cd example-wysiwyg
npm install
npm add '@vector-im/matrix-wysiwyg'
npm add '@vector-im/matrix-wysiwyg-wasm'
```
* Edit example-wysiwyg/src/App.tsx to look how it looks in this repo.
* Edit example-wysiwyg/index.html to set the page title and remove favicon.
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/composer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { ComposerModel } from '../generated/wysiwyg';
import { ComposerModel } from '@vector-im/matrix-wysiwyg-wasm';

import { processInput } from './composer';
import { FormattingFunctions } from './types';

Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
ComposerModel,
ComposerUpdate,
SuggestionPattern,
} from '../generated/wysiwyg';
} from '@vector-im/matrix-wysiwyg-wasm';

import {
WysiwygInputEvent,
InputEventProcessor,
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Please see LICENSE in the repository root for full details.
import {
// eslint-disable-next-line camelcase
new_composer_model,
} from '../generated/wysiwyg.js';
} from '@vector-im/matrix-wysiwyg-wasm';

import { initOnce } from './useComposerModel.js';

const NEWLINE_CHAR = '\n';
Expand Down
2 changes: 1 addition & 1 deletion platforms/web/lib/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { ComposerModel, DomHandle } from '../generated/wysiwyg';
import { ComposerModel, DomHandle } from '@vector-im/matrix-wysiwyg-wasm';

export function refreshComposerView(
node: HTMLElement,
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/suggestion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import init, {
// eslint-disable-next-line camelcase
new_composer_model,
SuggestionPattern,
} from '../generated/wysiwyg';
} from '@vector-im/matrix-wysiwyg-wasm';

import { SUGGESTIONS } from './constants';
import {
getSuggestionChar,
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/suggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { SuggestionPattern } from '../generated/wysiwyg';
import { SuggestionPattern } from '@vector-im/matrix-wysiwyg-wasm';

import { SUGGESTIONS } from './constants';
import { MappedSuggestion, SuggestionChar, SuggestionType } from './types';

Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import { ComposerUpdate } from '../generated/wysiwyg';
import { ComposerUpdate } from '@vector-im/matrix-wysiwyg-wasm';

import { ACTION_TYPES, SUGGESTIONS } from './constants';
import { AllowedMentionAttributes, LinkEvent } from './useListeners/types';

Expand Down
2 changes: 1 addition & 1 deletion platforms/web/lib/useComposerModel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Please see LICENSE in the repository root for full details.

import { act, RefObject } from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import * as mockRustModel from '@vector-im/matrix-wysiwyg-wasm';

import * as mockRustModel from '../generated/wysiwyg';
import { useComposerModel } from './useComposerModel';

describe('useComposerModel', () => {
Expand Down
4 changes: 2 additions & 2 deletions platforms/web/lib/useComposerModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ Please see LICENSE in the repository root for full details.
*/

import { RefObject, useCallback, useEffect, useState } from 'react';

// rust generated bindings
import init, {
ComposerModel,
// eslint-disable-next-line camelcase
new_composer_model,
// eslint-disable-next-line camelcase
new_composer_model_from_html,
} from '../generated/wysiwyg.js';
} from '@vector-im/matrix-wysiwyg-wasm';

import { replaceEditor } from './dom';

let initStarted = false;
Expand Down
2 changes: 1 addition & 1 deletion platforms/web/lib/useFormattingFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Please see LICENSE in the repository root for full details.
*/

import { RefObject, useMemo } from 'react';
import { ComposerModel } from '@vector-im/matrix-wysiwyg-wasm';

import { BlockType, FormattingFunctions } from './types';
import { sendWysiwygInputEvent } from './useListeners';
Expand All @@ -16,7 +17,6 @@ import {
LinkEvent,
SuggestionEvent,
} from './useListeners/types';
import { ComposerModel } from '../generated/wysiwyg';

export function useFormattingFunctions(
editorRef: RefObject<HTMLElement | null>,
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/useListeners/event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Please see LICENSE in the repository root for full details.
*/

// eslint-disable-next-line camelcase
import init, { new_composer_model } from '../../generated/wysiwyg';
import init, { new_composer_model } from '@vector-im/matrix-wysiwyg-wasm';

import { extractActionStates, handleKeyDown } from './event';
import { FormatBlockEvent } from './types';
import { FormattingFunctions } from '../types';
Expand Down
4 changes: 2 additions & 2 deletions platforms/web/lib/useListeners/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ Please see LICENSE in the repository root for full details.
*/

import { MouseEvent as ReactMouseEvent } from 'react';

import {
ComposerModel,
MenuStateUpdate,
SuggestionPattern,
} from '../../generated/wysiwyg';
} from '@vector-im/matrix-wysiwyg-wasm';

import { processEvent, processInput } from '../composer';
import {
getCurrentSelection,
Expand Down
5 changes: 4 additions & 1 deletion platforms/web/lib/useListeners/useListeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ Please see LICENSE in the repository root for full details.
*/

import { RefObject, useEffect, useRef, useState } from 'react';
import {
ComposerModel,
SuggestionPattern,
} from '@vector-im/matrix-wysiwyg-wasm';

import { ComposerModel, SuggestionPattern } from '../../generated/wysiwyg';
import { isClipboardEvent, isInputEvent } from './assert';
import { handleInput, handleKeyDown, handleSelectionChange } from './event';
import {
Expand Down
2 changes: 1 addition & 1 deletion platforms/web/lib/useTestCases/useTestCases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Please see LICENSE in the repository root for full details.
*/

import { RefObject, useCallback, useMemo, useRef, useState } from 'react';
import { ComposerModel } from '@vector-im/matrix-wysiwyg-wasm';

import { ComposerModel } from '../../generated/wysiwyg';
import { Actions } from './types';
import {
getSelectionAccordingToActions,
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/useTestCases/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only
Please see LICENSE in the repository root for full details.
*/

import init from '../../generated/wysiwyg';
import init from '@vector-im/matrix-wysiwyg-wasm';

import { Actions } from './types';
import {
escapeHtml,
Expand Down
3 changes: 2 additions & 1 deletion platforms/web/lib/useTestCases/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
ComposerUpdate,
// eslint-disable-next-line camelcase
new_composer_model_from_html,
} from '../../generated/wysiwyg';
} from '@vector-im/matrix-wysiwyg-wasm';

import { getCurrentSelection } from '../dom';
import { TraceAction } from '../types';
import { isSelectTuple } from './assert';
Expand Down
Loading

0 comments on commit f624d6f

Please sign in to comment.