qlevens
Version:
A lightning-fast implementation of the Levenshtein distance algorithm. Written in AssemblyScript, compiled to WebAssembly, and optimized for speed.
83 lines (82 loc) • 2.98 kB
JavaScript
async function instantiate(module, imports = {}) {
const adaptedImports = {
env: Object.assign(Object.create(globalThis), imports.env || {}, {
abort(message, fileName, lineNumber, columnNumber) {
// ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
message = __liftString(message >>> 0);
fileName = __liftString(fileName >>> 0);
lineNumber = lineNumber >>> 0;
columnNumber = columnNumber >>> 0;
(() => {
// @external.js
throw Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);
})();
},
}),
};
const { exports } = await WebAssembly.instantiate(module, adaptedImports);
const memory = exports.memory || imports.env.memory;
const adaptedExports = Object.setPrototypeOf({
distance(a, b) {
// src/index/distance(~lib/string/String, ~lib/string/String) => i32
a = __retain(__lowerString(a) || __notnull());
b = __lowerString(b) || __notnull();
try {
return exports.distance(a, b);
} finally {
__release(a);
}
},
}, exports);
function __liftString(pointer) {
if (!pointer) return null;
const
end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1,
memoryU16 = new Uint16Array(memory.buffer);
let
start = pointer >>> 1,
string = "";
while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, start += 1024));
return string + String.fromCharCode(...memoryU16.subarray(start, end));
}
function __lowerString(value) {
if (value == null) return 0;
const
length = value.length,
pointer = exports.__new(length << 1, 1) >>> 0,
memoryU16 = new Uint16Array(memory.buffer);
for (let i = 0; i < length; ++i) memoryU16[(pointer >>> 1) + i] = value.charCodeAt(i);
return pointer;
}
const refcounts = new Map();
function __retain(pointer) {
if (pointer) {
const refcount = refcounts.get(pointer);
if (refcount) refcounts.set(pointer, refcount + 1);
else refcounts.set(exports.__pin(pointer), 1);
}
return pointer;
}
function __release(pointer) {
if (pointer) {
const refcount = refcounts.get(pointer);
if (refcount === 1) exports.__unpin(pointer), refcounts.delete(pointer);
else if (refcount) refcounts.set(pointer, refcount - 1);
else throw Error(`invalid refcount '${refcount}' for reference '${pointer}'`);
}
}
function __notnull() {
throw TypeError("value must not be null");
}
return adaptedExports;
}
export const {
memory,
distance
} = await (async url => instantiate(
await (async () => {
try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
})(), {
}
))(new URL("release.wasm", import.meta.url));