@mnemonik/shared 7.152.0 → 7.153.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,8 @@ export type VueTemplateNode = TemplateRoot | TemplateRoot['children'][number];
7
7
  type ParsedVueSource = {
8
8
  descriptor: SFCDescriptor;
9
9
  nodeTypes: typeof import('@vue/compiler-core').NodeTypes;
10
+ /** Set on the sanitation path only; the template walk throws past it. */
11
+ templateNodeLimit?: number;
10
12
  };
11
13
  export declare function parseVueSource(source: string, forSanitation?: boolean): Promise<ParsedVueSource | {
12
14
  reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"vueSource.d.ts","sourceRoot":"","sources":["../src/vueSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,sDAAsD,CAAC;AACvF,KAAK,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,sFAAsF;AACtF,KAAK,eAAe,GAAG;IACrB,UAAU,EAAE,aAAa,CAAC;IAC1B,SAAS,EAAE,cAAc,oBAAoB,EAAE,SAAS,CAAC;CAC1D,CAAC;AACF,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,UAAQ,GACpB,OAAO,CAAC,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiC/C;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GACtD,IAAI,CAqBN"}
1
+ {"version":3,"file":"vueSource.d.ts","sourceRoot":"","sources":["../src/vueSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIvD,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,sDAAsD,CAAC;AACvF,KAAK,YAAY,GAAG,WAAW,CAAC,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,sFAAsF;AACtF,KAAK,eAAe,GAAG;IACrB,UAAU,EAAE,aAAa,CAAC;IAC1B,SAAS,EAAE,cAAc,oBAAoB,EAAE,SAAS,CAAC;IACzD,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAUF,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,UAAQ,GACpB,OAAO,CAAC,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAuC/C;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GACtD,IAAI,CAuBN"}
package/dist/vueSource.js CHANGED
@@ -1,11 +1,21 @@
1
1
  import { MAX_AST_PARSE_BYTES } from './ast/astChunker.js';
2
+ import { MAX_SCANNED_FILE_BYTES } from './codeScanner.js';
2
3
  /** A fallback scrub may repair syntax; it must never become graph evidence. */
3
4
  export const VUE_FIDELITY_MARKER = '<!-- mnemonik:vue-source-fidelity-unavailable -->';
5
+ /**
6
+ * Sanitation runs on the API server's event loop (scan push, file push, documents), and
7
+ * its edit loop costs the file's length per edit, so it keeps the 2 MiB and 200,000-node
8
+ * bounds until it moves off that loop. Connected-code reads run in the parse pool and
9
+ * take any file up to the product's 10 MB ceiling.
10
+ */
11
+ const SANITATION_MAX_BYTES = MAX_AST_PARSE_BYTES;
12
+ const SANITATION_TEMPLATE_NODE_LIMIT = 200_000;
4
13
  export async function parseVueSource(source, forSanitation = false) {
5
14
  // Sanitation still inspects marked bytes; graph extraction must continue to reject them.
6
15
  if (!forSanitation && source.includes(VUE_FIDELITY_MARKER))
7
16
  return { reason: 'vue_source_fidelity_unavailable' };
8
- if (Buffer.byteLength(source, 'utf8') > MAX_AST_PARSE_BYTES)
17
+ if (Buffer.byteLength(source, 'utf8') >
18
+ (forSanitation ? SANITATION_MAX_BYTES : MAX_SCANNED_FILE_BYTES))
9
19
  return { reason: 'file_too_large' };
10
20
  let clearCache;
11
21
  try {
@@ -27,7 +37,9 @@ export async function parseVueSource(source, forSanitation = false) {
27
37
  (descriptor.template?.lang && descriptor.template.lang !== 'html') ||
28
38
  descriptor.customBlocks.length)
29
39
  return { reason: 'vue_preprocessor_or_custom_block_unsupported' };
30
- return { descriptor, nodeTypes };
40
+ return forSanitation
41
+ ? { descriptor, nodeTypes, templateNodeLimit: SANITATION_TEMPLATE_NODE_LIMIT }
42
+ : { descriptor, nodeTypes };
31
43
  }
32
44
  catch {
33
45
  return { reason: 'vue_parse_failed' };
@@ -43,12 +55,14 @@ export function walkVueTemplate(parsed, visit) {
43
55
  const pending = descriptor.template?.ast
44
56
  ? [{ node: descriptor.template.ast, scoped: false }]
45
57
  : [];
58
+ // Iterative and linear in the template's nodes; only sanitation is bounded by count.
59
+ const limit = parsed.templateNodeLimit ?? Infinity;
46
60
  let count = 0;
47
61
  while (pending.length) {
48
62
  const item = pending.pop();
49
63
  if (!item)
50
64
  break;
51
- if (++count > 200_000)
65
+ if (++count > limit)
52
66
  throw new Error('vue_template_work_limit');
53
67
  const { node } = item;
54
68
  const scoped = item.scoped ||
@@ -1 +1 @@
1
- {"version":3,"file":"vueSource.js","sourceRoot":"","sources":["../src/vueSource.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vueSource.js","sourceRoot":"","sources":["../src/vueSource.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnemonik/shared",
3
- "version": "7.152.0",
3
+ "version": "7.153.0",
4
4
  "description": "Shared constants and utilities for Mnemonik packages",
5
5
  "repository": {
6
6
  "type": "git",
package/src/vueSource.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { SFCDescriptor } from '@vue/compiler-sfc';
2
2
  import { MAX_AST_PARSE_BYTES } from './ast/astChunker.js';
3
+ import { MAX_SCANNED_FILE_BYTES } from './codeScanner.js';
3
4
 
4
5
  /** A fallback scrub may repair syntax; it must never become graph evidence. */
5
6
  export const VUE_FIDELITY_MARKER = '<!-- mnemonik:vue-source-fidelity-unavailable -->';
@@ -10,7 +11,18 @@ export type VueTemplateNode = TemplateRoot | TemplateRoot['children'][number];
10
11
  type ParsedVueSource = {
11
12
  descriptor: SFCDescriptor;
12
13
  nodeTypes: typeof import('@vue/compiler-core').NodeTypes;
14
+ /** Set on the sanitation path only; the template walk throws past it. */
15
+ templateNodeLimit?: number;
13
16
  };
17
+
18
+ /**
19
+ * Sanitation runs on the API server's event loop (scan push, file push, documents), and
20
+ * its edit loop costs the file's length per edit, so it keeps the 2 MiB and 200,000-node
21
+ * bounds until it moves off that loop. Connected-code reads run in the parse pool and
22
+ * take any file up to the product's 10 MB ceiling.
23
+ */
24
+ const SANITATION_MAX_BYTES = MAX_AST_PARSE_BYTES;
25
+ const SANITATION_TEMPLATE_NODE_LIMIT = 200_000;
14
26
  export async function parseVueSource(
15
27
  source: string,
16
28
  forSanitation = false
@@ -18,7 +30,11 @@ export async function parseVueSource(
18
30
  // Sanitation still inspects marked bytes; graph extraction must continue to reject them.
19
31
  if (!forSanitation && source.includes(VUE_FIDELITY_MARKER))
20
32
  return { reason: 'vue_source_fidelity_unavailable' };
21
- if (Buffer.byteLength(source, 'utf8') > MAX_AST_PARSE_BYTES) return { reason: 'file_too_large' };
33
+ if (
34
+ Buffer.byteLength(source, 'utf8') >
35
+ (forSanitation ? SANITATION_MAX_BYTES : MAX_SCANNED_FILE_BYTES)
36
+ )
37
+ return { reason: 'file_too_large' };
22
38
  let clearCache: (() => void) | undefined;
23
39
  try {
24
40
  // Most shared consumers never scan Vue; do not load the compiler on their startup path.
@@ -40,7 +56,9 @@ export async function parseVueSource(
40
56
  descriptor.customBlocks.length
41
57
  )
42
58
  return { reason: 'vue_preprocessor_or_custom_block_unsupported' };
43
- return { descriptor, nodeTypes };
59
+ return forSanitation
60
+ ? { descriptor, nodeTypes, templateNodeLimit: SANITATION_TEMPLATE_NODE_LIMIT }
61
+ : { descriptor, nodeTypes };
44
62
  } catch {
45
63
  return { reason: 'vue_parse_failed' };
46
64
  } finally {
@@ -58,11 +76,13 @@ export function walkVueTemplate(
58
76
  const pending: Array<{ node: VueTemplateNode; scoped: boolean }> = descriptor.template?.ast
59
77
  ? [{ node: descriptor.template.ast, scoped: false }]
60
78
  : [];
79
+ // Iterative and linear in the template's nodes; only sanitation is bounded by count.
80
+ const limit = parsed.templateNodeLimit ?? Infinity;
61
81
  let count = 0;
62
82
  while (pending.length) {
63
83
  const item = pending.pop();
64
84
  if (!item) break;
65
- if (++count > 200_000) throw new Error('vue_template_work_limit');
85
+ if (++count > limit) throw new Error('vue_template_work_limit');
66
86
  const { node } = item;
67
87
  const scoped =
68
88
  item.scoped ||