@sigloch/graph-api-core 5.0.0 → 5.1.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.
@@ -23,6 +23,12 @@ export declare class FormatECodec {
23
23
  private parseNodeLine;
24
24
  private parseEdgeLine;
25
25
  private parseMerge;
26
+ /**
27
+ * CR-SM-251: derselbe Hydrations-Ort wie beim `@key value`-Pfad. Vorher war dies der einzige
28
+ * Pfad OHNE Hydration — hart auf `Record<string, string>` typisiert, womit `[concept:true]`
29
+ * als String "true" ankam und jede `=== true`-Ausnahme wirkungslos blieb (CR-GC-334 hatte
30
+ * genau diese Doppelung schon einmal fuer Objekte aufgeloest, nur eine Zeile weiter oben).
31
+ */
26
32
  private parseInlineAttrs;
27
33
  /**
28
34
  * CR-SM-215: fan-out serialization — edges sharing `(sourceId, edgeType)` collapse
@@ -7,7 +7,7 @@
7
7
  * family (`TYPE-slug`, `Name.TypeAbbr.Counter`, `cand_<hex>`); typing by spelling made
8
8
  * every foreign convention fail silently instead of loudly.
9
9
  */
10
- import { hydrateAttrValue } from '@sigloch/contracts/se';
10
+ import { hydrateAttrValue, attributeTypeOf } from '@sigloch/contracts/se';
11
11
  import { isValidTrace, tracePatternsOf } from './types.js';
12
12
  // ---------------------------------------------------------------------------
13
13
  // Regex patterns
@@ -78,7 +78,7 @@ export class FormatECodec {
78
78
  // them back as objects. Kept as a string, `realRef`/`testRef` fail their schema and
79
79
  // the element reads as UNBOUND — R-19/R-20 fired on every node authored through this
80
80
  // path. Same rule as the contracts parser, imported, not re-implemented.
81
- lastOp.attributes[attrMatch[1]] = hydrateAttrValue(attrMatch[2].trim());
81
+ lastOp.attributes[attrMatch[1]] = hydrateAttrValue(attrMatch[2].trim(), attributeTypeOf(lastOp.elementType, attrMatch[1]));
82
82
  }
83
83
  else {
84
84
  errors.push(`@attribute line without preceding node: "${line}"`);
@@ -197,7 +197,7 @@ export class FormatECodec {
197
197
  const attrMatch = INLINE_ATTRS_RE.exec(rest);
198
198
  if (attrMatch) {
199
199
  mainPart = rest.slice(0, attrMatch.index).trim();
200
- inlineAttrs = this.parseInlineAttrs(attrMatch[1]);
200
+ inlineAttrs = this.parseInlineAttrs(attrMatch[1], nodeType);
201
201
  }
202
202
  // Split uid|description
203
203
  const pipeIdx = mainPart.indexOf('|');
@@ -237,6 +237,9 @@ export class FormatECodec {
237
237
  const action = OP_PREFIX[opChar] ?? 'add';
238
238
  // Extract inline attributes from the line
239
239
  let mainPart = rest;
240
+ // CR-SM-251: Kanten-Attribute (cardinality/constraint/notes) sind Strings und bleiben es —
241
+ // `attributeTypeOf` kennt nur Element-Attribute, ohne Typ faellt die Hydrierung auf String
242
+ // zurueck. Der Typ ist trotzdem `unknown`, damit hier kein zweiter Hydrations-Pfad entsteht.
240
243
  let inlineAttrs;
241
244
  const attrMatch = INLINE_ATTRS_RE.exec(rest);
242
245
  if (attrMatch) {
@@ -308,12 +311,19 @@ export class FormatECodec {
308
311
  sourceIds: parts,
309
312
  });
310
313
  }
311
- parseInlineAttrs(raw) {
314
+ /**
315
+ * CR-SM-251: derselbe Hydrations-Ort wie beim `@key value`-Pfad. Vorher war dies der einzige
316
+ * Pfad OHNE Hydration — hart auf `Record<string, string>` typisiert, womit `[concept:true]`
317
+ * als String "true" ankam und jede `=== true`-Ausnahme wirkungslos blieb (CR-GC-334 hatte
318
+ * genau diese Doppelung schon einmal fuer Objekte aufgeloest, nur eine Zeile weiter oben).
319
+ */
320
+ parseInlineAttrs(raw, nodeType) {
312
321
  const attrs = {};
313
322
  for (const pair of raw.split(',')) {
314
323
  const colonIdx = pair.indexOf(':');
315
324
  if (colonIdx > 0) {
316
- attrs[pair.slice(0, colonIdx).trim()] = pair.slice(colonIdx + 1).trim();
325
+ const key = pair.slice(0, colonIdx).trim();
326
+ attrs[key] = hydrateAttrValue(pair.slice(colonIdx + 1).trim(), attributeTypeOf(nodeType, key));
317
327
  }
318
328
  }
319
329
  return attrs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigloch/graph-api-core",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,7 +43,7 @@
43
43
  "access": "public"
44
44
  },
45
45
  "peerDependencies": {
46
- "@sigloch/contracts": ">=5 <6",
46
+ "@sigloch/contracts": ">=5 <7",
47
47
  "kuzu-wasm": "^0.11.3"
48
48
  },
49
49
  "peerDependenciesMeta": {
@@ -52,7 +52,7 @@
52
52
  }
53
53
  },
54
54
  "devDependencies": {
55
- "@sigloch/contracts": "^5.0.1",
55
+ "@sigloch/contracts": "^6.0.0",
56
56
  "kuzu-wasm": "^0.11.3"
57
57
  }
58
58
  }