harper.js 0.25.0 → 0.26.0
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/dist/harper.d.ts +141 -5
- package/dist/harper.js +1325 -1776
- package/dist/harper_wasm_bg.wasm +0 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/package.json +13 -5
- package/api-extractor.json +0 -20
- package/docs.sh +0 -24
- package/examples/commonjs-simple/README.md +0 -11
- package/examples/commonjs-simple/index.js +0 -27
- package/examples/commonjs-simple/package.json +0 -11
- package/examples/commonjs-simple/yarn.lock +0 -8
- package/examples/raw-web/README.md +0 -4
- package/examples/raw-web/index.html +0 -55
- package/src/Linter.bench.ts +0 -31
- package/src/Linter.test.ts +0 -208
- package/src/Linter.ts +0 -73
- package/src/LocalLinter.ts +0 -139
- package/src/WorkerLinter/communication.test.ts +0 -63
- package/src/WorkerLinter/communication.ts +0 -111
- package/src/WorkerLinter/index.ts +0 -170
- package/src/WorkerLinter/worker.js +0 -24
- package/src/loadWasm.ts +0 -26
- package/src/main.ts +0 -18
- package/tsconfig.json +0 -25
- package/vite.config.js +0 -63
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { expect, test } from 'vitest';
|
|
2
|
-
import { deserializeArg, serializeArg } from './communication';
|
|
3
|
-
import { Span } from 'wasm';
|
|
4
|
-
import LocalLinter from '../LocalLinter';
|
|
5
|
-
|
|
6
|
-
test('works with strings', async () => {
|
|
7
|
-
const start = 'This is a string';
|
|
8
|
-
|
|
9
|
-
const end = await deserializeArg(structuredClone(await serializeArg(start)));
|
|
10
|
-
|
|
11
|
-
expect(end).toBe(start);
|
|
12
|
-
expect(typeof end).toBe(typeof start);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test('works with false booleans', async () => {
|
|
16
|
-
const start = false;
|
|
17
|
-
|
|
18
|
-
const end = await deserializeArg(structuredClone(await serializeArg(start)));
|
|
19
|
-
|
|
20
|
-
expect(end).toBe(start);
|
|
21
|
-
expect(typeof end).toBe(typeof start);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test('works with true booleans', async () => {
|
|
25
|
-
const start = true;
|
|
26
|
-
|
|
27
|
-
const end = await deserializeArg(structuredClone(await serializeArg(start)));
|
|
28
|
-
|
|
29
|
-
expect(end).toBe(start);
|
|
30
|
-
expect(typeof end).toBe(typeof start);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('works with numbers', async () => {
|
|
34
|
-
const start = 123;
|
|
35
|
-
|
|
36
|
-
const end = await deserializeArg(structuredClone(await serializeArg(start)));
|
|
37
|
-
|
|
38
|
-
expect(end).toBe(start);
|
|
39
|
-
expect(typeof end).toBe(typeof start);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('works with Spans', async () => {
|
|
43
|
-
const start = Span.new(123, 321);
|
|
44
|
-
|
|
45
|
-
const end = await deserializeArg(structuredClone(await serializeArg(start)));
|
|
46
|
-
|
|
47
|
-
expect(end.start).toBe(start.start);
|
|
48
|
-
expect(end.len()).toBe(start.len());
|
|
49
|
-
expect(typeof end).toBe(typeof start);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test('works with Lints', async () => {
|
|
53
|
-
const linter = new LocalLinter();
|
|
54
|
-
const lints = await linter.lint('This is an test.');
|
|
55
|
-
const start = lints[0];
|
|
56
|
-
|
|
57
|
-
expect(start).not.toBeNull();
|
|
58
|
-
|
|
59
|
-
const end = await deserializeArg(structuredClone(await serializeArg(start)));
|
|
60
|
-
|
|
61
|
-
expect(end.message()).toBe(start.message());
|
|
62
|
-
expect(end.lint_kind()).toBe(start.lint_kind());
|
|
63
|
-
});
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/** This module aims to define the communication protocol between the main thread and the worker.
|
|
2
|
-
* Note that much of the complication here comes from the fact that we can't serialize function calls or referenced WebAssembly memory.*/
|
|
3
|
-
|
|
4
|
-
import loadWasm from '../loadWasm';
|
|
5
|
-
|
|
6
|
-
export type Type =
|
|
7
|
-
| 'string'
|
|
8
|
-
| 'number'
|
|
9
|
-
| 'boolean'
|
|
10
|
-
| 'Suggestion'
|
|
11
|
-
| 'Lint'
|
|
12
|
-
| 'Span'
|
|
13
|
-
| 'Array'
|
|
14
|
-
| 'undefined';
|
|
15
|
-
|
|
16
|
-
/** Serializable argument to a procedure to be run on the web worker. */
|
|
17
|
-
export type RequestArg = {
|
|
18
|
-
json: string;
|
|
19
|
-
type: Type;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export async function serialize(req: DeserializedRequest): Promise<SerializedRequest> {
|
|
23
|
-
return {
|
|
24
|
-
procName: req.procName,
|
|
25
|
-
args: await Promise.all(req.args.map(serializeArg))
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export async function serializeArg(arg: any): Promise<RequestArg> {
|
|
30
|
-
const { Lint, Span, Suggestion } = await loadWasm();
|
|
31
|
-
|
|
32
|
-
if (Array.isArray(arg)) {
|
|
33
|
-
return { json: JSON.stringify(await Promise.all(arg.map(serializeArg))), type: 'Array' };
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
switch (typeof arg) {
|
|
37
|
-
case 'string':
|
|
38
|
-
case 'number':
|
|
39
|
-
case 'boolean':
|
|
40
|
-
case 'undefined':
|
|
41
|
-
// @ts-expect-error see the `Type` type.
|
|
42
|
-
return { json: JSON.stringify(arg), type: typeof arg };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (arg.to_json != undefined) {
|
|
46
|
-
const json = arg.to_json();
|
|
47
|
-
let type: Type | undefined = undefined;
|
|
48
|
-
|
|
49
|
-
if (arg instanceof Lint) {
|
|
50
|
-
type = 'Lint';
|
|
51
|
-
} else if (arg instanceof Suggestion) {
|
|
52
|
-
type = 'Suggestion';
|
|
53
|
-
} else if (arg instanceof Span) {
|
|
54
|
-
type = 'Span';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (type == undefined) {
|
|
58
|
-
throw new Error('Unhandled case');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return { json, type };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
throw new Error('Unhandled case');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function deserializeArg(requestArg: RequestArg): Promise<any> {
|
|
68
|
-
const { Lint, Span, Suggestion } = await loadWasm();
|
|
69
|
-
|
|
70
|
-
switch (requestArg.type) {
|
|
71
|
-
case 'undefined':
|
|
72
|
-
return undefined;
|
|
73
|
-
case 'boolean':
|
|
74
|
-
case 'number':
|
|
75
|
-
case 'string':
|
|
76
|
-
return JSON.parse(requestArg.json);
|
|
77
|
-
case 'Suggestion':
|
|
78
|
-
return Suggestion.from_json(requestArg.json);
|
|
79
|
-
case 'Lint':
|
|
80
|
-
return Lint.from_json(requestArg.json);
|
|
81
|
-
case 'Span':
|
|
82
|
-
return Span.from_json(requestArg.json);
|
|
83
|
-
case 'Array':
|
|
84
|
-
return await Promise.all(JSON.parse(requestArg.json).map(deserializeArg));
|
|
85
|
-
default:
|
|
86
|
-
throw new Error(`Unhandled case: ${requestArg.type}`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** An object that is sent to the web worker to request work to be done. */
|
|
91
|
-
export type SerializedRequest = {
|
|
92
|
-
/** The procedure to be executed. */
|
|
93
|
-
procName: string;
|
|
94
|
-
/** The arguments to the procedure */
|
|
95
|
-
args: RequestArg[];
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/** An object that is received by the web worker to request work to be done. */
|
|
99
|
-
export type DeserializedRequest = {
|
|
100
|
-
/** The procedure to be executed. */
|
|
101
|
-
procName: string;
|
|
102
|
-
/** The arguments to the procedure */
|
|
103
|
-
args: any[];
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
export async function deserialize(request: SerializedRequest): Promise<DeserializedRequest> {
|
|
107
|
-
return {
|
|
108
|
-
procName: request.procName,
|
|
109
|
-
args: await Promise.all(request.args.map(deserializeArg))
|
|
110
|
-
};
|
|
111
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { DeserializedRequest, deserializeArg, serialize } from './communication';
|
|
2
|
-
import type { Lint, Suggestion, Span } from 'wasm';
|
|
3
|
-
import Linter from '../Linter';
|
|
4
|
-
import Worker from './worker.js?worker&inline';
|
|
5
|
-
import { getWasmUri } from '../loadWasm';
|
|
6
|
-
import { LintConfig, LintOptions } from '../main';
|
|
7
|
-
|
|
8
|
-
/** The data necessary to complete a request once the worker has responded. */
|
|
9
|
-
type RequestItem = {
|
|
10
|
-
resolve: (item: unknown) => void;
|
|
11
|
-
reject: (item: unknown) => void;
|
|
12
|
-
request: DeserializedRequest;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/** A Linter that spins up a dedicated web worker to do processing on a separate thread.
|
|
16
|
-
* Main benefit: this Linter will not block the event loop for large documents.
|
|
17
|
-
*
|
|
18
|
-
* NOTE: This class will not work properly in Node. In that case, just use `LocalLinter`. */
|
|
19
|
-
export default class WorkerLinter implements Linter {
|
|
20
|
-
private worker;
|
|
21
|
-
private requestQueue: RequestItem[];
|
|
22
|
-
private working = true;
|
|
23
|
-
|
|
24
|
-
constructor() {
|
|
25
|
-
this.worker = new Worker();
|
|
26
|
-
this.requestQueue = [];
|
|
27
|
-
|
|
28
|
-
// Fires when the worker sends 'ready'.
|
|
29
|
-
this.worker.onmessage = () => {
|
|
30
|
-
this.setupMainEventListeners();
|
|
31
|
-
|
|
32
|
-
this.worker.postMessage(getWasmUri());
|
|
33
|
-
|
|
34
|
-
this.working = false;
|
|
35
|
-
this.submitRemainingRequests();
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private setupMainEventListeners() {
|
|
40
|
-
this.worker.onmessage = (e: MessageEvent) => {
|
|
41
|
-
const { resolve } = this.requestQueue.shift()!;
|
|
42
|
-
deserializeArg(e.data).then((v) => {
|
|
43
|
-
resolve(v);
|
|
44
|
-
|
|
45
|
-
this.working = false;
|
|
46
|
-
|
|
47
|
-
this.submitRemainingRequests();
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
this.worker.onmessageerror = (e: MessageEvent) => {
|
|
52
|
-
const { reject } = this.requestQueue.shift()!;
|
|
53
|
-
reject(e.data);
|
|
54
|
-
this.working = false;
|
|
55
|
-
|
|
56
|
-
this.submitRemainingRequests();
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
setup(): Promise<void> {
|
|
61
|
-
return this.rpc('setup', []);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
lint(text: string, options?: LintOptions): Promise<Lint[]> {
|
|
65
|
-
return this.rpc('lint', [text, options]);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
applySuggestion(text: string, suggestion: Suggestion, span: Span): Promise<string> {
|
|
69
|
-
return this.rpc('applySuggestion', [text, suggestion, span]);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
isLikelyEnglish(text: string): Promise<boolean> {
|
|
73
|
-
return this.rpc('isLikelyEnglish', [text]);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
isolateEnglish(text: string): Promise<string> {
|
|
77
|
-
return this.rpc('isolateEnglish', [text]);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async getLintConfig(): Promise<LintConfig> {
|
|
81
|
-
return JSON.parse(await this.getLintConfigAsJSON());
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
setLintConfig(config: LintConfig): Promise<void> {
|
|
85
|
-
return this.setLintConfigWithJSON(JSON.stringify(config));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
getLintConfigAsJSON(): Promise<string> {
|
|
89
|
-
return this.rpc('getLintConfigAsJSON', []);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
setLintConfigWithJSON(config: string): Promise<void> {
|
|
93
|
-
return this.rpc('setLintConfigWithJSON', [config]);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
toTitleCase(text: string): Promise<string> {
|
|
97
|
-
return this.rpc('toTitleCase', [text]);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
getLintDescriptionsAsJSON(): Promise<string> {
|
|
101
|
-
return this.rpc('getLintDescriptionsAsJSON', []);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async getLintDescriptions(): Promise<Record<string, string>> {
|
|
105
|
-
return JSON.parse(await this.getLintDescriptionsAsJSON()) as Record<string, string>;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
getDefaultLintConfigAsJSON(): Promise<string> {
|
|
109
|
-
return this.rpc('getDefaultLintConfigAsJSON', []);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async getDefaultLintConfig(): Promise<LintConfig> {
|
|
113
|
-
return JSON.parse(await this.getDefaultLintConfigAsJSON()) as LintConfig;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async ignoreLint(lint: Lint): Promise<void> {
|
|
117
|
-
return this.rpc('ignoreLint', [lint]);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async exportIgnoredLints(): Promise<string> {
|
|
121
|
-
return this.rpc('exportIgnoredLints', []);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async importIgnoredLints(json: string): Promise<void> {
|
|
125
|
-
return this.rpc('importIgnoredLints', [json]);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async clearIgnoredLints(): Promise<void> {
|
|
129
|
-
return this.rpc('clearIgnoredLints', []);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
async importWords(words: string[]): Promise<void> {
|
|
133
|
-
return this.rpc('importWords', [words]);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async exportWords(): Promise<string[]> {
|
|
137
|
-
return this.rpc('exportWords', []);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/** Run a procedure on the remote worker. */
|
|
141
|
-
private async rpc(procName: string, args: any[]): Promise<any> {
|
|
142
|
-
const promise = new Promise((resolve, reject) => {
|
|
143
|
-
this.requestQueue.push({
|
|
144
|
-
resolve,
|
|
145
|
-
reject,
|
|
146
|
-
request: { procName, args }
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
this.submitRemainingRequests();
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
return promise;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
private async submitRemainingRequests() {
|
|
156
|
-
if (this.working) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
this.working = true;
|
|
161
|
-
|
|
162
|
-
if (this.requestQueue.length > 0) {
|
|
163
|
-
const { request } = this.requestQueue[0];
|
|
164
|
-
|
|
165
|
-
this.worker.postMessage(await serialize(request));
|
|
166
|
-
} else {
|
|
167
|
-
this.working = false;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { setWasmUri } from '../loadWasm';
|
|
2
|
-
import LocalLinter from '../LocalLinter';
|
|
3
|
-
import { deserialize, serializeArg } from './communication';
|
|
4
|
-
|
|
5
|
-
const linter = new LocalLinter();
|
|
6
|
-
|
|
7
|
-
/** @param {SerializedRequest} v */
|
|
8
|
-
async function processRequest(v) {
|
|
9
|
-
const { procName, args } = await deserialize(v);
|
|
10
|
-
|
|
11
|
-
let res = await linter[procName](...args);
|
|
12
|
-
postMessage(await serializeArg(res));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
self.onmessage = function (e) {
|
|
16
|
-
setWasmUri(e.data);
|
|
17
|
-
|
|
18
|
-
self.onmessage = function (e) {
|
|
19
|
-
processRequest(e.data);
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// Notify the main thread that we are ready
|
|
24
|
-
postMessage('ready');
|
package/src/loadWasm.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// @ts-expect-error because this virtual module hasn't been added to a `d.ts` file.
|
|
2
|
-
import wasmUri from 'virtual:wasm';
|
|
3
|
-
|
|
4
|
-
let curWasmUri = wasmUri;
|
|
5
|
-
|
|
6
|
-
/** Get the currently set data URI for the WebAssembly module.
|
|
7
|
-
* I'm not a huge of the singleton, but we're swapping out same data, just from a different source, so the state doesn't meaningfully change. */
|
|
8
|
-
export function getWasmUri(): string {
|
|
9
|
-
return curWasmUri;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/** Set the data URI for the WebAssembly module. */
|
|
13
|
-
export function setWasmUri(uri: string) {
|
|
14
|
-
curWasmUri = uri;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Load the WebAssembly manually and dynamically, making sure to set up infrastructure.
|
|
18
|
-
* You can use an optional data URL for the WebAssembly file if the module is being loaded from a Web Worker.
|
|
19
|
-
* */
|
|
20
|
-
export default async function loadWasm() {
|
|
21
|
-
const wasm = await import('wasm');
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
await wasm.default({ module_or_path: getWasmUri() });
|
|
24
|
-
|
|
25
|
-
return wasm;
|
|
26
|
-
}
|
package/src/main.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Lint, Span, Suggestion } from 'wasm';
|
|
2
|
-
import { SuggestionKind } from 'wasm';
|
|
3
|
-
import Linter from './Linter';
|
|
4
|
-
import LocalLinter from './LocalLinter';
|
|
5
|
-
import WorkerLinter from './WorkerLinter';
|
|
6
|
-
|
|
7
|
-
export { LocalLinter, WorkerLinter, SuggestionKind };
|
|
8
|
-
export type { Linter, Lint, Span, Suggestion };
|
|
9
|
-
|
|
10
|
-
/** A linting rule configuration dependent on upstream Harper's available rules.
|
|
11
|
-
* This is a record, since you shouldn't hard-code the existence of any particular rules and should generalize based on this struct. */
|
|
12
|
-
export type LintConfig = Record<string, boolean | undefined>;
|
|
13
|
-
|
|
14
|
-
/** The option used to configure the parser for an individual linting operation. */
|
|
15
|
-
export type LintOptions = {
|
|
16
|
-
/** The markup language that is being passed. Defaults to `markdown`. */
|
|
17
|
-
language?: 'plaintext' | 'markdown';
|
|
18
|
-
};
|
package/tsconfig.json
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
/* Bundler mode */
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
"allowImportingTsExtensions": true,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"moduleDetection": "force",
|
|
13
|
-
"noEmit": true,
|
|
14
|
-
/* Linting */
|
|
15
|
-
"strict": true,
|
|
16
|
-
"noUnusedLocals": true,
|
|
17
|
-
"noUnusedParameters": true,
|
|
18
|
-
"noFallthroughCasesInSwitch": true,
|
|
19
|
-
"types": ["vite/client"],
|
|
20
|
-
"paths": {
|
|
21
|
-
"wasm": ["../../harper-wasm/pkg"]
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"include": ["src"]
|
|
25
|
-
}
|
package/vite.config.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path';
|
|
2
|
-
import dts from 'vite-plugin-dts';
|
|
3
|
-
import { defineConfig } from 'vite';
|
|
4
|
-
import virtual from 'vite-plugin-virtual';
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
|
|
7
|
-
function fileAsObject(path) {
|
|
8
|
-
let content = fs.readFileSync(path);
|
|
9
|
-
return JSON.parse(content);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default defineConfig({
|
|
13
|
-
build: {
|
|
14
|
-
lib: {
|
|
15
|
-
entry: resolve(__dirname, 'src/main.ts'),
|
|
16
|
-
fileName: `harper`,
|
|
17
|
-
name: 'harper',
|
|
18
|
-
formats: ['es']
|
|
19
|
-
},
|
|
20
|
-
rollupOptions: {
|
|
21
|
-
output: {
|
|
22
|
-
inlineDynamicImports: true
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
base: './',
|
|
27
|
-
plugins: [
|
|
28
|
-
dts({
|
|
29
|
-
...fileAsObject('./api-extractor.json'),
|
|
30
|
-
rollupTypes: true,
|
|
31
|
-
tsconfigPath: './tsconfig.json'
|
|
32
|
-
}),
|
|
33
|
-
virtual({
|
|
34
|
-
'virtual:wasm': `import wasmUri from 'wasm/harper_wasm_bg.wasm?inline'; export default wasmUri`
|
|
35
|
-
})
|
|
36
|
-
],
|
|
37
|
-
worker: {
|
|
38
|
-
plugins: [
|
|
39
|
-
virtual({
|
|
40
|
-
'virtual:wasm': `export default ''`
|
|
41
|
-
})
|
|
42
|
-
],
|
|
43
|
-
format: 'es',
|
|
44
|
-
rollupOptions: {
|
|
45
|
-
output: {
|
|
46
|
-
inlineDynamicImports: true
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
server: {
|
|
51
|
-
fs: {
|
|
52
|
-
allow: ['../../harper-wasm/pkg']
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
test: {
|
|
56
|
-
browser: {
|
|
57
|
-
provider: 'playwright',
|
|
58
|
-
enabled: true,
|
|
59
|
-
headless: true
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
assetsInclude: ['**/*.wasm']
|
|
63
|
-
});
|