Comparing version 1.4.6 to 2.0.0
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__export(require("./saxWasm")); | ||
__exportStar(require("./saxWasm"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -11,7 +11,5 @@ export declare class SaxEventType { | ||
static CloseTag: number; | ||
static OpenCDATA: number; | ||
static Cdata: number; | ||
static CloseCDATA: number; | ||
} | ||
export declare type Detail = Position | Attribute | Text | Tag | StringReader; | ||
export declare type Detail = Position | Attribute | Text | Tag | ProcInst; | ||
export declare abstract class Reader<T = Detail> { | ||
@@ -27,3 +25,2 @@ protected data: Uint8Array; | ||
}; | ||
abstract readonly value: any; | ||
} | ||
@@ -35,25 +32,28 @@ export declare class Position { | ||
} | ||
export declare class Attribute extends Reader<string | number | Position> { | ||
readonly nameStart: Position; | ||
readonly nameEnd: Position; | ||
readonly valueStart: Position; | ||
readonly valueEnd: Position; | ||
readonly name: string; | ||
readonly value: string; | ||
export declare class Attribute extends Reader<Text> { | ||
name: Text; | ||
value: Text; | ||
constructor(buffer: Uint8Array, ptr?: number); | ||
toJSON(): { | ||
[prop: string]: string | number | Position; | ||
[prop: string]: Text; | ||
}; | ||
toString(): string; | ||
} | ||
export declare class Text extends Reader<string | Position> { | ||
readonly start: Position; | ||
readonly end: Position; | ||
readonly value: string; | ||
export declare class ProcInst extends Reader<Position | Text> { | ||
target: Text; | ||
content: Text; | ||
constructor(buffer: Uint8Array, ptr?: number); | ||
get start(): Position; | ||
get end(): Position; | ||
toJSON(): { | ||
[prop: string]: string | Position; | ||
[p: string]: Position | Text; | ||
}; | ||
toString(): string; | ||
} | ||
export declare class StringReader extends Reader<string> { | ||
readonly value: string; | ||
export declare class Text extends Reader<string | Position> { | ||
get start(): Position; | ||
get end(): Position; | ||
get value(): string; | ||
toJSON(): { | ||
[p: string]: string; | ||
[prop: string]: string | Position; | ||
}; | ||
@@ -63,14 +63,14 @@ toString(): string; | ||
export declare class Tag extends Reader<Attribute[] | Text[] | Position | string | number | boolean> { | ||
readonly openStart: Position; | ||
readonly openEnd: Position; | ||
readonly closeStart: Position; | ||
readonly closeEnd: Position; | ||
readonly selfClosing: boolean; | ||
readonly name: string; | ||
readonly attributes: Attribute[]; | ||
readonly textNodes: Text[]; | ||
get openStart(): Position; | ||
get openEnd(): Position; | ||
get closeStart(): Position; | ||
get closeEnd(): Position; | ||
get selfClosing(): boolean; | ||
get name(): string; | ||
get attributes(): Attribute[]; | ||
get textNodes(): Text[]; | ||
toJSON(): { | ||
[p: string]: Attribute[] | Text[] | Position | string | number | boolean; | ||
}; | ||
readonly value: string; | ||
get value(): string; | ||
} | ||
@@ -93,3 +93,3 @@ export interface SaxParserOptions { | ||
constructor(events?: number, options?: SaxParserOptions); | ||
write(chunk: Uint8Array, offset?: number): void; | ||
write(chunk: Uint8Array): void; | ||
end(): void; | ||
@@ -96,0 +96,0 @@ prepareWasm(saxWasm: Uint8Array): Promise<boolean>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SAXParser = exports.Tag = exports.Text = exports.ProcInst = exports.Attribute = exports.Position = exports.Reader = exports.SaxEventType = void 0; | ||
class SaxEventType { | ||
@@ -25,7 +26,3 @@ } | ||
// 512 | ||
SaxEventType.OpenCDATA = 0b1000000000; | ||
// 1024 | ||
SaxEventType.Cdata = 0b10000000000; | ||
// 2048 | ||
SaxEventType.CloseCDATA = 0b100000000000; | ||
SaxEventType.Cdata = 0b1000000000; | ||
class Reader { | ||
@@ -47,35 +44,46 @@ constructor(data, ptr = 0) { | ||
class Attribute extends Reader { | ||
get nameStart() { | ||
return this.cache.nameStart || (this.cache.nameStart = readPosition(this.data, this.ptr)); | ||
constructor(buffer, ptr = 0) { | ||
super(buffer, ptr); | ||
const len = readU32(buffer, ptr); | ||
ptr += 4; | ||
this.name = new Text(buffer, ptr); | ||
ptr += len; | ||
this.value = new Text(buffer, ptr); | ||
} | ||
get nameEnd() { | ||
return this.cache.nameEnd || (this.cache.nameEnd = readPosition(this.data, this.ptr + 8)); | ||
toJSON() { | ||
const { name, value } = this; | ||
return { name, value }; | ||
} | ||
get valueStart() { | ||
return this.cache.valueStart || (this.cache.valueStart = readPosition(this.data, this.ptr + 16)); | ||
toString() { | ||
const { name, value } = this; | ||
return `${name}="${value}"`; | ||
} | ||
get valueEnd() { | ||
return this.cache.valueEnd || (this.cache.valueEnd = readPosition(this.data, this.ptr + 24)); | ||
} | ||
exports.Attribute = Attribute; | ||
class ProcInst extends Reader { | ||
constructor(buffer, ptr = 0) { | ||
super(buffer, ptr); | ||
ptr += 16; | ||
const len = readU32(buffer, ptr); | ||
ptr += 4; | ||
this.target = new Text(buffer, ptr); | ||
ptr += len; | ||
this.content = new Text(buffer, ptr); | ||
} | ||
get name() { | ||
if (this.cache.name) { | ||
return this.cache.name; | ||
} | ||
const nameLen = readU32(this.data, this.ptr + 32); | ||
return (this.cache.name = readString(this.data.buffer, this.ptr + 36, nameLen)); | ||
get start() { | ||
return this.cache.start || (this.cache.start = readPosition(this.data, this.ptr)); | ||
} | ||
get value() { | ||
if (this.cache.value) { | ||
return this.cache.value; | ||
} | ||
const nameLen = readU32(this.data, this.ptr + 32); | ||
const valueLen = readU32(this.data, this.ptr + 36 + nameLen); | ||
return (this.cache.value = readString(this.data.buffer, this.ptr + 40 + nameLen, valueLen)); | ||
get end() { | ||
return this.cache.end || (this.cache.end = readPosition(this.data, this.ptr + 8)); | ||
} | ||
toJSON() { | ||
const { nameStart, nameEnd, valueStart, valueEnd, name, value } = this; | ||
return { nameStart, nameEnd, valueStart, valueEnd, name, value }; | ||
const { start, end, target, content } = this; | ||
return { start, end, target, content }; | ||
} | ||
toString() { | ||
const { target, content } = this; | ||
return `<? ${target} ${content} ?>`; | ||
} | ||
} | ||
exports.Attribute = Attribute; | ||
exports.ProcInst = ProcInst; | ||
class Text extends Reader { | ||
@@ -93,3 +101,3 @@ get start() { | ||
const valueLen = readU32(this.data, this.ptr + 16); | ||
return (this.cache.value = readString(this.data.buffer, this.ptr + 20, valueLen)); | ||
return (this.cache.value = readString(this.data, this.ptr + 20, valueLen)); | ||
} | ||
@@ -100,14 +108,2 @@ toJSON() { | ||
} | ||
} | ||
exports.Text = Text; | ||
class StringReader extends Reader { | ||
get value() { | ||
if (this.cache.value) { | ||
return this.cache.value; | ||
} | ||
return (this.cache.value = readString(this.data.buffer, this.ptr, this.data.length)); | ||
} | ||
toJSON() { | ||
return { value: this.value }; | ||
} | ||
toString() { | ||
@@ -117,18 +113,18 @@ return this.value; | ||
} | ||
exports.StringReader = StringReader; | ||
exports.Text = Text; | ||
class Tag extends Reader { | ||
get openStart() { | ||
return this.cache.openStart || (this.cache.openStart = readPosition(this.data, 0)); | ||
return this.cache.openStart || (this.cache.openStart = readPosition(this.data, this.ptr + 8)); | ||
} | ||
get openEnd() { | ||
return this.cache.openEnd || (this.cache.openEnd = readPosition(this.data, 8)); | ||
return this.cache.openEnd || (this.cache.openEnd = readPosition(this.data, this.ptr + 16)); | ||
} | ||
get closeStart() { | ||
return this.cache.closeStart || (this.cache.closeStart = readPosition(this.data, 16)); | ||
return this.cache.closeStart || (this.cache.closeStart = readPosition(this.data, this.ptr + 24)); | ||
} | ||
get closeEnd() { | ||
return this.cache.closeEnd || (this.cache.closeEnd = readPosition(this.data, 24)); | ||
return this.cache.closeEnd || (this.cache.closeEnd = readPosition(this.data, this.ptr + 32)); | ||
} | ||
get selfClosing() { | ||
return !!this.data[32]; | ||
return !!this.data[this.ptr + 40]; | ||
} | ||
@@ -139,4 +135,4 @@ get name() { | ||
} | ||
const nameLen = readU32(this.data, 33); | ||
return (this.cache.name = readString(this.data.buffer, 37, nameLen)); | ||
const nameLen = readU32(this.data, this.ptr + 41); | ||
return (this.cache.name = readString(this.data, this.ptr + 45, nameLen)); | ||
} | ||
@@ -148,3 +144,3 @@ get attributes() { | ||
// starting location of the attribute block | ||
let ptr = readU32(this.data, this.data.length - 8); | ||
let ptr = readU32(this.data, this.ptr); | ||
let numAttrs = readU32(this.data, ptr); | ||
@@ -166,3 +162,3 @@ ptr += 4; | ||
// starting location of the text nodes block | ||
let ptr = readU32(this.data, this.data.length - 4); | ||
let ptr = readU32(this.data, this.ptr + 4); | ||
let numTextNodes = readU32(this.data, ptr); | ||
@@ -191,3 +187,3 @@ const textNodes = []; | ||
this.eventTrap = (event, ptr, len) => { | ||
const uint8array = new Uint8Array(this.wasmSaxParser.memory.buffer.slice(ptr, ptr + len)); | ||
const uint8array = new Uint8Array(this.wasmSaxParser.memory.buffer, ptr, len); | ||
let detail; | ||
@@ -198,2 +194,5 @@ switch (event) { | ||
break; | ||
case SaxEventType.ProcessingInstruction: | ||
detail = new ProcInst(uint8array); | ||
break; | ||
case SaxEventType.OpenTag: | ||
@@ -205,10 +204,10 @@ case SaxEventType.CloseTag: | ||
case SaxEventType.Text: | ||
case SaxEventType.Cdata: | ||
case SaxEventType.Comment: | ||
case SaxEventType.Doctype: | ||
case SaxEventType.SGMLDeclaration: | ||
detail = new Text(uint8array); | ||
break; | ||
case SaxEventType.OpenCDATA: | ||
detail = readPosition(uint8array); | ||
break; | ||
default: | ||
detail = new StringReader(uint8array); | ||
break; | ||
throw new Error('No reader for this event type'); | ||
} | ||
@@ -229,8 +228,9 @@ this.eventHandler(event, detail); | ||
} | ||
}, configurable: false, enumerable: true | ||
}, | ||
configurable: false, enumerable: true | ||
} | ||
}); | ||
} | ||
write(chunk, offset = 0) { | ||
const { write, memory: { buffer } } = this.wasmSaxParser; | ||
write(chunk) { | ||
const { write, memory } = this.wasmSaxParser; | ||
// Allocations within the WASM process | ||
@@ -244,7 +244,7 @@ // invalidate reference to the memory buffer. | ||
// memory allocation to prevent too many new Uint8Array instances. | ||
if (!this.writeBuffer || this.writeBuffer.buffer !== buffer) { | ||
this.writeBuffer = new Uint8Array(buffer, 0, this.options.highWaterMark); | ||
if (!this.writeBuffer || this.writeBuffer.buffer !== memory.buffer) { | ||
this.writeBuffer = new Uint8Array(memory.buffer); | ||
} | ||
this.writeBuffer.set(chunk); | ||
write(offset, chunk.byteLength); | ||
write(0, chunk.byteLength); | ||
} | ||
@@ -260,3 +260,3 @@ end() { | ||
tableBase: 0, | ||
memory: new WebAssembly.Memory({ initial: 32 }), | ||
memory: new WebAssembly.Memory({ initial: 10 }), | ||
table: new WebAssembly.Table({ initial: 1, element: 'anyfunc' }), | ||
@@ -275,11 +275,11 @@ event_listener: this.eventTrap | ||
exports.SAXParser = SAXParser; | ||
function readString(data, byteOffset, length) { | ||
function readString(data, offset, length) { | ||
const env = (global || window); | ||
// Node | ||
if (env.Buffer !== undefined) { | ||
return Buffer.from(data, byteOffset, length).toString(); | ||
return Buffer.from(data.buffer, data.byteOffset + offset, length).toString(); | ||
} | ||
// Web | ||
return (SAXParser.textDecoder || (SAXParser.textDecoder = new TextDecoder())) | ||
.decode(new Uint8Array(data, byteOffset, length)); | ||
.decode(data.subarray(offset, offset + length)); | ||
} | ||
@@ -286,0 +286,0 @@ function readU32(uint8Array, ptr) { |
{ | ||
"name": "sax-wasm", | ||
"version": "1.4.6", | ||
"version": "2.0.0", | ||
"repository": "https://github.com/justinwilaby/sax-wasm", | ||
@@ -35,3 +35,3 @@ "description": "An extremely fast JSX, HTML and XML parser written in Rust compiled to WebAssembly for Node and the Web", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^12.0.8", | ||
"@types/node": "14.11.1", | ||
"coveralls": "^3.0.6", | ||
@@ -47,5 +47,5 @@ "expect.js": "^0.3.1", | ||
"source-map-support": "^0.5.13", | ||
"ts-node": "^8.3.0", | ||
"typescript": "^3.6.2" | ||
"ts-node": "9.0.0", | ||
"typescript": "4.0.3" | ||
} | ||
} |
@@ -8,5 +8,5 @@ # SAX (Simple API for XML) for WebAssembly | ||
The first streamable, low memory XML, HTML, and JSX parser for [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly). | ||
The first streamable, low memory XML, HTML, JSX and Angular Template parser for [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly). | ||
Sax Wasm is a sax style parser for XML, HTML and JSX written in [Rust](https://www.rust-lang.org/en-US/), compiled for | ||
Sax Wasm is a sax style parser for XML, HTML, JSX anf Angular Templates written in [Rust](https://www.rust-lang.org/en-US/), compiled for | ||
WebAssembly with the sole motivation to bring **faster than native speeds** to XML and JSX parsing for node and the web. | ||
@@ -19,3 +19,3 @@ Inspired by [sax js](https://github.com/isaacs/sax-js) and rebuilt with Rust for WebAssembly, sax-wasm brings optimizations | ||
## Benchmarks (Node v14.5.0 / 2.7 GHz Quad-Core Intel Core i7) | ||
## Benchmarks (Node v14.13.0 / 2.7 GHz Quad-Core Intel Core i7) | ||
All parsers are tested using a large XML document (2.1 MB) containing a variety of elements and is streamed when supported | ||
@@ -28,7 +28,7 @@ by the parser. This attempts to recreate the best real-world use case for parsing XML. Other libraries test benchmarks using a | ||
|--------------------------------------------------------------------------------------------|--------------------------:|:------:|:---------------:| | ||
| [sax-wasm](https://github.com/justinwilaby/sax-wasm) | 143.14 | ☑ | ☑ | | ||
| [sax-js](https://github.com/isaacs/sax-js) | 158.47 | ☑ | ☑* | | ||
| [node-expat](https://github.com/node-xmpp/node-expat) | 273.22 | ☐ | ☐ | | ||
| [libxmljs](https://github.com/polotek/libxmljs) | 358.91 | ☐ | ☐ | | ||
| [node-xml](https://github.com/dylang/node-xml) | 638.00 | ☑ | ☐ | | ||
| [sax-wasm](https://github.com/justinwilaby/sax-wasm) | 95.08 | ☑ | ☑ | | ||
| [sax-js](https://github.com/isaacs/sax-js) | 167.33 | ☑ | ☑* | | ||
| [node-expat](https://github.com/node-xmpp/node-expat) | 242.82 | ☐ | ☐ | | ||
| [libxmljs](https://github.com/polotek/libxmljs) | 287.00 | ☐ | ☐ | | ||
| [node-xml](https://github.com/dylang/node-xml) | 621.26 | ☑ | ☐ | | ||
<sub>*built for node but *should* run in the browser</sub> | ||
@@ -146,6 +146,6 @@ | ||
|SaxEventType.Text |0b000000000001|text: [Text](src/js/saxWasm.ts#L95) | | ||
|SaxEventType.ProcessingInstruction|0b000000000010|procInst: [StringReader](src/js/saxWasm.ts#L118)| | ||
|SaxEventType.SGMLDeclaration |0b000000000100|sgmlDecl: [StringReader](src/js/saxWasm.ts#L118)| | ||
|SaxEventType.Doctype |0b000000001000|doctype: [StringReader](src/js/saxWasm.ts#L118) | | ||
|SaxEventType.Comment |0b000000010000|comment: [StringReader](src/js/saxWasm.ts#L118) | | ||
|SaxEventType.ProcessingInstruction|0b000000000010|procInst: [Text](src/js/saxWasm.ts#L95) | | ||
|SaxEventType.SGMLDeclaration |0b000000000100|sgmlDecl: [Text](src/js/saxWasm.ts#L95) | | ||
|SaxEventType.Doctype |0b000000001000|doctype: [Text](src/js/saxWasm.ts#L95) | | ||
|SaxEventType.Comment |0b000000010000|comment: [Text](src/js/saxWasm.ts#L95) | | ||
|SaxEventType.OpenTagStart |0b000000100000|tag: [Tag](src/js/saxWasm.ts#L135) | | ||
@@ -155,5 +155,3 @@ |SaxEventType.Attribute |0b000001000000|attribute: [Attribute](src/js/saxWasm.ts#L55) | | ||
|SaxEventType.CloseTag |0b000100000000|tag: [Tag](src/js/saxWasm.ts#L135) | | ||
|SaxEventType.OpenCDATA |0b001000000000|start: [Position](src/js/saxWasm.ts#L45) | | ||
|SaxEventType.CDATA |0b010000000000|cdata: [StringReader](src/js/saxWasm.ts#L118) | | ||
|SaxEventType.CloseCDATA |0b100000000000|end: [Position](src/js/saxWasm.ts#L45) | | ||
|SaxEventType.CDATA |0b001000000000|start: [Position](src/js/saxWasm.ts#L45) | | ||
@@ -160,0 +158,0 @@ ## Speeding things up on large documents |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
62907
386
246