rusteerio 1.1.1 → 1.1.3
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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/README.md +37 -37
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/{chunk-FPRP6UIX.mjs → chunk-HN63P3U7.mjs} +625 -401
- package/dist/chunk-HN63P3U7.mjs.map +1 -0
- package/dist/index.cjs +624 -400
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +1 -1
- package/dist/slim.cjs +555 -407
- package/dist/slim.cjs.map +1 -1
- package/dist/slim.d.mts +2 -2
- package/dist/slim.d.ts +2 -2
- package/dist/slim.mjs +1 -1
- package/dist/{types-Cs9UP1Vv.d.mts → types-CJsc0PH-.d.mts} +12 -0
- package/dist/{types-Cs9UP1Vv.d.ts → types-CJsc0PH-.d.ts} +12 -0
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/native/src/arena.rs +163 -7
- package/native/src/attributes.rs +18 -1
- package/native/src/codec.rs +79 -0
- package/native/src/lib.rs +119 -30
- package/native/src/runtime.rs +23 -0
- package/native/src/snapshot.rs +117 -80
- package/native/src/tokenizer.rs +34 -20
- package/package.json +1 -1
- package/rusteerio.darwin-arm64.node +0 -0
- package/rusteerio.darwin-x64.node +0 -0
- package/rusteerio.linux-arm64-gnu.node +0 -0
- package/rusteerio.linux-arm64-musl.node +0 -0
- package/rusteerio.linux-x64-gnu.node +0 -0
- package/rusteerio.linux-x64-musl.node +0 -0
- package/rusteerio.win32-arm64-msvc.node +0 -0
- package/rusteerio.win32-x64-msvc.node +0 -0
- package/src/extract.ts +117 -24
- package/src/index.ts +27 -6
- package/src/match.ts +4 -4
- package/src/native.ts +4 -0
- package/src/nodes.ts +70 -10
- package/src/router.ts +80 -4
- package/src/selection.ts +18 -17
- package/src/snapshot.ts +37 -0
- package/src/transport.ts +1 -1
- package/dist/chunk-FPRP6UIX.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -256,7 +256,7 @@ function wrapNativeBinding(binding) {
|
|
|
256
256
|
if (raw.NativeHookStream) wrapped.NativeHookStream = wrapConstructor(raw.NativeHookStream, ([isDocument2, options, bridge]) => [isDocument2, encodeOptions(options), wrapBridge(bridge)], wrapStream);
|
|
257
257
|
if (raw.parseWithTreeAdapter) wrapped.parseWithTreeAdapter = (source, isDocument2, options, bridge) => invoke(() => raw.parseWithTreeAdapter(encodeString(source), isDocument2, encodeOptions(options), wrapBridge(bridge)));
|
|
258
258
|
if (raw.parseAsync) wrapped.parseAsync = (source, isDocument2, options) => invoke(() => raw.parseAsync(encodeString(source), isDocument2, encodeOptions(options)));
|
|
259
|
-
if (raw.parseManyAsync) wrapped.parseManyAsync = (sources, isDocument2, threads, options) => invoke(() => raw.parseManyAsync(sources.map(encodeString), isDocument2, threads, encodeOptions(options)));
|
|
259
|
+
if (raw.parseManyAsync) wrapped.parseManyAsync = (sources, isDocument2, threads, options, plans) => invoke(() => raw.parseManyAsync(sources.map(encodeString), isDocument2, threads, encodeOptions(options), plans === void 0 ? void 0 : encodeJson(plans)));
|
|
260
260
|
if (raw.extractPlanManyAsync) wrapped.extractPlanManyAsync = async (sources, plan, threads, options) => decodeJson(await invoke(() => raw.extractPlanManyAsync(sources.map(encodeString), encodeJson(plan), threads, encodeOptions(options))));
|
|
261
261
|
if (raw.extractManyAsync) wrapped.extractManyAsync = async (sources, queries, threads, isDocument2, options) => decodeJson(await invoke(() => raw.extractManyAsync(sources.map(encodeString), queries.map((query) => ({ ...query, key: encodeString(query.key), selector: encodeString(query.selector), ...query.attr === void 0 ? {} : { attr: encodeString(query.attr) } })), threads, isDocument2, encodeOptions(options))));
|
|
262
262
|
return wrapped;
|
|
@@ -304,6 +304,284 @@ function nativeStatus() {
|
|
|
304
304
|
return available ? { available } : { available, error: String(bindingError ?? "Native binding not found") };
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
// src/snapshot.ts
|
|
308
|
+
var HEADER = 5;
|
|
309
|
+
var STRIDE = 15;
|
|
310
|
+
var ABSENT = 4294967295;
|
|
311
|
+
var HAS_START_INDEX = 1;
|
|
312
|
+
var HAS_END_INDEX = 2;
|
|
313
|
+
var HAS_NAMESPACE = 4;
|
|
314
|
+
var EMPTY_ATTRIBUTE_MAPS = 8;
|
|
315
|
+
var OPAQUE = 16;
|
|
316
|
+
var RELEASED = 32;
|
|
317
|
+
var noChildren = Object.freeze([]);
|
|
318
|
+
var noAttributes = Object.freeze({});
|
|
319
|
+
var SnapshotRecord = class {
|
|
320
|
+
constructor(snapshot, id, base) {
|
|
321
|
+
this.snapshot = snapshot;
|
|
322
|
+
this.id = id;
|
|
323
|
+
this.base = base;
|
|
324
|
+
this.decodedData = void 0;
|
|
325
|
+
this.decodedAttributes = void 0;
|
|
326
|
+
this.decodedChildren = void 0;
|
|
327
|
+
}
|
|
328
|
+
snapshot;
|
|
329
|
+
id;
|
|
330
|
+
base;
|
|
331
|
+
decodedData;
|
|
332
|
+
decodedAttributes;
|
|
333
|
+
decodedChildren;
|
|
334
|
+
get type() {
|
|
335
|
+
return this.snapshot.name(this.snapshot.nodes[this.base]);
|
|
336
|
+
}
|
|
337
|
+
get name() {
|
|
338
|
+
const name = this.snapshot.nodes[this.base + 6];
|
|
339
|
+
return name ? this.snapshot.name(name - 1) : void 0;
|
|
340
|
+
}
|
|
341
|
+
get data() {
|
|
342
|
+
if (this.decodedData !== void 0) return this.decodedData;
|
|
343
|
+
const data2 = this.snapshot.nodes[this.base + 7];
|
|
344
|
+
return data2 ? this.decodedData = this.snapshot.string(data2 - 1) : void 0;
|
|
345
|
+
}
|
|
346
|
+
get parent() {
|
|
347
|
+
const parent = this.snapshot.nodes[this.base + 1];
|
|
348
|
+
return parent ? parent - 1 : null;
|
|
349
|
+
}
|
|
350
|
+
get prev() {
|
|
351
|
+
const prev = this.snapshot.nodes[this.base + 2];
|
|
352
|
+
return prev ? prev - 1 : null;
|
|
353
|
+
}
|
|
354
|
+
get next() {
|
|
355
|
+
const next = this.snapshot.nodes[this.base + 3];
|
|
356
|
+
return next ? next - 1 : null;
|
|
357
|
+
}
|
|
358
|
+
get startIndex() {
|
|
359
|
+
return this.index(HAS_START_INDEX, 11);
|
|
360
|
+
}
|
|
361
|
+
get endIndex() {
|
|
362
|
+
return this.index(HAS_END_INDEX, 12);
|
|
363
|
+
}
|
|
364
|
+
get namespace() {
|
|
365
|
+
const nodes = this.snapshot.nodes;
|
|
366
|
+
return nodes[this.base + 10] & HAS_NAMESPACE ? this.snapshot.name(nodes[this.base + 13]) : void 0;
|
|
367
|
+
}
|
|
368
|
+
get attribsNamespace() {
|
|
369
|
+
return this.snapshot.nodes[this.base + 10] & EMPTY_ATTRIBUTE_MAPS ? {} : void 0;
|
|
370
|
+
}
|
|
371
|
+
get attribsPrefix() {
|
|
372
|
+
return this.snapshot.nodes[this.base + 10] & EMPTY_ATTRIBUTE_MAPS ? {} : void 0;
|
|
373
|
+
}
|
|
374
|
+
get attribs() {
|
|
375
|
+
return this.decodedAttributes ??= this.snapshot.attributesOf(this.id);
|
|
376
|
+
}
|
|
377
|
+
get children() {
|
|
378
|
+
return this.decodedChildren ??= this.snapshot.childrenOf(this.id);
|
|
379
|
+
}
|
|
380
|
+
index(flag, offset) {
|
|
381
|
+
const nodes = this.snapshot.nodes;
|
|
382
|
+
if (!(nodes[this.base + 10] & flag)) return void 0;
|
|
383
|
+
const value = nodes[this.base + offset];
|
|
384
|
+
return value === ABSENT ? null : value;
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
var recordFields = ["type", "name", "data", "parent", "prev", "next", "startIndex", "endIndex", "namespace", "attribsNamespace", "attribsPrefix", "attribs", "children"];
|
|
388
|
+
function plainRecord(record) {
|
|
389
|
+
if (!(record instanceof SnapshotRecord)) return record;
|
|
390
|
+
const copy = { id: record.id };
|
|
391
|
+
for (const field of recordFields) {
|
|
392
|
+
const value = record[field];
|
|
393
|
+
if (value !== void 0) copy[field] = value;
|
|
394
|
+
}
|
|
395
|
+
for (const key of Object.keys(record)) if (!key.startsWith("decoded") && key !== "snapshot" && key !== "base" && key !== "id") copy[key] = record[key];
|
|
396
|
+
return copy;
|
|
397
|
+
}
|
|
398
|
+
var NodeSnapshot = class {
|
|
399
|
+
size;
|
|
400
|
+
nodes;
|
|
401
|
+
children;
|
|
402
|
+
attributes;
|
|
403
|
+
strings;
|
|
404
|
+
text;
|
|
405
|
+
isEncoded;
|
|
406
|
+
names = [];
|
|
407
|
+
/** Per interned type: 1 for element types, 2 for root, 3 for text, 0 otherwise. */
|
|
408
|
+
typeKinds = [];
|
|
409
|
+
/** Node object constructors by interned type, resolved once per snapshot. */
|
|
410
|
+
viewConstructors = void 0;
|
|
411
|
+
/** Text nodes too large for the arrays, read individually while this snapshot is current. */
|
|
412
|
+
largeTexts = /* @__PURE__ */ new Map();
|
|
413
|
+
constructor(raw) {
|
|
414
|
+
const { data: data2 } = raw;
|
|
415
|
+
const childrenStart = HEADER + data2[0];
|
|
416
|
+
const attributesStart = childrenStart + data2[1];
|
|
417
|
+
const stringsStart = attributesStart + data2[2];
|
|
418
|
+
this.text = raw.text;
|
|
419
|
+
this.isEncoded = data2[4] === 1;
|
|
420
|
+
this.nodes = data2.subarray(HEADER, childrenStart);
|
|
421
|
+
this.children = data2.subarray(childrenStart, attributesStart);
|
|
422
|
+
this.attributes = data2.subarray(attributesStart, stringsStart);
|
|
423
|
+
this.strings = data2.subarray(stringsStart, stringsStart + data2[3]);
|
|
424
|
+
this.size = this.nodes.length / STRIDE;
|
|
425
|
+
}
|
|
426
|
+
/** The record, `null` for a released node, or `undefined` when it must be read individually. */
|
|
427
|
+
record(local) {
|
|
428
|
+
if (local >= this.size) return void 0;
|
|
429
|
+
const base = local * STRIDE;
|
|
430
|
+
const flags = this.nodes[base + 10];
|
|
431
|
+
if (flags & RELEASED) return null;
|
|
432
|
+
if (flags & OPAQUE) return void 0;
|
|
433
|
+
const record = new SnapshotRecord(this, local, base);
|
|
434
|
+
const extras = this.nodes[base + 14];
|
|
435
|
+
if (extras) {
|
|
436
|
+
const fields = JSON.parse(this.string(extras - 1));
|
|
437
|
+
for (const key of Object.keys(fields)) Object.defineProperty(record, key, { value: fields[key], writable: true, enumerable: true, configurable: true });
|
|
438
|
+
}
|
|
439
|
+
return record;
|
|
440
|
+
}
|
|
441
|
+
/** Whether a node's fields all live in the arrays, so callers may read them without a record. */
|
|
442
|
+
isPlain(local) {
|
|
443
|
+
if (local >= this.size) return false;
|
|
444
|
+
const base = local * STRIDE;
|
|
445
|
+
return (this.nodes[base + 10] & (OPAQUE | RELEASED)) === 0 && this.nodes[base + 14] === 0;
|
|
446
|
+
}
|
|
447
|
+
typeOf(local) {
|
|
448
|
+
return this.name(this.nodes[local * STRIDE]);
|
|
449
|
+
}
|
|
450
|
+
nameOf(local) {
|
|
451
|
+
const name = this.nodes[local * STRIDE + 6];
|
|
452
|
+
return name ? this.name(name - 1) : void 0;
|
|
453
|
+
}
|
|
454
|
+
dataOf(local) {
|
|
455
|
+
const data2 = this.nodes[local * STRIDE + 7];
|
|
456
|
+
return data2 ? this.string(data2 - 1) : void 0;
|
|
457
|
+
}
|
|
458
|
+
/** The parent, previous or next sibling (`offset` 1, 2 or 3), or `null`. */
|
|
459
|
+
linkOf(local, offset) {
|
|
460
|
+
const link = this.nodes[local * STRIDE + offset];
|
|
461
|
+
return link ? link - 1 : null;
|
|
462
|
+
}
|
|
463
|
+
namespaceOf(local) {
|
|
464
|
+
const base = local * STRIDE;
|
|
465
|
+
return this.nodes[base + 10] & HAS_NAMESPACE ? this.name(this.nodes[base + 13]) : void 0;
|
|
466
|
+
}
|
|
467
|
+
/** A node's attributes as parse5 attribute objects; plain nodes have no namespaced ones. */
|
|
468
|
+
attributeObjects(local) {
|
|
469
|
+
const base = local * STRIDE;
|
|
470
|
+
const count = this.nodes[base + 9];
|
|
471
|
+
const first = this.nodes[base + 8];
|
|
472
|
+
const attributes = this.attributes;
|
|
473
|
+
const result = new Array(count);
|
|
474
|
+
for (let index = 0; index < count; index++) {
|
|
475
|
+
const pair = (first + index) * 2;
|
|
476
|
+
result[index] = { name: this.name(attributes[pair]), value: this.string(attributes[pair + 1]) };
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
/** Copies a node's attributes onto `target`, in order. */
|
|
481
|
+
copyAttributes(local, target) {
|
|
482
|
+
const base = local * STRIDE;
|
|
483
|
+
const count = this.nodes[base + 9];
|
|
484
|
+
const first = this.nodes[base + 8];
|
|
485
|
+
const attributes = this.attributes;
|
|
486
|
+
for (let index = 0; index < count; index++) {
|
|
487
|
+
const pair = (first + index) * 2;
|
|
488
|
+
const name = this.name(attributes[pair]);
|
|
489
|
+
const value = this.string(attributes[pair + 1]);
|
|
490
|
+
if (name === "__proto__") Object.defineProperty(target, name, { value, writable: true, enumerable: true, configurable: true });
|
|
491
|
+
else target[name] = value;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/** The flat child id list; a node's children start at `childStart(local)`. */
|
|
495
|
+
get childIds() {
|
|
496
|
+
return this.children;
|
|
497
|
+
}
|
|
498
|
+
childStart(local) {
|
|
499
|
+
return this.nodes[local * STRIDE + 4];
|
|
500
|
+
}
|
|
501
|
+
/** Whether a node is an element: a tag, script or style. */
|
|
502
|
+
isElementAt(local) {
|
|
503
|
+
return this.typeKind(local) === 1;
|
|
504
|
+
}
|
|
505
|
+
isRootAt(local) {
|
|
506
|
+
return this.typeKind(local) === 2;
|
|
507
|
+
}
|
|
508
|
+
isTextAt(local) {
|
|
509
|
+
return this.typeKind(local) === 3;
|
|
510
|
+
}
|
|
511
|
+
/** Whether a node's record adds fields stored as JSON, such as source locations. */
|
|
512
|
+
hasExtraFields(local) {
|
|
513
|
+
return this.nodes[local * STRIDE + 14] !== 0;
|
|
514
|
+
}
|
|
515
|
+
/** Whether the slot holds a node, rather than one a collection released. */
|
|
516
|
+
isPresent(local) {
|
|
517
|
+
return local < this.size && (this.nodes[local * STRIDE + 10] & RELEASED) === 0;
|
|
518
|
+
}
|
|
519
|
+
typeKind(local) {
|
|
520
|
+
const reference = this.nodes[local * STRIDE];
|
|
521
|
+
let kind = this.typeKinds[reference];
|
|
522
|
+
if (kind === void 0) {
|
|
523
|
+
const type = this.name(reference);
|
|
524
|
+
kind = this.typeKinds[reference] = type === "tag" || type === "script" || type === "style" ? 1 : type === "root" ? 2 : type === "text" ? 3 : 0;
|
|
525
|
+
}
|
|
526
|
+
return kind;
|
|
527
|
+
}
|
|
528
|
+
/** The interned reference of a node's type, comparable across nodes of this snapshot. */
|
|
529
|
+
typeReference(local) {
|
|
530
|
+
return this.nodes[local * STRIDE];
|
|
531
|
+
}
|
|
532
|
+
/** Child ids without materializing the record. */
|
|
533
|
+
childCount(local) {
|
|
534
|
+
return this.nodes[local * STRIDE + 5];
|
|
535
|
+
}
|
|
536
|
+
childAt(local, index) {
|
|
537
|
+
return this.children[this.nodes[local * STRIDE + 4] + index];
|
|
538
|
+
}
|
|
539
|
+
childrenOf(local) {
|
|
540
|
+
const base = local * STRIDE;
|
|
541
|
+
const count = this.nodes[base + 5];
|
|
542
|
+
if (count === 0) return noChildren;
|
|
543
|
+
const first = this.nodes[base + 4];
|
|
544
|
+
return Array.from(this.children.subarray(first, first + count));
|
|
545
|
+
}
|
|
546
|
+
attributesOf(local) {
|
|
547
|
+
const base = local * STRIDE;
|
|
548
|
+
const count = this.nodes[base + 9];
|
|
549
|
+
if (count === 0) return noAttributes;
|
|
550
|
+
const first = this.nodes[base + 8];
|
|
551
|
+
const attributes = this.attributes;
|
|
552
|
+
const result = {};
|
|
553
|
+
for (let index = 0; index < count; index++) {
|
|
554
|
+
const pair = (first + index) * 2;
|
|
555
|
+
const name = this.name(attributes[pair]);
|
|
556
|
+
const value = this.string(attributes[pair + 1]);
|
|
557
|
+
if (name === "__proto__") Object.defineProperty(result, name, { value, writable: true, enumerable: true, configurable: true });
|
|
558
|
+
else result[name] = value;
|
|
559
|
+
}
|
|
560
|
+
return result;
|
|
561
|
+
}
|
|
562
|
+
/** One attribute's value, without decoding the rest. */
|
|
563
|
+
attributeValue(local, name) {
|
|
564
|
+
const base = local * STRIDE;
|
|
565
|
+
const count = this.nodes[base + 9];
|
|
566
|
+
const first = this.nodes[base + 8];
|
|
567
|
+
const attributes = this.attributes;
|
|
568
|
+
for (let index = count - 1; index >= 0; index--) {
|
|
569
|
+
const pair = (first + index) * 2;
|
|
570
|
+
if (this.name(attributes[pair]) === name) return this.string(attributes[pair + 1]);
|
|
571
|
+
}
|
|
572
|
+
return void 0;
|
|
573
|
+
}
|
|
574
|
+
string(reference) {
|
|
575
|
+
const strings = this.strings;
|
|
576
|
+
const value = this.text.slice(strings[reference * 2], strings[reference * 2 + 1]);
|
|
577
|
+
return this.isEncoded ? decodeString(value) : value;
|
|
578
|
+
}
|
|
579
|
+
/** Names repeat across nodes, so each decodes once. */
|
|
580
|
+
name(reference) {
|
|
581
|
+
return this.names[reference] ??= this.string(reference);
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
|
|
307
585
|
// src/hooks.ts
|
|
308
586
|
var tokenCallbacks = ["onattribdata", "onattribentity", "onattribend", "onattribname", "oncdata", "onclosetag", "oncomment", "ondeclaration", "onend", "onopentagend", "onopentagname", "onprocessinginstruction", "onselfclosingtag", "ontext", "ontextentity"];
|
|
309
587
|
function createTokenizerSession(options) {
|
|
@@ -606,357 +884,110 @@ function replayIntoAdapter(document, adapter, isDocument2) {
|
|
|
606
884
|
for (let local = 0; local < Math.min(size, 65); local++) recordAt(state, local);
|
|
607
885
|
for (let local = 0; local < size; local++) {
|
|
608
886
|
const snapshot = plainSnapshot(state, local);
|
|
609
|
-
const record = snapshot ? void 0 : recordAt(state, local);
|
|
610
|
-
if (!snapshot && !record) continue;
|
|
611
|
-
const type = snapshot ? snapshot.typeOf(local) : record.type;
|
|
612
|
-
if (local === root) {
|
|
613
|
-
nodes[local] = isDocument2 ? adapter.createDocument() : adapter.createDocumentFragment();
|
|
614
|
-
const mode = record?.["x-mode"];
|
|
615
|
-
if (isDocument2 && mode !== void 0) adapter.setDocumentMode(nodes[local], mode);
|
|
616
|
-
continue;
|
|
617
|
-
}
|
|
618
|
-
const parentLocal = snapshot ? snapshot.linkOf(local, 1) : record.parent;
|
|
619
|
-
const parent = parentLocal == null ? void 0 : nodes[parentLocal];
|
|
620
|
-
if (parent === void 0) return void 0;
|
|
621
|
-
switch (type) {
|
|
622
|
-
case "tag":
|
|
623
|
-
case "script":
|
|
624
|
-
case "style": {
|
|
625
|
-
const element = snapshot ? adapter.createElement(snapshot.nameOf(local), snapshot.namespaceOf(local), snapshot.attributeObjects(local)) : adapter.createElement(record.name, record.namespace, attributeList(record));
|
|
626
|
-
adapter.appendChild(parent, element);
|
|
627
|
-
nodes[local] = element;
|
|
628
|
-
break;
|
|
629
|
-
}
|
|
630
|
-
case "root": {
|
|
631
|
-
const content = adapter.createDocumentFragment();
|
|
632
|
-
adapter.setTemplateContent(parent, content);
|
|
633
|
-
nodes[local] = content;
|
|
634
|
-
break;
|
|
635
|
-
}
|
|
636
|
-
case "text": {
|
|
637
|
-
adapter.insertText(parent, (snapshot ? snapshot.dataOf(local) : record.data) ?? "");
|
|
638
|
-
const children = adapter.getChildNodes(parent);
|
|
639
|
-
nodes[local] = children[children.length - 1];
|
|
640
|
-
break;
|
|
641
|
-
}
|
|
642
|
-
case "comment": {
|
|
643
|
-
const comment = adapter.createCommentNode((snapshot ? snapshot.dataOf(local) : record.data) ?? "");
|
|
644
|
-
adapter.appendChild(parent, comment);
|
|
645
|
-
nodes[local] = comment;
|
|
646
|
-
break;
|
|
647
|
-
}
|
|
648
|
-
case "directive": {
|
|
649
|
-
if (!record || record.name !== "!doctype" || !isDocument2) return void 0;
|
|
650
|
-
adapter.setDocumentType(parent, record["x-name"] ?? "", record["x-publicId"] ?? "", record["x-systemId"] ?? "");
|
|
651
|
-
nodes[local] = Array.from(adapter.getChildNodes(parent) ?? []).find((child) => adapter.isDocumentTypeNode(child));
|
|
652
|
-
break;
|
|
653
|
-
}
|
|
654
|
-
default:
|
|
655
|
-
return void 0;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
const changes = differencesFromParse(adapter, nodes, state, root);
|
|
659
|
-
if (!changes) return void 0;
|
|
660
|
-
for (const change of changes) operation(document, "setNode", { id: state.base + change.local, field: change.field, value: change.value });
|
|
661
|
-
return nodes;
|
|
662
|
-
}
|
|
663
|
-
function attributeList(record) {
|
|
664
|
-
const attributes = record.attribs ?? {};
|
|
665
|
-
return Object.keys(attributes).map((name) => {
|
|
666
|
-
const namespace = record.attribsNamespace?.[name];
|
|
667
|
-
const prefix = record.attribsPrefix?.[name];
|
|
668
|
-
return { name, value: attributes[name], ...namespace === void 0 ? {} : { namespace }, ...prefix === void 0 ? {} : { prefix } };
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
function differencesFromParse(adapter, nodes, state, root) {
|
|
672
|
-
const changes = [];
|
|
673
|
-
for (let local = 0; local < nodes.length; local++) {
|
|
674
|
-
const node = nodes[local];
|
|
675
|
-
const snapshot = plainSnapshot(state, local);
|
|
676
|
-
const record = snapshot ? void 0 : recordAt(state, local);
|
|
677
|
-
if (!snapshot && !record) continue;
|
|
678
|
-
if (!node) return void 0;
|
|
679
|
-
const type = snapshot ? snapshot.typeOf(local) : record.type;
|
|
680
|
-
if (local !== root && adapter.getParentNode(node) !== nodes[snapshot ? snapshot.linkOf(local, 1) : record.parent]) return void 0;
|
|
681
|
-
if (type !== "text" && type !== "comment" && type !== "directive") {
|
|
682
|
-
const children = adapter.getChildNodes(node) ?? [];
|
|
683
|
-
const count = snapshot ? snapshot.childCount(local) : record.children.length;
|
|
684
|
-
if (children.length !== count) return void 0;
|
|
685
|
-
for (let index = 0; index < count; index++) if (children[index] !== nodes[snapshot ? snapshot.childAt(local, index) : record.children[index]]) return void 0;
|
|
686
|
-
}
|
|
687
|
-
if (type === "tag" || type === "script" || type === "style") {
|
|
688
|
-
const name = snapshot ? snapshot.nameOf(local) : record.name;
|
|
689
|
-
const namespace = snapshot ? snapshot.namespaceOf(local) : record.namespace;
|
|
690
|
-
if (!adapter.isElementNode(node) || adapter.getTagName(node) !== name || adapter.getNamespaceURI(node) !== namespace) return void 0;
|
|
691
|
-
const attributes = adapter.getAttrList(node) ?? [];
|
|
692
|
-
const expected = snapshot ? snapshot.attributeObjects(local) : attributeList(record);
|
|
693
|
-
const isSame = attributes.length === expected.length && attributes.every((attribute, index) => attribute.name === expected[index].name && attribute.value === expected[index].value);
|
|
694
|
-
if (!isSame) {
|
|
695
|
-
const values = /* @__PURE__ */ Object.create(null);
|
|
696
|
-
const namespaces = /* @__PURE__ */ Object.create(null);
|
|
697
|
-
const prefixes = /* @__PURE__ */ Object.create(null);
|
|
698
|
-
for (const attribute of attributes) {
|
|
699
|
-
values[attribute.name] = attribute.value;
|
|
700
|
-
if (attribute.namespace !== void 0) namespaces[attribute.name] = attribute.namespace;
|
|
701
|
-
if (attribute.prefix !== void 0) prefixes[attribute.name] = attribute.prefix;
|
|
702
|
-
}
|
|
703
|
-
changes.push({ local, field: "attribs", value: values }, { local, field: "attribsNamespace", value: namespaces }, { local, field: "attribsPrefix", value: prefixes });
|
|
704
|
-
}
|
|
705
|
-
} else if (type === "text" || type === "comment") {
|
|
706
|
-
if (type === "text" ? !adapter.isTextNode(node) : !adapter.isCommentNode(node)) return void 0;
|
|
707
|
-
const data2 = type === "text" ? adapter.getTextNodeContent(node) : adapter.getCommentNodeContent(node);
|
|
708
|
-
if (data2 !== (snapshot ? snapshot.dataOf(local) : record.data)) changes.push({ local, field: "data", value: data2 });
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
return changes;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
// src/snapshot.ts
|
|
715
|
-
var HEADER = 5;
|
|
716
|
-
var STRIDE = 15;
|
|
717
|
-
var ABSENT = 4294967295;
|
|
718
|
-
var HAS_START_INDEX = 1;
|
|
719
|
-
var HAS_END_INDEX = 2;
|
|
720
|
-
var HAS_NAMESPACE = 4;
|
|
721
|
-
var EMPTY_ATTRIBUTE_MAPS = 8;
|
|
722
|
-
var OPAQUE = 16;
|
|
723
|
-
var RELEASED = 32;
|
|
724
|
-
var noChildren = Object.freeze([]);
|
|
725
|
-
var noAttributes = Object.freeze({});
|
|
726
|
-
var SnapshotRecord = class {
|
|
727
|
-
constructor(snapshot, id, base) {
|
|
728
|
-
this.snapshot = snapshot;
|
|
729
|
-
this.id = id;
|
|
730
|
-
this.base = base;
|
|
731
|
-
this.decodedData = void 0;
|
|
732
|
-
this.decodedAttributes = void 0;
|
|
733
|
-
this.decodedChildren = void 0;
|
|
734
|
-
}
|
|
735
|
-
snapshot;
|
|
736
|
-
id;
|
|
737
|
-
base;
|
|
738
|
-
decodedData;
|
|
739
|
-
decodedAttributes;
|
|
740
|
-
decodedChildren;
|
|
741
|
-
get type() {
|
|
742
|
-
return this.snapshot.name(this.snapshot.nodes[this.base]);
|
|
743
|
-
}
|
|
744
|
-
get name() {
|
|
745
|
-
const name = this.snapshot.nodes[this.base + 6];
|
|
746
|
-
return name ? this.snapshot.name(name - 1) : void 0;
|
|
747
|
-
}
|
|
748
|
-
get data() {
|
|
749
|
-
if (this.decodedData !== void 0) return this.decodedData;
|
|
750
|
-
const data2 = this.snapshot.nodes[this.base + 7];
|
|
751
|
-
return data2 ? this.decodedData = this.snapshot.string(data2 - 1) : void 0;
|
|
752
|
-
}
|
|
753
|
-
get parent() {
|
|
754
|
-
const parent = this.snapshot.nodes[this.base + 1];
|
|
755
|
-
return parent ? parent - 1 : null;
|
|
756
|
-
}
|
|
757
|
-
get prev() {
|
|
758
|
-
const prev = this.snapshot.nodes[this.base + 2];
|
|
759
|
-
return prev ? prev - 1 : null;
|
|
760
|
-
}
|
|
761
|
-
get next() {
|
|
762
|
-
const next = this.snapshot.nodes[this.base + 3];
|
|
763
|
-
return next ? next - 1 : null;
|
|
764
|
-
}
|
|
765
|
-
get startIndex() {
|
|
766
|
-
return this.index(HAS_START_INDEX, 11);
|
|
767
|
-
}
|
|
768
|
-
get endIndex() {
|
|
769
|
-
return this.index(HAS_END_INDEX, 12);
|
|
770
|
-
}
|
|
771
|
-
get namespace() {
|
|
772
|
-
const nodes = this.snapshot.nodes;
|
|
773
|
-
return nodes[this.base + 10] & HAS_NAMESPACE ? this.snapshot.name(nodes[this.base + 13]) : void 0;
|
|
774
|
-
}
|
|
775
|
-
get attribsNamespace() {
|
|
776
|
-
return this.snapshot.nodes[this.base + 10] & EMPTY_ATTRIBUTE_MAPS ? {} : void 0;
|
|
777
|
-
}
|
|
778
|
-
get attribsPrefix() {
|
|
779
|
-
return this.snapshot.nodes[this.base + 10] & EMPTY_ATTRIBUTE_MAPS ? {} : void 0;
|
|
780
|
-
}
|
|
781
|
-
get attribs() {
|
|
782
|
-
return this.decodedAttributes ??= this.snapshot.attributesOf(this.id);
|
|
783
|
-
}
|
|
784
|
-
get children() {
|
|
785
|
-
return this.decodedChildren ??= this.snapshot.childrenOf(this.id);
|
|
786
|
-
}
|
|
787
|
-
index(flag, offset) {
|
|
788
|
-
const nodes = this.snapshot.nodes;
|
|
789
|
-
if (!(nodes[this.base + 10] & flag)) return void 0;
|
|
790
|
-
const value = nodes[this.base + offset];
|
|
791
|
-
return value === ABSENT ? null : value;
|
|
792
|
-
}
|
|
793
|
-
};
|
|
794
|
-
var recordFields = ["type", "name", "data", "parent", "prev", "next", "startIndex", "endIndex", "namespace", "attribsNamespace", "attribsPrefix", "attribs", "children"];
|
|
795
|
-
function plainRecord(record) {
|
|
796
|
-
if (!(record instanceof SnapshotRecord)) return record;
|
|
797
|
-
const copy = { id: record.id };
|
|
798
|
-
for (const field of recordFields) {
|
|
799
|
-
const value = record[field];
|
|
800
|
-
if (value !== void 0) copy[field] = value;
|
|
801
|
-
}
|
|
802
|
-
for (const key of Object.keys(record)) if (!key.startsWith("decoded") && key !== "snapshot" && key !== "base" && key !== "id") copy[key] = record[key];
|
|
803
|
-
return copy;
|
|
804
|
-
}
|
|
805
|
-
var NodeSnapshot = class {
|
|
806
|
-
size;
|
|
807
|
-
nodes;
|
|
808
|
-
children;
|
|
809
|
-
attributes;
|
|
810
|
-
strings;
|
|
811
|
-
text;
|
|
812
|
-
isEncoded;
|
|
813
|
-
names = [];
|
|
814
|
-
/** Node object constructors by interned type, resolved once per snapshot. */
|
|
815
|
-
viewConstructors = void 0;
|
|
816
|
-
constructor(raw) {
|
|
817
|
-
const { data: data2 } = raw;
|
|
818
|
-
const childrenStart = HEADER + data2[0];
|
|
819
|
-
const attributesStart = childrenStart + data2[1];
|
|
820
|
-
const stringsStart = attributesStart + data2[2];
|
|
821
|
-
this.text = raw.text;
|
|
822
|
-
this.isEncoded = data2[4] === 1;
|
|
823
|
-
this.nodes = data2.subarray(HEADER, childrenStart);
|
|
824
|
-
this.children = data2.subarray(childrenStart, attributesStart);
|
|
825
|
-
this.attributes = data2.subarray(attributesStart, stringsStart);
|
|
826
|
-
this.strings = data2.subarray(stringsStart, stringsStart + data2[3]);
|
|
827
|
-
this.size = this.nodes.length / STRIDE;
|
|
828
|
-
}
|
|
829
|
-
/** The record, `null` for a released node, or `undefined` when it must be read individually. */
|
|
830
|
-
record(local) {
|
|
831
|
-
if (local >= this.size) return void 0;
|
|
832
|
-
const base = local * STRIDE;
|
|
833
|
-
const flags = this.nodes[base + 10];
|
|
834
|
-
if (flags & RELEASED) return null;
|
|
835
|
-
if (flags & OPAQUE) return void 0;
|
|
836
|
-
const record = new SnapshotRecord(this, local, base);
|
|
837
|
-
const extras = this.nodes[base + 14];
|
|
838
|
-
if (extras) {
|
|
839
|
-
const fields = JSON.parse(this.string(extras - 1));
|
|
840
|
-
for (const key of Object.keys(fields)) Object.defineProperty(record, key, { value: fields[key], writable: true, enumerable: true, configurable: true });
|
|
841
|
-
}
|
|
842
|
-
return record;
|
|
843
|
-
}
|
|
844
|
-
/** Whether a node's fields all live in the arrays, so callers may read them without a record. */
|
|
845
|
-
isPlain(local) {
|
|
846
|
-
if (local >= this.size) return false;
|
|
847
|
-
const base = local * STRIDE;
|
|
848
|
-
return (this.nodes[base + 10] & (OPAQUE | RELEASED)) === 0 && this.nodes[base + 14] === 0;
|
|
849
|
-
}
|
|
850
|
-
typeOf(local) {
|
|
851
|
-
return this.name(this.nodes[local * STRIDE]);
|
|
852
|
-
}
|
|
853
|
-
nameOf(local) {
|
|
854
|
-
const name = this.nodes[local * STRIDE + 6];
|
|
855
|
-
return name ? this.name(name - 1) : void 0;
|
|
856
|
-
}
|
|
857
|
-
dataOf(local) {
|
|
858
|
-
const data2 = this.nodes[local * STRIDE + 7];
|
|
859
|
-
return data2 ? this.string(data2 - 1) : void 0;
|
|
860
|
-
}
|
|
861
|
-
/** The parent, previous or next sibling (`offset` 1, 2 or 3), or `null`. */
|
|
862
|
-
linkOf(local, offset) {
|
|
863
|
-
const link = this.nodes[local * STRIDE + offset];
|
|
864
|
-
return link ? link - 1 : null;
|
|
865
|
-
}
|
|
866
|
-
namespaceOf(local) {
|
|
867
|
-
const base = local * STRIDE;
|
|
868
|
-
return this.nodes[base + 10] & HAS_NAMESPACE ? this.name(this.nodes[base + 13]) : void 0;
|
|
869
|
-
}
|
|
870
|
-
/** A node's attributes as parse5 attribute objects; plain nodes have no namespaced ones. */
|
|
871
|
-
attributeObjects(local) {
|
|
872
|
-
const base = local * STRIDE;
|
|
873
|
-
const count = this.nodes[base + 9];
|
|
874
|
-
const first = this.nodes[base + 8];
|
|
875
|
-
const attributes = this.attributes;
|
|
876
|
-
const result = new Array(count);
|
|
877
|
-
for (let index = 0; index < count; index++) {
|
|
878
|
-
const pair = (first + index) * 2;
|
|
879
|
-
result[index] = { name: this.name(attributes[pair]), value: this.string(attributes[pair + 1]) };
|
|
887
|
+
const record = snapshot ? void 0 : recordAt(state, local);
|
|
888
|
+
if (!snapshot && !record) continue;
|
|
889
|
+
const type = snapshot ? snapshot.typeOf(local) : record.type;
|
|
890
|
+
if (local === root) {
|
|
891
|
+
nodes[local] = isDocument2 ? adapter.createDocument() : adapter.createDocumentFragment();
|
|
892
|
+
const mode = record?.["x-mode"];
|
|
893
|
+
if (isDocument2 && mode !== void 0) adapter.setDocumentMode(nodes[local], mode);
|
|
894
|
+
continue;
|
|
880
895
|
}
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
896
|
+
const parentLocal = snapshot ? snapshot.linkOf(local, 1) : record.parent;
|
|
897
|
+
const parent = parentLocal == null ? void 0 : nodes[parentLocal];
|
|
898
|
+
if (parent === void 0) return void 0;
|
|
899
|
+
switch (type) {
|
|
900
|
+
case "tag":
|
|
901
|
+
case "script":
|
|
902
|
+
case "style": {
|
|
903
|
+
const element = snapshot ? adapter.createElement(snapshot.nameOf(local), snapshot.namespaceOf(local), snapshot.attributeObjects(local)) : adapter.createElement(record.name, record.namespace, attributeList(record));
|
|
904
|
+
adapter.appendChild(parent, element);
|
|
905
|
+
nodes[local] = element;
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
908
|
+
case "root": {
|
|
909
|
+
const content = adapter.createDocumentFragment();
|
|
910
|
+
adapter.setTemplateContent(parent, content);
|
|
911
|
+
nodes[local] = content;
|
|
912
|
+
break;
|
|
913
|
+
}
|
|
914
|
+
case "text": {
|
|
915
|
+
adapter.insertText(parent, (snapshot ? snapshot.dataOf(local) : record.data) ?? "");
|
|
916
|
+
const children = adapter.getChildNodes(parent);
|
|
917
|
+
nodes[local] = children[children.length - 1];
|
|
918
|
+
break;
|
|
919
|
+
}
|
|
920
|
+
case "comment": {
|
|
921
|
+
const comment = adapter.createCommentNode((snapshot ? snapshot.dataOf(local) : record.data) ?? "");
|
|
922
|
+
adapter.appendChild(parent, comment);
|
|
923
|
+
nodes[local] = comment;
|
|
924
|
+
break;
|
|
925
|
+
}
|
|
926
|
+
case "directive": {
|
|
927
|
+
if (!record || record.name !== "!doctype" || !isDocument2) return void 0;
|
|
928
|
+
adapter.setDocumentType(parent, record["x-name"] ?? "", record["x-publicId"] ?? "", record["x-systemId"] ?? "");
|
|
929
|
+
nodes[local] = Array.from(adapter.getChildNodes(parent) ?? []).find((child) => adapter.isDocumentTypeNode(child));
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
default:
|
|
933
|
+
return void 0;
|
|
895
934
|
}
|
|
896
935
|
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
if (count === 0) return noAttributes;
|
|
926
|
-
const first = this.nodes[base + 8];
|
|
927
|
-
const attributes = this.attributes;
|
|
928
|
-
const result = {};
|
|
929
|
-
for (let index = 0; index < count; index++) {
|
|
930
|
-
const pair = (first + index) * 2;
|
|
931
|
-
const name = this.name(attributes[pair]);
|
|
932
|
-
const value = this.string(attributes[pair + 1]);
|
|
933
|
-
if (name === "__proto__") Object.defineProperty(result, name, { value, writable: true, enumerable: true, configurable: true });
|
|
934
|
-
else result[name] = value;
|
|
936
|
+
const changes = differencesFromParse(adapter, nodes, state, root);
|
|
937
|
+
if (!changes) return void 0;
|
|
938
|
+
for (const change of changes) operation(document, "setNode", { id: state.base + change.local, field: change.field, value: change.value });
|
|
939
|
+
return nodes;
|
|
940
|
+
}
|
|
941
|
+
function attributeList(record) {
|
|
942
|
+
const attributes = record.attribs ?? {};
|
|
943
|
+
return Object.keys(attributes).map((name) => {
|
|
944
|
+
const namespace = record.attribsNamespace?.[name];
|
|
945
|
+
const prefix = record.attribsPrefix?.[name];
|
|
946
|
+
return { name, value: attributes[name], ...namespace === void 0 ? {} : { namespace }, ...prefix === void 0 ? {} : { prefix } };
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
function differencesFromParse(adapter, nodes, state, root) {
|
|
950
|
+
const changes = [];
|
|
951
|
+
for (let local = 0; local < nodes.length; local++) {
|
|
952
|
+
const node = nodes[local];
|
|
953
|
+
const snapshot = plainSnapshot(state, local);
|
|
954
|
+
const record = snapshot ? void 0 : recordAt(state, local);
|
|
955
|
+
if (!snapshot && !record) continue;
|
|
956
|
+
if (!node) return void 0;
|
|
957
|
+
const type = snapshot ? snapshot.typeOf(local) : record.type;
|
|
958
|
+
if (local !== root && adapter.getParentNode(node) !== nodes[snapshot ? snapshot.linkOf(local, 1) : record.parent]) return void 0;
|
|
959
|
+
if (type !== "text" && type !== "comment" && type !== "directive") {
|
|
960
|
+
const children = adapter.getChildNodes(node) ?? [];
|
|
961
|
+
const count = snapshot ? snapshot.childCount(local) : record.children.length;
|
|
962
|
+
if (children.length !== count) return void 0;
|
|
963
|
+
for (let index = 0; index < count; index++) if (children[index] !== nodes[snapshot ? snapshot.childAt(local, index) : record.children[index]]) return void 0;
|
|
935
964
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
965
|
+
if (type === "tag" || type === "script" || type === "style") {
|
|
966
|
+
const name = snapshot ? snapshot.nameOf(local) : record.name;
|
|
967
|
+
const namespace = snapshot ? snapshot.namespaceOf(local) : record.namespace;
|
|
968
|
+
if (!adapter.isElementNode(node) || adapter.getTagName(node) !== name || adapter.getNamespaceURI(node) !== namespace) return void 0;
|
|
969
|
+
const attributes = adapter.getAttrList(node) ?? [];
|
|
970
|
+
const expected = snapshot ? snapshot.attributeObjects(local) : attributeList(record);
|
|
971
|
+
const isSame = attributes.length === expected.length && attributes.every((attribute, index) => attribute.name === expected[index].name && attribute.value === expected[index].value);
|
|
972
|
+
if (!isSame) {
|
|
973
|
+
const values = /* @__PURE__ */ Object.create(null);
|
|
974
|
+
const namespaces = /* @__PURE__ */ Object.create(null);
|
|
975
|
+
const prefixes = /* @__PURE__ */ Object.create(null);
|
|
976
|
+
for (const attribute of attributes) {
|
|
977
|
+
values[attribute.name] = attribute.value;
|
|
978
|
+
if (attribute.namespace !== void 0) namespaces[attribute.name] = attribute.namespace;
|
|
979
|
+
if (attribute.prefix !== void 0) prefixes[attribute.name] = attribute.prefix;
|
|
980
|
+
}
|
|
981
|
+
changes.push({ local, field: "attribs", value: values }, { local, field: "attribsNamespace", value: namespaces }, { local, field: "attribsPrefix", value: prefixes });
|
|
982
|
+
}
|
|
983
|
+
} else if (type === "text" || type === "comment") {
|
|
984
|
+
if (type === "text" ? !adapter.isTextNode(node) : !adapter.isCommentNode(node)) return void 0;
|
|
985
|
+
const data2 = type === "text" ? adapter.getTextNodeContent(node) : adapter.getCommentNodeContent(node);
|
|
986
|
+
if (data2 !== (snapshot ? snapshot.dataOf(local) : record.data)) changes.push({ local, field: "data", value: data2 });
|
|
947
987
|
}
|
|
948
|
-
return void 0;
|
|
949
988
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
const value = this.text.slice(strings[reference * 2], strings[reference * 2 + 1]);
|
|
953
|
-
return this.isEncoded ? decodeString(value) : value;
|
|
954
|
-
}
|
|
955
|
-
/** Names repeat across nodes, so each decodes once. */
|
|
956
|
-
name(reference) {
|
|
957
|
-
return this.names[reference] ??= this.string(reference);
|
|
958
|
-
}
|
|
959
|
-
};
|
|
989
|
+
return changes;
|
|
990
|
+
}
|
|
960
991
|
|
|
961
992
|
// src/router.ts
|
|
962
993
|
var STRIDE2 = 2 ** 32;
|
|
@@ -1055,7 +1086,8 @@ function stateFor(raw, options = {}) {
|
|
|
1055
1086
|
isExposed: false,
|
|
1056
1087
|
hasChildLists: false,
|
|
1057
1088
|
collectionRetries: 0,
|
|
1058
|
-
isCollectionEvicted: false
|
|
1089
|
+
isCollectionEvicted: false,
|
|
1090
|
+
hasPreparedSnapshot: false
|
|
1059
1091
|
};
|
|
1060
1092
|
holder[stateKey] = state;
|
|
1061
1093
|
return state;
|
|
@@ -1180,7 +1212,7 @@ function readRecord(state, local) {
|
|
|
1180
1212
|
const size = Math.max(state.snapshotSize, state.baseline);
|
|
1181
1213
|
const firstSnapshotRead = state.generation === 0 ? size / 100 : 1 + size / 100;
|
|
1182
1214
|
if (reads >= Math.min(minimumReadsBeforeSnapshot, firstSnapshotRead)) {
|
|
1183
|
-
const snapshot = new NodeSnapshot(state.raw.snapshot());
|
|
1215
|
+
const snapshot = new NodeSnapshot(takePreparedSnapshot(state, true) ?? state.raw.snapshot());
|
|
1184
1216
|
state.snapshotSize = snapshot.size;
|
|
1185
1217
|
state.bulk = snapshot;
|
|
1186
1218
|
const record = snapshot.record(local);
|
|
@@ -1189,10 +1221,45 @@ function readRecord(state, local) {
|
|
|
1189
1221
|
}
|
|
1190
1222
|
return rawOperation(state.raw, "node", { id: local });
|
|
1191
1223
|
}
|
|
1224
|
+
function usePreparedSnapshot(document) {
|
|
1225
|
+
if (!(document instanceof RoutedDocument)) return;
|
|
1226
|
+
const state = document.state;
|
|
1227
|
+
state.hasPreparedSnapshot = state.generation === 0 && state.bulk === 0;
|
|
1228
|
+
}
|
|
1229
|
+
function takePreparedSnapshot(state, isWanted) {
|
|
1230
|
+
if (!state.hasPreparedSnapshot) return void 0;
|
|
1231
|
+
state.hasPreparedSnapshot = false;
|
|
1232
|
+
return state.raw.takePreparedSnapshot?.(isWanted) ?? void 0;
|
|
1233
|
+
}
|
|
1192
1234
|
function plainSnapshot(state, local) {
|
|
1193
1235
|
const bulk = state.bulk;
|
|
1194
1236
|
return bulk instanceof NodeSnapshot && !(state.stale.size && state.stale.has(local)) && bulk.isPlain(local) ? bulk : void 0;
|
|
1195
1237
|
}
|
|
1238
|
+
function structureSnapshot(state, local) {
|
|
1239
|
+
const bulk = state.bulk;
|
|
1240
|
+
return bulk instanceof NodeSnapshot && !(state.stale.size && state.stale.has(local)) && bulk.isPresent(local) ? bulk : void 0;
|
|
1241
|
+
}
|
|
1242
|
+
var snapshotTextBudget = 256;
|
|
1243
|
+
function textFromSnapshot(state, local) {
|
|
1244
|
+
let text = "";
|
|
1245
|
+
const stack = [local];
|
|
1246
|
+
for (let visited = 0; stack.length; visited++) {
|
|
1247
|
+
const node = stack.pop();
|
|
1248
|
+
const snapshot = structureSnapshot(state, node);
|
|
1249
|
+
if (!snapshot || visited === snapshotTextBudget) return void 0;
|
|
1250
|
+
if (snapshot.isTextAt(node)) {
|
|
1251
|
+
text += snapshot.dataOf(node) ?? largeText(state, snapshot, node);
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
for (let index = snapshot.childCount(node) - 1; index >= 0; index--) stack.push(snapshot.childAt(node, index));
|
|
1255
|
+
}
|
|
1256
|
+
return text;
|
|
1257
|
+
}
|
|
1258
|
+
function largeText(state, snapshot, local) {
|
|
1259
|
+
let text = snapshot.largeTexts.get(local);
|
|
1260
|
+
if (text === void 0) snapshot.largeTexts.set(local, text = state.raw.text([local]));
|
|
1261
|
+
return text;
|
|
1262
|
+
}
|
|
1196
1263
|
function attributeAt(state, local, name) {
|
|
1197
1264
|
const snapshot = plainSnapshot(state, local);
|
|
1198
1265
|
if (snapshot) return snapshot.attributeValue(local, name);
|
|
@@ -1201,15 +1268,18 @@ function attributeAt(state, local, name) {
|
|
|
1201
1268
|
return typeof value === "string" ? value : void 0;
|
|
1202
1269
|
}
|
|
1203
1270
|
function invalidate(state) {
|
|
1271
|
+
takePreparedSnapshot(state, false);
|
|
1204
1272
|
state.generation++;
|
|
1205
1273
|
state.records = [];
|
|
1206
1274
|
state.bulk = 0;
|
|
1207
1275
|
state.stale.clear();
|
|
1208
1276
|
}
|
|
1209
1277
|
function invalidateNodes(state, locals) {
|
|
1278
|
+
takePreparedSnapshot(state, false);
|
|
1210
1279
|
const isSnapshot = state.bulk instanceof NodeSnapshot;
|
|
1280
|
+
const { records } = state;
|
|
1211
1281
|
for (const local of locals) {
|
|
1212
|
-
|
|
1282
|
+
if (records[local] !== void 0) records[local] = void 0;
|
|
1213
1283
|
if (isSnapshot) state.stale.add(local);
|
|
1214
1284
|
}
|
|
1215
1285
|
}
|
|
@@ -1444,6 +1514,11 @@ var RoutedDocument = class {
|
|
|
1444
1514
|
return this.globals(group.state, found);
|
|
1445
1515
|
}
|
|
1446
1516
|
text(ids) {
|
|
1517
|
+
if (ids.length === 1) {
|
|
1518
|
+
const state = this.owner(ids[0]);
|
|
1519
|
+
const text = textFromSnapshot(state, ids[0] - state.base);
|
|
1520
|
+
if (text !== void 0) return text;
|
|
1521
|
+
}
|
|
1447
1522
|
return this.groups(ids).map((group) => group.state.raw.text(group.locals)).join("");
|
|
1448
1523
|
}
|
|
1449
1524
|
innerHtml(id) {
|
|
@@ -1528,9 +1603,12 @@ var RoutedDocument = class {
|
|
|
1528
1603
|
return this.globals(state, inserted);
|
|
1529
1604
|
}
|
|
1530
1605
|
const result2 = [];
|
|
1606
|
+
const isBesideTarget = args.position === "before" || args.position === "after";
|
|
1531
1607
|
for (let index = 0; index < targets.length; index++) {
|
|
1532
1608
|
const target = this.owner(targets[index]);
|
|
1533
1609
|
const targetLocal = targets[index] - target.base;
|
|
1610
|
+
const record = recordAt(target, targetLocal);
|
|
1611
|
+
if (!record || !parentTypes.has(record.type) || isBesideTarget && record.parent == null) continue;
|
|
1534
1612
|
const local = this.moveInto(target, nodes, index + 1 < targets.length);
|
|
1535
1613
|
const inserted = this.call(target, command, { ...args, targetIds: [targetLocal], nodeIds: local });
|
|
1536
1614
|
result2.push(...this.globals(target, inserted));
|
|
@@ -1753,6 +1831,8 @@ function traverseRecords(document, ids, kind) {
|
|
|
1753
1831
|
for (const id of ids) {
|
|
1754
1832
|
const state = stateIn(document, id);
|
|
1755
1833
|
const { base } = state;
|
|
1834
|
+
const snapshot = state.bulk instanceof NodeSnapshot ? state.bulk : void 0;
|
|
1835
|
+
if (snapshot?.isPresent(id - base) && traverseSnapshot(snapshot, base, id - base, kind, result)) continue;
|
|
1756
1836
|
const node = recordAt(state, id - base);
|
|
1757
1837
|
if (!node) continue;
|
|
1758
1838
|
const isElement2 = (local) => isElementType(recordAt(state, local)?.type);
|
|
@@ -1793,6 +1873,60 @@ function traverseRecords(document, ids, kind) {
|
|
|
1793
1873
|
}
|
|
1794
1874
|
return result;
|
|
1795
1875
|
}
|
|
1876
|
+
function traverseSnapshot(snapshot, base, local, kind, result) {
|
|
1877
|
+
const pushChildren2 = (parent, isElementsOnly, except) => {
|
|
1878
|
+
const count = snapshot.childCount(parent);
|
|
1879
|
+
for (let index = 0; index < count; index++) {
|
|
1880
|
+
const child = snapshot.childAt(parent, index);
|
|
1881
|
+
if (child !== except && (!isElementsOnly || snapshot.isElementAt(child))) result.push(base + child);
|
|
1882
|
+
}
|
|
1883
|
+
};
|
|
1884
|
+
switch (kind) {
|
|
1885
|
+
case "children":
|
|
1886
|
+
pushChildren2(local, true, -1);
|
|
1887
|
+
return true;
|
|
1888
|
+
case "contents":
|
|
1889
|
+
pushChildren2(local, false, -1);
|
|
1890
|
+
return true;
|
|
1891
|
+
case "siblings": {
|
|
1892
|
+
const parent = snapshot.linkOf(local, 1);
|
|
1893
|
+
if (parent !== null && snapshot.isPresent(parent)) pushChildren2(parent, true, local);
|
|
1894
|
+
return true;
|
|
1895
|
+
}
|
|
1896
|
+
case "parent": {
|
|
1897
|
+
const parent = snapshot.linkOf(local, 1);
|
|
1898
|
+
if (parent !== null && snapshot.isPresent(parent) && snapshot.isElementAt(parent)) result.push(base + parent);
|
|
1899
|
+
return true;
|
|
1900
|
+
}
|
|
1901
|
+
case "parents":
|
|
1902
|
+
case "ancestors": {
|
|
1903
|
+
let parent = snapshot.linkOf(local, 1);
|
|
1904
|
+
for (let steps = 0; parent !== null && steps < snapshot.size && snapshot.isPresent(parent) && !snapshot.isRootAt(parent); steps++) {
|
|
1905
|
+
if (snapshot.isElementAt(parent)) result.push(base + parent);
|
|
1906
|
+
parent = snapshot.linkOf(parent, 1);
|
|
1907
|
+
}
|
|
1908
|
+
return true;
|
|
1909
|
+
}
|
|
1910
|
+
case "next":
|
|
1911
|
+
case "prev":
|
|
1912
|
+
case "nextAll":
|
|
1913
|
+
case "prevAll": {
|
|
1914
|
+
const offset = kind === "next" || kind === "nextAll" ? 3 : 2;
|
|
1915
|
+
const isSingle = kind === "next" || kind === "prev";
|
|
1916
|
+
let sibling = snapshot.linkOf(local, offset);
|
|
1917
|
+
for (let steps = 0; sibling !== null && steps < snapshot.size && snapshot.isPresent(sibling); steps++) {
|
|
1918
|
+
if (snapshot.isElementAt(sibling)) {
|
|
1919
|
+
result.push(base + sibling);
|
|
1920
|
+
if (isSingle) break;
|
|
1921
|
+
}
|
|
1922
|
+
sibling = snapshot.linkOf(sibling, offset);
|
|
1923
|
+
}
|
|
1924
|
+
return true;
|
|
1925
|
+
}
|
|
1926
|
+
default:
|
|
1927
|
+
return false;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1796
1930
|
function viewAt(state, local) {
|
|
1797
1931
|
const existing = state.views[local] ?? cachedView(state, local);
|
|
1798
1932
|
if (existing) return existing;
|
|
@@ -1801,9 +1935,9 @@ function viewAt(state, local) {
|
|
|
1801
1935
|
state.adapterNodes[local] = void 0;
|
|
1802
1936
|
return adoptObject(state, local, parsed);
|
|
1803
1937
|
}
|
|
1804
|
-
const snapshot =
|
|
1938
|
+
const snapshot = structureSnapshot(state, local);
|
|
1805
1939
|
let constructor;
|
|
1806
|
-
if (snapshot) constructor = viewConstructor(snapshot.typeOf(local), false);
|
|
1940
|
+
if (snapshot && !snapshot.hasExtraFields(local)) constructor = viewConstructor(snapshot.typeOf(local), false);
|
|
1807
1941
|
else {
|
|
1808
1942
|
const record = recordAt(state, local);
|
|
1809
1943
|
if (!record) return void 0;
|
|
@@ -2002,14 +2136,17 @@ function fillChildren(view) {
|
|
|
2002
2136
|
if (!target) return;
|
|
2003
2137
|
const state = view[VIEW_STATE];
|
|
2004
2138
|
const local = view[VIEW_LOCAL];
|
|
2005
|
-
const snapshot =
|
|
2139
|
+
const snapshot = structureSnapshot(state, local);
|
|
2006
2140
|
if (snapshot && state.stale.size === 0) {
|
|
2007
2141
|
fillFromSnapshot(state, snapshot, local, target);
|
|
2008
2142
|
return;
|
|
2009
2143
|
}
|
|
2010
2144
|
const locals = viewRecord(view).children ?? [];
|
|
2011
|
-
target.length = locals.length;
|
|
2012
2145
|
for (let index = 0; index < locals.length; index++) target[index] = viewAt(state, locals[index]);
|
|
2146
|
+
truncate(target, locals.length);
|
|
2147
|
+
}
|
|
2148
|
+
function truncate(target, length) {
|
|
2149
|
+
if (target.length !== length) target.length = length;
|
|
2013
2150
|
}
|
|
2014
2151
|
function fillFromSnapshot(state, snapshot, local, target) {
|
|
2015
2152
|
const count = snapshot.childCount(local);
|
|
@@ -2018,17 +2155,17 @@ function fillFromSnapshot(state, snapshot, local, target) {
|
|
|
2018
2155
|
const views = state.views;
|
|
2019
2156
|
const isStrong = !state.adapterNodes;
|
|
2020
2157
|
const constructors = snapshotConstructors(snapshot);
|
|
2021
|
-
target.length = count;
|
|
2022
2158
|
for (let index = 0; index < count; index++) {
|
|
2023
2159
|
const child = childIds2[first + index];
|
|
2024
2160
|
let node = views[child] ?? (state.weakViews.size ? cachedView(state, child) : void 0);
|
|
2025
2161
|
if (node === void 0) {
|
|
2026
|
-
const constructor = isStrong && child < state.baseline && snapshot.
|
|
2162
|
+
const constructor = isStrong && child < state.baseline && snapshot.isPresent(child) && !snapshot.hasExtraFields(child) ? constructors(snapshot.typeReference(child)) : void 0;
|
|
2027
2163
|
if (constructor) views[child] = node = new constructor(state, child);
|
|
2028
2164
|
else node = viewAt(state, child);
|
|
2029
2165
|
}
|
|
2030
2166
|
target[index] = node;
|
|
2031
2167
|
}
|
|
2168
|
+
truncate(target, count);
|
|
2032
2169
|
}
|
|
2033
2170
|
function snapshotConstructors(snapshot) {
|
|
2034
2171
|
let lookup = snapshot.viewConstructors;
|
|
@@ -2051,7 +2188,7 @@ var snapshotField = (field) => ({
|
|
|
2051
2188
|
get() {
|
|
2052
2189
|
const state = this[VIEW_STATE];
|
|
2053
2190
|
const local = this[VIEW_LOCAL];
|
|
2054
|
-
const snapshot = plainSnapshot(state, local);
|
|
2191
|
+
const snapshot = field === "data" ? plainSnapshot(state, local) : structureSnapshot(state, local);
|
|
2055
2192
|
if (snapshot) return field === "type" ? snapshot.typeOf(local) : field === "name" ? snapshot.nameOf(local) : snapshot.dataOf(local);
|
|
2056
2193
|
return viewRecord(this)[field];
|
|
2057
2194
|
},
|
|
@@ -2064,7 +2201,7 @@ var pointerField = (field) => ({
|
|
|
2064
2201
|
get() {
|
|
2065
2202
|
const state = this[VIEW_STATE];
|
|
2066
2203
|
const local = this[VIEW_LOCAL];
|
|
2067
|
-
const snapshot =
|
|
2204
|
+
const snapshot = structureSnapshot(state, local);
|
|
2068
2205
|
return linkedView(this, snapshot ? snapshot.linkOf(local, linkOffsets[field]) : viewRecord(this)[field]);
|
|
2069
2206
|
},
|
|
2070
2207
|
set(value) {
|
|
@@ -2917,11 +3054,11 @@ function selectSimpleWithin(document, contexts, selector, options) {
|
|
|
2917
3054
|
}
|
|
2918
3055
|
var isElementType2 = (type) => type === "tag" || type === "script" || type === "style";
|
|
2919
3056
|
function typeAt(state, local) {
|
|
2920
|
-
const snapshot =
|
|
3057
|
+
const snapshot = structureSnapshot(state, local);
|
|
2921
3058
|
return snapshot ? snapshot.typeOf(local) : recordAt(state, local)?.type;
|
|
2922
3059
|
}
|
|
2923
3060
|
function pushChildren(state, local, stack) {
|
|
2924
|
-
const snapshot =
|
|
3061
|
+
const snapshot = structureSnapshot(state, local);
|
|
2925
3062
|
if (snapshot) {
|
|
2926
3063
|
for (let index = snapshot.childCount(local) - 1; index >= 0; index--) stack.push(snapshot.childAt(local, index));
|
|
2927
3064
|
return;
|
|
@@ -2937,7 +3074,7 @@ function sameMatchOptions(documentOptions, isXml, isLowerCaseTags, isLowerCaseAt
|
|
|
2937
3074
|
return isDocumentXml === isXml && (documentOptions.lowerCaseTags ?? !isDocumentXml) === isLowerCaseTags && (documentOptions.lowerCaseAttributeNames ?? !isDocumentXml) === isLowerCaseAttributes;
|
|
2938
3075
|
}
|
|
2939
3076
|
function matchesCompound(state, local, compound, isLowerCaseTags, isLowerCaseAttributes) {
|
|
2940
|
-
const snapshot =
|
|
3077
|
+
const snapshot = structureSnapshot(state, local);
|
|
2941
3078
|
const record = snapshot ? void 0 : recordAt(state, local);
|
|
2942
3079
|
if (!snapshot && !record) return false;
|
|
2943
3080
|
if (!isElementType2(snapshot ? snapshot.typeOf(local) : record.type)) return false;
|
|
@@ -3517,26 +3654,25 @@ var Cheerio = class {
|
|
|
3517
3654
|
}
|
|
3518
3655
|
/** @internal */
|
|
3519
3656
|
_insert(position, content) {
|
|
3657
|
+
if (typeof content[0] !== "function") {
|
|
3658
|
+
const ids = this.ids;
|
|
3659
|
+
if (ids.length) this.op("insert", { targetIds: ids, nodeIds: this._domIds(content), position });
|
|
3660
|
+
return this;
|
|
3661
|
+
}
|
|
3520
3662
|
const targets = this.ids.filter((id) => ["root", "tag", "script", "style", "cdata"].includes(nodeRecord(this[DOCUMENT], id).type));
|
|
3521
3663
|
if (!targets.length)
|
|
3522
3664
|
return this;
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
});
|
|
3535
|
-
let nodes = this._domIds(content);
|
|
3536
|
-
if (targets[targets.length - 1] !== this.ids[this.ids.length - 1])
|
|
3537
|
-
nodes = this.op("clone", { ids: nodes, deep: true });
|
|
3538
|
-
this.op("insert", { targetIds: targets, nodeIds: nodes, position });
|
|
3539
|
-
return this;
|
|
3665
|
+
return this.each((index, node) => {
|
|
3666
|
+
if (!targets.includes(this.ids[index]))
|
|
3667
|
+
return;
|
|
3668
|
+
if ((position === "before" || position === "after") && nodeRecord(this[DOCUMENT], this.ids[index]).parent == null)
|
|
3669
|
+
return;
|
|
3670
|
+
const value = content[0].call(node, index, this[DOCUMENT].innerHtml(this.ids[index]));
|
|
3671
|
+
let nodes = this._domIds(value);
|
|
3672
|
+
if (index < this.length - 1)
|
|
3673
|
+
nodes = this.op("clone", { ids: nodes, deep: true });
|
|
3674
|
+
this.op("insert", { targetIds: [this.ids[index]], nodeIds: nodes, position });
|
|
3675
|
+
});
|
|
3540
3676
|
}
|
|
3541
3677
|
append(...content) {
|
|
3542
3678
|
return this._insert("append", content);
|
|
@@ -3716,28 +3852,30 @@ function plainKeys(map) {
|
|
|
3716
3852
|
return !import_node_util2.types.isProxy(map) && (Object.getPrototypeOf(map) === Object.prototype || Object.getPrototypeOf(map) === null) ? Object.keys(map) : void 0;
|
|
3717
3853
|
}
|
|
3718
3854
|
function nativePrefix(scope, map, keys, key) {
|
|
3719
|
-
if (!keys || scope
|
|
3855
|
+
if (!keys || !hasNativeExtraction(scope)) return void 0;
|
|
3856
|
+
const prefix = prefixPlan(map, keys, key, scope.options);
|
|
3857
|
+
if (!prefix) return void 0;
|
|
3858
|
+
return { keys: prefix.names, values: runPlan(scope, prefix.plan) };
|
|
3859
|
+
}
|
|
3860
|
+
function prefixPlan(map, keys, key, options) {
|
|
3720
3861
|
const prefix = /* @__PURE__ */ Object.create(null);
|
|
3721
|
-
let count = 0;
|
|
3722
3862
|
let plan;
|
|
3723
|
-
|
|
3724
|
-
for (let position = index; position < keys.length; position++) {
|
|
3863
|
+
for (let position = keys.indexOf(key); position < keys.length; position++) {
|
|
3725
3864
|
const name = keys[position];
|
|
3726
3865
|
const slot = Object.getOwnPropertyDescriptor(map, name);
|
|
3727
3866
|
if (!slot || !slot.enumerable || !("value" in slot)) break;
|
|
3728
3867
|
Object.defineProperty(prefix, name, { value: slot.value, enumerable: true, configurable: true });
|
|
3729
|
-
const compiled2 = compileExtractPlan(prefix,
|
|
3868
|
+
const compiled2 = compileExtractPlan(prefix, options);
|
|
3730
3869
|
if (!compiled2) {
|
|
3731
3870
|
delete prefix[name];
|
|
3732
3871
|
break;
|
|
3733
3872
|
}
|
|
3734
3873
|
plan = compiled2;
|
|
3735
|
-
count++;
|
|
3736
3874
|
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
return
|
|
3875
|
+
return plan ? { names: Object.keys(prefix), plan } : void 0;
|
|
3876
|
+
}
|
|
3877
|
+
function hasNativeExtraction(scope) {
|
|
3878
|
+
return scope._make === nativeExtractionMethods.make && scope._findBySelector === nativeExtractionMethods.find && scope.prop === nativeExtractionMethods.prop && scope.extract === nativeExtractionMethods.extract;
|
|
3741
3879
|
}
|
|
3742
3880
|
function extract(map) {
|
|
3743
3881
|
const result = {};
|
|
@@ -3782,8 +3920,17 @@ function extract(map) {
|
|
|
3782
3920
|
return result;
|
|
3783
3921
|
}
|
|
3784
3922
|
function nativeRows(scope, key, all, selector, map) {
|
|
3923
|
+
if (!hasNativeExtraction(scope)) return void 0;
|
|
3924
|
+
const planned = rowsPlan(key, all, selector, map, scope.options);
|
|
3925
|
+
if (!planned) return void 0;
|
|
3926
|
+
const writes = writeCount();
|
|
3927
|
+
const extracted = runPlan(scope, planned.plan)[key];
|
|
3928
|
+
const rows = all ? extracted : extracted === void 0 ? [] : [extracted];
|
|
3929
|
+
return Array.isArray(rows) ? { keys: planned.nativeKeys, rows, writes } : void 0;
|
|
3930
|
+
}
|
|
3931
|
+
function rowsPlan(key, all, selector, map, options) {
|
|
3785
3932
|
const keys = plainKeys(map);
|
|
3786
|
-
if (!keys
|
|
3933
|
+
if (!keys) return void 0;
|
|
3787
3934
|
const subset = /* @__PURE__ */ Object.create(null);
|
|
3788
3935
|
const nativeKeys = /* @__PURE__ */ new Set();
|
|
3789
3936
|
for (const name of keys) {
|
|
@@ -3791,21 +3938,81 @@ function nativeRows(scope, key, all, selector, map) {
|
|
|
3791
3938
|
if (!slot || !slot.enumerable || !("value" in slot)) continue;
|
|
3792
3939
|
const single = /* @__PURE__ */ Object.create(null);
|
|
3793
3940
|
Object.defineProperty(single, name, { value: slot.value, enumerable: true, configurable: true });
|
|
3794
|
-
if (!compileExtractPlan(single,
|
|
3941
|
+
if (!compileExtractPlan(single, options)) continue;
|
|
3795
3942
|
Object.defineProperty(subset, name, { value: slot.value, enumerable: true, configurable: true });
|
|
3796
3943
|
nativeKeys.add(name);
|
|
3797
3944
|
}
|
|
3798
3945
|
if (!nativeKeys.size || nativeKeys.size === keys.length) return void 0;
|
|
3799
3946
|
const outer = /* @__PURE__ */ Object.create(null);
|
|
3800
3947
|
Object.defineProperty(outer, key, { value: all ? [{ selector, value: subset }] : { selector, value: subset }, enumerable: true, configurable: true });
|
|
3801
|
-
const plan = compileExtractPlan(outer,
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3948
|
+
const plan = compileExtractPlan(outer, options);
|
|
3949
|
+
return plan ? { nativeKeys, plan } : void 0;
|
|
3950
|
+
}
|
|
3951
|
+
function rootExtractPlans(map, options) {
|
|
3952
|
+
if (!isPlainData(map, 0) || hasInheritedEntryFields()) return [];
|
|
3953
|
+
try {
|
|
3954
|
+
return collectRootExtractPlans(map, options);
|
|
3955
|
+
} catch {
|
|
3956
|
+
return [];
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
function isPlainData(value, depth) {
|
|
3960
|
+
if (typeof value !== "object" || value === null) return true;
|
|
3961
|
+
if (depth > 32 || import_node_util2.types.isProxy(value)) return false;
|
|
3962
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3963
|
+
if (prototype !== Object.prototype && prototype !== Array.prototype && prototype !== null) return false;
|
|
3964
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
3965
|
+
const slot = Object.getOwnPropertyDescriptor(value, key);
|
|
3966
|
+
if (!("value" in slot) || !isPlainData(slot.value, depth + 1)) return false;
|
|
3967
|
+
}
|
|
3968
|
+
return true;
|
|
3969
|
+
}
|
|
3970
|
+
function hasInheritedEntryFields() {
|
|
3971
|
+
return "selector" in Object.prototype || "value" in Object.prototype || "0" in Array.prototype;
|
|
3972
|
+
}
|
|
3973
|
+
function collectRootExtractPlans(map, options) {
|
|
3974
|
+
const plans = [];
|
|
3975
|
+
const keys = plainKeys(map);
|
|
3976
|
+
const processed = /* @__PURE__ */ new Set();
|
|
3977
|
+
for (const key in map) {
|
|
3978
|
+
if (processed.has(key)) continue;
|
|
3979
|
+
const prefix = keys ? prefixPlan(map, keys, key, options) : void 0;
|
|
3980
|
+
if (prefix) {
|
|
3981
|
+
for (const name of prefix.names) processed.add(name);
|
|
3982
|
+
plans.push(prefix.plan);
|
|
3983
|
+
continue;
|
|
3984
|
+
}
|
|
3985
|
+
const entry = map[key];
|
|
3986
|
+
const all = Array.isArray(entry);
|
|
3987
|
+
const descriptor = all ? entry[0] : entry;
|
|
3988
|
+
const value = typeof descriptor === "string" ? "textContent" : descriptor.value ?? "textContent";
|
|
3989
|
+
if (typeof value !== "object" || value === null) continue;
|
|
3990
|
+
const planned = rowsPlan(key, all, typeof descriptor === "string" ? descriptor : descriptor.selector, value, options);
|
|
3991
|
+
if (planned) plans.push(planned.plan);
|
|
3992
|
+
}
|
|
3993
|
+
return plans.filter((plan) => !JSON.stringify(plan).includes("innerHTML"));
|
|
3994
|
+
}
|
|
3995
|
+
var preparedPlans = /* @__PURE__ */ new WeakMap();
|
|
3996
|
+
function prepareExtractPlans(document, plans, results) {
|
|
3997
|
+
if (!results) return;
|
|
3998
|
+
const prepared = /* @__PURE__ */ new Map();
|
|
3999
|
+
for (let index = 0; index < plans.length; index++) {
|
|
4000
|
+
const result = results[index];
|
|
4001
|
+
if (typeof result === "string") prepared.set(JSON.stringify(plans[index]), decodeJson(result));
|
|
4002
|
+
}
|
|
4003
|
+
preparedPlans.set(document, { writes: writeCount(), results: prepared });
|
|
4004
|
+
}
|
|
4005
|
+
function releaseExtractPlans(document) {
|
|
4006
|
+
preparedPlans.delete(document);
|
|
4007
|
+
}
|
|
4008
|
+
function runPlan(scope, plan) {
|
|
4009
|
+
const document = scope[DOCUMENT];
|
|
4010
|
+
const prepared = preparedPlans.get(document);
|
|
4011
|
+
const isRoot = prepared !== void 0 && prepared.writes === writeCount() && scope.ids.length === 1 && scope.ids[0] === document.rootId();
|
|
4012
|
+
const result = isRoot ? prepared.results.get(JSON.stringify(plan)) : void 0;
|
|
4013
|
+
const values = result !== void 0 ? JSON.parse(result) : scope.op("extractPlan", { ids: scope.ids, plan });
|
|
3805
4014
|
hydrateExtractResult(values, plan.entries);
|
|
3806
|
-
|
|
3807
|
-
const rows = all ? extracted : extracted === void 0 ? [] : [extracted];
|
|
3808
|
-
return Array.isArray(rows) ? { keys: nativeKeys, rows, writes } : void 0;
|
|
4015
|
+
return values;
|
|
3809
4016
|
}
|
|
3810
4017
|
function completeRow(scope, map, rows, index) {
|
|
3811
4018
|
const row = {};
|
|
@@ -4476,7 +4683,9 @@ var dom = {
|
|
|
4476
4683
|
isCDATA,
|
|
4477
4684
|
hasChildren
|
|
4478
4685
|
};
|
|
4686
|
+
var defaultOptions = { _useHtmlParser2: false };
|
|
4479
4687
|
function flattenOptions(options, base) {
|
|
4688
|
+
if (!options) return base ?? defaultOptions;
|
|
4480
4689
|
const result = { _useHtmlParser2: false, ...base, ...options };
|
|
4481
4690
|
if (options?.xml) {
|
|
4482
4691
|
result._useHtmlParser2 = true;
|
|
@@ -4636,13 +4845,23 @@ function parallelOptions(options) {
|
|
|
4636
4845
|
return { options: flattenOptions(opts), threads };
|
|
4637
4846
|
}
|
|
4638
4847
|
async function loadAll(content, options, isDocument2 = true) {
|
|
4848
|
+
return loadAllWithPlans(content, options, isDocument2);
|
|
4849
|
+
}
|
|
4850
|
+
async function loadAllWithPlans(content, options, isDocument2, plans) {
|
|
4639
4851
|
const { options: opts, threads } = parallelOptions(options);
|
|
4640
4852
|
if (!Array.isArray(content) || content.some((item) => typeof item !== "string")) throw new TypeError("loadAll expects an array of HTML strings");
|
|
4641
4853
|
if (!content.length) return [];
|
|
4642
4854
|
const binding = requireNative();
|
|
4643
4855
|
if (!binding.parseManyAsync || hasParserHooks(opts)) return Promise.all(content.map((html) => loadAsync(html, opts, isDocument2)));
|
|
4644
|
-
const documents = await binding.parseManyAsync([...content], isDocument2, threads, JSON.stringify(opts));
|
|
4645
|
-
return documents.map((document) =>
|
|
4856
|
+
const documents = await binding.parseManyAsync([...content], isDocument2, threads, JSON.stringify(opts), plans && JSON.stringify(plans));
|
|
4857
|
+
return documents.map((document) => {
|
|
4858
|
+
const routed = routeDocument(document, opts);
|
|
4859
|
+
if (plans) {
|
|
4860
|
+
usePreparedSnapshot(routed);
|
|
4861
|
+
prepareExtractPlans(routed, plans, document.takePreparedPlans?.());
|
|
4862
|
+
}
|
|
4863
|
+
return createAPI(routed, opts);
|
|
4864
|
+
});
|
|
4646
4865
|
}
|
|
4647
4866
|
function nativeQueries(map, options) {
|
|
4648
4867
|
const queries = [];
|
|
@@ -4678,11 +4897,16 @@ async function extractAll(content, map, options) {
|
|
|
4678
4897
|
}
|
|
4679
4898
|
return results2;
|
|
4680
4899
|
}
|
|
4681
|
-
const documents = await
|
|
4900
|
+
const documents = await loadAllWithPlans(content, { ...opts, threads }, true, hasParserHooks(opts) ? void 0 : rootExtractPlans(map, opts));
|
|
4682
4901
|
const results = [];
|
|
4683
4902
|
let yieldedAt = performance.now();
|
|
4684
4903
|
for (const document of documents) {
|
|
4685
|
-
|
|
4904
|
+
const root = document.root();
|
|
4905
|
+
try {
|
|
4906
|
+
results.push((await extractCooperatively(root, map)).value);
|
|
4907
|
+
} finally {
|
|
4908
|
+
releaseExtractPlans(root[DOCUMENT]);
|
|
4909
|
+
}
|
|
4686
4910
|
if (performance.now() - yieldedAt >= 4) {
|
|
4687
4911
|
await (0, import_promises.setImmediate)();
|
|
4688
4912
|
yieldedAt = performance.now();
|