@poe-platform/safe-fs 0.1.813 → 0.1.814

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.
@@ -54,7 +54,7 @@ export interface XmlStepLimits extends XmlLimits {
54
54
  readonly events?: (event: XmlStreamEvent) => void;
55
55
  }
56
56
  export interface XmlSourceLimits extends XmlStepLimits {
57
- /** Emit text and CDATA in bounded fragments, marking continuations of the same logical
57
+ /** Emit content bodies in bounded fragments, marking continuations of the same logical
58
58
  * node. Requires retainTree: false; consumers must preserve fragment identity. */
59
59
  readonly fragmentContent?: boolean;
60
60
  /** Store active parser frames through host-serviced requests. Requires retainTree: false. */
@@ -326,6 +326,33 @@ export function* parseXmlSourceSteps(length, limits = {}) {
326
326
  const [prefix, localName] = qualifiedNameSync(name, qualifiedNames);
327
327
  return [name, prefix, localName];
328
328
  };
329
+ const rawContent = function* (kind, start, end, parent, target = "") {
330
+ if (end - start > maxTextLength - textLength)
331
+ throw new XmlLimitError("maxTextLength", "XML text limit exceeded");
332
+ textLength += end - start;
333
+ admitContent();
334
+ let cursor = start, continuation = false;
335
+ do {
336
+ let finish = limits.fragmentContent ? Math.min(end, cursor + 512) : end;
337
+ if (finish < end) {
338
+ const last = yield* source.charCodeAt(finish - 1);
339
+ if (last >= 0xd800 && last <= 0xdbff)
340
+ finish--;
341
+ }
342
+ const text = yield* source.slice(cursor, finish);
343
+ const content = kind === "processing-instruction" ? { kind, target, text } : { kind, text };
344
+ if (kind === "cdata" && retainTree)
345
+ parent.element.text += text;
346
+ if (retain)
347
+ (parent?.content ?? (root ? epilog : prolog)).push(content);
348
+ limits.events?.({ type: "content", content, parent: parent?.element,
349
+ ...(continuation ? { continuation: true } : {}) });
350
+ if (limits.fragmentContent)
351
+ yield Math.max(1, text.length);
352
+ continuation = true;
353
+ cursor = finish;
354
+ } while (cursor < end);
355
+ };
329
356
  while (yield* source.has(offset)) {
330
357
  pendingWork += 1;
331
358
  if (pendingWork >= 512) {
@@ -431,17 +458,10 @@ export function* parseXmlSourceSteps(length, limits = {}) {
431
458
  }
432
459
  else if ((yield* source.startsWith("<!--", offset))) {
433
460
  const end = yield* find(source, "-->", offset + 4);
434
- const text = end < 0 ? "" : yield* source.slice(offset + 4, end);
435
- if (end < 0 || (yield* find(text, "--", 0)) >= 0 || text.endsWith("-")) {
461
+ if (end < 0 || (yield* source.indexOf("--", offset + 4, end)) >= 0
462
+ || (end > offset + 4 && (yield* source.charCodeAt(end - 1)) === 45))
436
463
  invalid("malformed comment");
437
- }
438
- const parent = (yield* stack.peek());
439
- admitText(text);
440
- admitContent();
441
- if (retain) {
442
- (parent?.content ?? (root ? epilog : prolog)).push({ kind: "comment", text });
443
- }
444
- limits.events?.({ type: "content", content: { kind: "comment", text }, parent: parent?.element });
464
+ yield* rawContent("comment", offset + 4, end, yield* stack.peek());
445
465
  offset = end + 3;
446
466
  }
447
467
  else if ((yield* source.startsWith("<![CDATA[", offset))) {
@@ -450,32 +470,7 @@ export function* parseXmlSourceSteps(length, limits = {}) {
450
470
  const end = yield* find(source, "]]>", offset + 9);
451
471
  if (end < 0)
452
472
  invalid("unterminated CDATA");
453
- if (end - offset - 9 > maxTextLength - textLength)
454
- throw new XmlLimitError("maxTextLength", "XML text limit exceeded");
455
- const parent = (yield* stack.peek());
456
- admitContent();
457
- let cursor = offset + 9, continuation = false;
458
- do {
459
- let finish = limits.fragmentContent ? Math.min(end, cursor + 512) : end;
460
- if (finish < end) {
461
- const last = yield* source.charCodeAt(finish - 1);
462
- if (last >= 0xd800 && last <= 0xdbff)
463
- finish--;
464
- }
465
- const text = yield* source.slice(cursor, finish);
466
- admitText(text);
467
- if (retainTree)
468
- parent.element.text += text;
469
- if (retain)
470
- parent.content.push({ kind: "cdata", text });
471
- limits.events?.({ type: "content", content: { kind: "cdata", text }, parent: parent.element,
472
- ...(continuation ? { continuation: true } : {}) });
473
- // Let external consumers persist each fragment before producing another.
474
- if (limits.fragmentContent)
475
- yield Math.max(1, text.length);
476
- continuation = true;
477
- cursor = finish;
478
- } while (cursor < end);
473
+ yield* rawContent("cdata", offset + 9, end, yield* stack.peek());
479
474
  offset = end + 3;
480
475
  }
481
476
  else if ((yield* source.startsWith("<?", offset))) {
@@ -489,34 +484,31 @@ export function* parseXmlSourceSteps(length, limits = {}) {
489
484
  const end = yield* find(source, "?>", offset);
490
485
  if (end < 0)
491
486
  invalid("unterminated processing instruction");
492
- const content = (yield* source.slice(offset, end));
493
487
  if (target.length === 3 && target.toLowerCase() === "xml") {
488
+ const content = yield* source.slice(offset, end);
494
489
  if (start !== 0 || target !== "xml"
495
- || !(yield* validDeclaration(content, limits.expectedEncoding))) {
490
+ || !(yield* validDeclaration(content, limits.expectedEncoding)))
496
491
  invalid("unsupported XML declaration");
497
- }
498
492
  if (retainContent)
499
- declaration = (yield* source.slice(start, end + 2));
493
+ declaration = yield* source.slice(start, end + 2);
500
494
  }
501
- else if (content && !" \t\n\r".includes(content[0]))
502
- invalid("invalid processing instruction");
503
- if (!(target.length === 3 && target.toLowerCase() === "xml")) {
504
- const parent = (yield* stack.peek());
505
- let wsStart = 0;
506
- while (wsStart < content.length && " \t\n\r".includes(content[wsStart]))
507
- wsStart++;
508
- pendingWork += wsStart;
495
+ else {
496
+ if (offset < end && !" \t\n\r".includes(yield* source.slice(offset, offset + 1)))
497
+ invalid("invalid processing instruction");
498
+ let body = offset;
499
+ while (body < end && " \t\n\r".includes(yield* source.slice(body, body + 1))) {
500
+ body++;
501
+ pendingWork++;
502
+ if (pendingWork >= 512) {
503
+ yield 512;
504
+ pendingWork -= 512;
505
+ }
506
+ }
509
507
  while (pendingWork >= 512) {
510
508
  yield 512;
511
509
  pendingWork -= 512;
512
510
  }
513
- const text = content.slice(wsStart);
514
- admitText(text);
515
- admitContent();
516
- if (retain) {
517
- (parent?.content ?? (root ? epilog : prolog)).push({ kind: "processing-instruction", target, text });
518
- }
519
- limits.events?.({ type: "content", content: { kind: "processing-instruction", target, text }, parent: parent?.element });
511
+ yield* rawContent("processing-instruction", body, end, yield* stack.peek(), target);
520
512
  }
521
513
  offset = end + 2;
522
514
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poe-platform/safe-fs",
3
- "version": "0.1.813",
3
+ "version": "0.1.814",
4
4
  "description": "Composable filesystem with a portable core and explicit Node adapters",
5
5
  "type": "module",
6
6
  "license": "MIT",