@graphty/graph-io 0.3.35 → 0.3.37

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.
Files changed (172) hide show
  1. package/dist/chunks/{choose-494CpuXQ.js → choose-CsO24U-5.js} +2 -2
  2. package/dist/chunks/{choose-494CpuXQ.js.map → choose-CsO24U-5.js.map} +1 -1
  3. package/dist/chunks/{constants-BBK4rsQZ.js → constants-BPRiVyBu.js} +2 -2
  4. package/dist/chunks/{constants-BBK4rsQZ.js.map → constants-BPRiVyBu.js.map} +1 -1
  5. package/dist/chunks/{escape-wVIEtLv6.js → escape-BRcyzD77.js} +4 -4
  6. package/dist/chunks/{escape-wVIEtLv6.js.map → escape-BRcyzD77.js.map} +1 -1
  7. package/dist/chunks/{export-Cbt4h_0n.js → export-CTUlibzr.js} +4 -4
  8. package/dist/chunks/export-CTUlibzr.js.map +1 -0
  9. package/dist/chunks/{exporter-CkPnJCXU.js → exporter-2UNIxzcu.js} +3 -3
  10. package/dist/chunks/{exporter-CkPnJCXU.js.map → exporter-2UNIxzcu.js.map} +1 -1
  11. package/dist/chunks/{exporter-LZTIAzkS.js → exporter-B_YFZ4ix.js} +8 -8
  12. package/dist/chunks/exporter-B_YFZ4ix.js.map +1 -0
  13. package/dist/chunks/{exporter-CqnmKk-f.js → exporter-Bn4jdYfd.js} +5 -5
  14. package/dist/chunks/{exporter-CqnmKk-f.js.map → exporter-Bn4jdYfd.js.map} +1 -1
  15. package/dist/chunks/{exporter-DMxRy-0l.js → exporter-flsHFoER.js} +4 -4
  16. package/dist/chunks/{exporter-DMxRy-0l.js.map → exporter-flsHFoER.js.map} +1 -1
  17. package/dist/chunks/{importer-C1VMuEBQ.js → importer-BD3mi2QH.js} +10 -10
  18. package/dist/chunks/importer-BD3mi2QH.js.map +1 -0
  19. package/dist/chunks/{importer-DvPvd4Yy.js → importer-Bgb9sgZZ.js} +9 -9
  20. package/dist/chunks/importer-Bgb9sgZZ.js.map +1 -0
  21. package/dist/chunks/{importer-CSmH218L.js → importer-CEuUmyPe.js} +10 -10
  22. package/dist/chunks/importer-CEuUmyPe.js.map +1 -0
  23. package/dist/chunks/{importer-DMgcD1wI.js → importer-DqMtyYLX.js} +11 -11
  24. package/dist/chunks/importer-DqMtyYLX.js.map +1 -0
  25. package/dist/chunks/{importer-BTSvNJUB.js → importer-Dwqepe_B.js} +3 -3
  26. package/dist/chunks/{importer-BTSvNJUB.js.map → importer-Dwqepe_B.js.map} +1 -1
  27. package/dist/chunks/{importer-BTbjwN10.js → importer-oIUx9u_g.js} +9 -9
  28. package/dist/chunks/importer-oIUx9u_g.js.map +1 -0
  29. package/dist/chunks/{importer-DtKPzhVp.js → importer-yWUPR_nU.js} +13 -13
  30. package/dist/chunks/importer-yWUPR_nU.js.map +1 -0
  31. package/dist/chunks/{json-elements-CxJF-Szz.js → json-elements-AkglPS3m.js} +4 -4
  32. package/dist/chunks/json-elements-AkglPS3m.js.map +1 -0
  33. package/dist/chunks/{ontology-export-p1PsPenq.js → ontology-export-DDoG3egY.js} +2 -2
  34. package/dist/chunks/{ontology-export-p1PsPenq.js.map → ontology-export-DDoG3egY.js.map} +1 -1
  35. package/dist/chunks/{records-BrfHycmg.js → records-ChmWZGuz.js} +2 -2
  36. package/dist/chunks/{records-BrfHycmg.js.map → records-ChmWZGuz.js.map} +1 -1
  37. package/dist/chunks/{text-BD-TzLNm.js → text-Btw3sBe_.js} +2 -2
  38. package/dist/chunks/{text-BD-TzLNm.js.map → text-Btw3sBe_.js.map} +1 -1
  39. package/dist/csv.js +4 -4
  40. package/dist/cx.js +1 -1
  41. package/dist/cx2.js +2 -2
  42. package/dist/cys.js +1 -1
  43. package/dist/dot.js +1 -1
  44. package/dist/gexf.js +30 -30
  45. package/dist/gexf.js.map +1 -1
  46. package/dist/gml.js +8 -8
  47. package/dist/gml.js.map +1 -1
  48. package/dist/graph-io.js +28 -28
  49. package/dist/graph-io.js.map +1 -1
  50. package/dist/graphml.js +2 -2
  51. package/dist/json.js +1 -1
  52. package/dist/neo4j.js +6 -6
  53. package/dist/neo4j.js.map +1 -1
  54. package/dist/obo.js +1 -1
  55. package/dist/pajek.js +1 -1
  56. package/dist/src/common/attributes.d.ts +1 -2
  57. package/dist/src/common/attributes.d.ts.map +1 -1
  58. package/dist/src/common/attributes.js +2 -2
  59. package/dist/src/common/attributes.js.map +1 -1
  60. package/dist/src/common/direction.d.ts +1 -2
  61. package/dist/src/common/direction.d.ts.map +1 -1
  62. package/dist/src/common/direction.js +2 -2
  63. package/dist/src/common/direction.js.map +1 -1
  64. package/dist/src/common/escape.js +1 -1
  65. package/dist/src/common/escape.js.map +1 -1
  66. package/dist/src/common/export.js +1 -1
  67. package/dist/src/common/export.js.map +1 -1
  68. package/dist/src/common/ids.d.ts +1 -2
  69. package/dist/src/common/ids.d.ts.map +1 -1
  70. package/dist/src/common/ids.js +1 -2
  71. package/dist/src/common/ids.js.map +1 -1
  72. package/dist/src/common/input.d.ts +1 -2
  73. package/dist/src/common/input.d.ts.map +1 -1
  74. package/dist/src/common/input.js +2 -2
  75. package/dist/src/common/input.js.map +1 -1
  76. package/dist/src/common/json-elements.js +1 -1
  77. package/dist/src/common/json-elements.js.map +1 -1
  78. package/dist/src/common/options.d.ts +1 -2
  79. package/dist/src/common/options.d.ts.map +1 -1
  80. package/dist/src/common/options.js +1 -1
  81. package/dist/src/common/options.js.map +1 -1
  82. package/dist/src/common/xml.js +1 -1
  83. package/dist/src/common/xml.js.map +1 -1
  84. package/dist/src/formats/cx/importer.js +6 -6
  85. package/dist/src/formats/cx/importer.js.map +1 -1
  86. package/dist/src/formats/cys/importer.js +3 -3
  87. package/dist/src/formats/cys/importer.js.map +1 -1
  88. package/dist/src/formats/cys/tables.js +1 -1
  89. package/dist/src/formats/cys/tables.js.map +1 -1
  90. package/dist/src/formats/dot/exporter.js +3 -3
  91. package/dist/src/formats/dot/exporter.js.map +1 -1
  92. package/dist/src/formats/dot/importer.js +1 -1
  93. package/dist/src/formats/dot/importer.js.map +1 -1
  94. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  95. package/dist/src/formats/gexf/exporter.js +24 -27
  96. package/dist/src/formats/gexf/exporter.js.map +1 -1
  97. package/dist/src/formats/gexf/importer.d.ts +1 -2
  98. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  99. package/dist/src/formats/gexf/importer.js +5 -5
  100. package/dist/src/formats/gexf/importer.js.map +1 -1
  101. package/dist/src/formats/gml/exporter.js +4 -4
  102. package/dist/src/formats/gml/exporter.js.map +1 -1
  103. package/dist/src/formats/gml/syntax.js +1 -1
  104. package/dist/src/formats/gml/syntax.js.map +1 -1
  105. package/dist/src/formats/graphml/exporter.js +3 -3
  106. package/dist/src/formats/graphml/exporter.js.map +1 -1
  107. package/dist/src/formats/graphml/importer.js +2 -2
  108. package/dist/src/formats/graphml/importer.js.map +1 -1
  109. package/dist/src/formats/graphml/tree.js +2 -2
  110. package/dist/src/formats/graphml/tree.js.map +1 -1
  111. package/dist/src/formats/json/exporter.js +1 -1
  112. package/dist/src/formats/json/exporter.js.map +1 -1
  113. package/dist/src/formats/json/importer.js +1 -1
  114. package/dist/src/formats/json/importer.js.map +1 -1
  115. package/dist/src/formats/neo4j/exporter.js +3 -3
  116. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  117. package/dist/src/formats/pajek/exporter.js +4 -4
  118. package/dist/src/formats/pajek/exporter.js.map +1 -1
  119. package/dist/src/formats/xgmml/document.js +6 -6
  120. package/dist/src/formats/xgmml/document.js.map +1 -1
  121. package/dist/src/formats/xgmml/emit.js +2 -2
  122. package/dist/src/formats/xgmml/emit.js.map +1 -1
  123. package/dist/src/formats/xgmml/exporter.js +1 -1
  124. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  125. package/dist/src/formats/xgmml/importer.js +1 -1
  126. package/dist/src/formats/xgmml/importer.js.map +1 -1
  127. package/dist/src/registry.js +2 -2
  128. package/dist/src/registry.js.map +1 -1
  129. package/dist/src/sniff.js +1 -1
  130. package/dist/src/sniff.js.map +1 -1
  131. package/dist/xgmml.js +2 -2
  132. package/package.json +2 -2
  133. package/src/common/attributes.ts +1 -2
  134. package/src/common/direction.ts +2 -2
  135. package/src/common/escape.ts +1 -1
  136. package/src/common/export.ts +1 -1
  137. package/src/common/ids.ts +1 -3
  138. package/src/common/input.ts +2 -2
  139. package/src/common/json-elements.ts +1 -1
  140. package/src/common/options.ts +1 -1
  141. package/src/common/xml.ts +1 -1
  142. package/src/formats/cx/importer.ts +6 -6
  143. package/src/formats/cys/importer.ts +3 -3
  144. package/src/formats/cys/tables.ts +1 -1
  145. package/src/formats/dot/exporter.ts +3 -3
  146. package/src/formats/dot/importer.ts +1 -1
  147. package/src/formats/gexf/exporter.ts +24 -28
  148. package/src/formats/gexf/importer.ts +5 -5
  149. package/src/formats/gml/exporter.ts +4 -4
  150. package/src/formats/gml/syntax.ts +1 -1
  151. package/src/formats/graphml/exporter.ts +3 -3
  152. package/src/formats/graphml/importer.ts +2 -2
  153. package/src/formats/graphml/tree.ts +2 -2
  154. package/src/formats/json/exporter.ts +1 -1
  155. package/src/formats/json/importer.ts +1 -1
  156. package/src/formats/neo4j/exporter.ts +3 -3
  157. package/src/formats/pajek/exporter.ts +4 -4
  158. package/src/formats/xgmml/document.ts +6 -6
  159. package/src/formats/xgmml/emit.ts +2 -2
  160. package/src/formats/xgmml/exporter.ts +1 -1
  161. package/src/formats/xgmml/importer.ts +1 -1
  162. package/src/registry.ts +2 -2
  163. package/src/sniff.ts +1 -1
  164. package/dist/chunks/export-Cbt4h_0n.js.map +0 -1
  165. package/dist/chunks/exporter-LZTIAzkS.js.map +0 -1
  166. package/dist/chunks/importer-BTbjwN10.js.map +0 -1
  167. package/dist/chunks/importer-C1VMuEBQ.js.map +0 -1
  168. package/dist/chunks/importer-CSmH218L.js.map +0 -1
  169. package/dist/chunks/importer-DMgcD1wI.js.map +0 -1
  170. package/dist/chunks/importer-DtKPzhVp.js.map +0 -1
  171. package/dist/chunks/importer-DvPvd4Yy.js.map +0 -1
  172. package/dist/chunks/json-elements-CxJF-Szz.js.map +0 -1
@@ -659,8 +659,7 @@ function collectTemporalTables(
659
659
  const end = table.get(TEMPORAL_COLUMNS.end);
660
660
  const value = table.get(TEMPORAL_COLUMNS.value);
661
661
  if (
662
- element === null ||
663
- element.dtype !== "u32" ||
662
+ element?.dtype !== "u32" ||
664
663
  start === null ||
665
664
  !isNumericScalar(start) ||
666
665
  end === null ||
@@ -1195,7 +1194,7 @@ function uniqueId(preferred: string, name: string, used: Set<string>): string {
1195
1194
  * @returns the text
1196
1195
  */
1197
1196
  function timeText(column: Column, companion: Column | null, row: number, timeFormat: TimeFormat | null): string {
1198
- if (companion !== null && companion.isSet(row)) {
1197
+ if (companion?.isSet(row)) {
1199
1198
  return companion.value(row) as string;
1200
1199
  }
1201
1200
  return formatTimeValue(column.value(row) as number, timeFormat);
@@ -1212,11 +1211,11 @@ function lifetimeAttrs(roles: RoleColumns, row: number, plan: ExportPlan): strin
1212
1211
  let out = "";
1213
1212
  const { timeFormat, version } = plan;
1214
1213
  let bits = 0;
1215
- if (version === "1.2" && roles.open !== null && roles.open.isSet(row)) {
1214
+ if (version === "1.2" && roles.open?.isSet(row)) {
1216
1215
  bits = roles.open.value(row) as number;
1217
1216
  }
1218
1217
  const write = (name: string, column: Column | null, open: boolean): void => {
1219
- if (column === null || !column.isSet(row)) {
1218
+ if (!column?.isSet(row)) {
1220
1219
  return;
1221
1220
  }
1222
1221
  const value = column.value(row) as number;
@@ -1228,7 +1227,7 @@ function lifetimeAttrs(roles: RoleColumns, row: number, plan: ExportPlan): strin
1228
1227
  // time-type) and replace `start` / `end`
1229
1228
  out += ` ${open ? `${name}open` : name}="${escapeXmlAttribute(text)}"`;
1230
1229
  };
1231
- if (roles.timestamp !== null && roles.timestamp.isSet(row)) {
1230
+ if (roles.timestamp?.isSet(row)) {
1232
1231
  if (version === "1.3" && plan.timeRepresentation === "timestamp") {
1233
1232
  write("timestamp", roles.timestamp, false);
1234
1233
  } else {
@@ -1239,7 +1238,7 @@ function lifetimeAttrs(roles: RoleColumns, row: number, plan: ExportPlan): strin
1239
1238
  write("start", roles.start, (bits & OPEN_START) !== 0);
1240
1239
  write("end", roles.end, (bits & OPEN_END) !== 0);
1241
1240
  }
1242
- if (version === "1.3" && roles.timestamps !== null && roles.timestamps.isSet(row)) {
1241
+ if (version === "1.3" && roles.timestamps?.isSet(row)) {
1243
1242
  const items = listItems(roles.timestamps, row).map((t) => formatTimeValue(t as number, timeFormat));
1244
1243
  out += ` timestamps="${escapeXmlAttribute(`<[${items.join(", ")}]>`)}"`;
1245
1244
  }
@@ -1258,17 +1257,14 @@ function lifetimeAttrs(roles: RoleColumns, row: number, plan: ExportPlan): strin
1258
1257
  */
1259
1258
  function spellsElement(roles: RoleColumns, row: number, plan: ExportPlan, indent: string): string {
1260
1259
  const pairs: (readonly [number, number, number])[] = [];
1261
- if (roles.spells !== null && roles.spells.isSet(row)) {
1262
- const open =
1263
- plan.version === "1.2" && roles.spellsOpen !== null && roles.spellsOpen.isSet(row)
1264
- ? listItems(roles.spellsOpen, row)
1265
- : [];
1260
+ if (roles.spells?.isSet(row)) {
1261
+ const open = plan.version === "1.2" && roles.spellsOpen?.isSet(row) ? listItems(roles.spellsOpen, row) : [];
1266
1262
  listItems(roles.spells, row).forEach((pair, i) => {
1267
1263
  const [s, e] = Array.from(pair as ArrayLike<number>);
1268
1264
  pairs.push([s, e, (open[i] as number | undefined) ?? 0]);
1269
1265
  });
1270
1266
  }
1271
- if (plan.version === "1.2" && roles.timestamps !== null && roles.timestamps.isSet(row)) {
1267
+ if (plan.version === "1.2" && roles.timestamps?.isSet(row)) {
1272
1268
  for (const t of listItems(roles.timestamps, row)) {
1273
1269
  pairs.push([t as number, t as number, 0]);
1274
1270
  }
@@ -1304,9 +1300,9 @@ function attvaluesElement(attrs: readonly AttributeSpec[], row: number, plan: Ex
1304
1300
  let out = "";
1305
1301
  for (const spec of attrs) {
1306
1302
  const { column } = spec;
1307
- if (column !== null && column.isSet(row)) {
1303
+ if (column?.isSet(row)) {
1308
1304
  let text: string | null;
1309
- if (spec.companion !== null && spec.companion.isSet(row)) {
1305
+ if (spec.companion?.isSet(row)) {
1310
1306
  text = spec.companion.value(row) as string;
1311
1307
  } else {
1312
1308
  text = spec.format(cellValue(column, row));
@@ -1328,7 +1324,7 @@ function attvaluesElement(attrs: readonly AttributeSpec[], row: number, plan: Ex
1328
1324
  continue;
1329
1325
  }
1330
1326
  let text: string | null;
1331
- if (table.valueText !== null && table.valueText.isSet(r)) {
1327
+ if (table.valueText?.isSet(r)) {
1332
1328
  text = table.valueText.value(r) as string;
1333
1329
  } else {
1334
1330
  text = table.format(cellValue(table.value, r));
@@ -1357,7 +1353,7 @@ function timedAttrs(table: TemporalTable, r: number, plan: ExportPlan): string {
1357
1353
  return ` timestamp="${escapeXmlAttribute(timeText(table.start, table.startText, r, plan.timeFormat))}"`;
1358
1354
  }
1359
1355
  let bits = 0;
1360
- if (plan.version === "1.2" && table.open !== null && table.open.isSet(r)) {
1356
+ if (plan.version === "1.2" && table.open?.isSet(r)) {
1361
1357
  bits = table.open.value(r) as number;
1362
1358
  }
1363
1359
  if (Number.isFinite(start)) {
@@ -1447,7 +1443,7 @@ function listItems(column: Column, row: number): readonly unknown[] {
1447
1443
  function vizElements(roles: RoleColumns, row: number, indent: string, writeZ: boolean): string {
1448
1444
  let out = "";
1449
1445
  const { color } = roles;
1450
- if (color !== null && color.isSet(row)) {
1446
+ if (color?.isSet(row)) {
1451
1447
  const lanes = Array.from(color.value(row) as ArrayLike<number>);
1452
1448
  const scale = color.dtype === "u8" ? 1 : 255;
1453
1449
  const channel = (v: number): string => String(Math.max(0, Math.min(255, Math.round(v * scale))));
@@ -1461,7 +1457,7 @@ function vizElements(roles: RoleColumns, row: number, indent: string, writeZ: bo
1461
1457
  out += `${indent}<viz:color${attrs}/>\n`;
1462
1458
  }
1463
1459
  const { position } = roles;
1464
- if (position !== null && position.isSet(row)) {
1460
+ if (position?.isSet(row)) {
1465
1461
  const lanes = Array.from(position.value(row) as ArrayLike<number>);
1466
1462
  const fmt = position.dtype === "f32" ? formatF32 : formatF64;
1467
1463
  let attrs = ` x="${fmt(lanes[0])}" y="${fmt(lanes[1])}"`;
@@ -1474,16 +1470,16 @@ function vizElements(roles: RoleColumns, row: number, indent: string, writeZ: bo
1474
1470
  ["size", roles.size],
1475
1471
  ["thickness", roles.thickness],
1476
1472
  ] as const) {
1477
- if (column !== null && column.isSet(row)) {
1473
+ if (column?.isSet(row)) {
1478
1474
  const value = column.value(row) as number;
1479
1475
  const text = column.dtype === "f32" ? formatF32(value) : formatF64(value);
1480
1476
  out += `${indent}<viz:${name} value="${escapeXmlAttribute(text)}"/>\n`;
1481
1477
  }
1482
1478
  }
1483
1479
  const { shape } = roles;
1484
- if (shape !== null && shape.isSet(row)) {
1480
+ if (shape?.isSet(row)) {
1485
1481
  let attrs = ` value="${escapeXmlAttribute(String(shape.value(row)))}"`;
1486
- if (roles.shapeUri !== null && roles.shapeUri.isSet(row)) {
1482
+ if (roles.shapeUri?.isSet(row)) {
1487
1483
  attrs += ` uri="${escapeXmlAttribute(roles.shapeUri.value(row) as string)}"`;
1488
1484
  }
1489
1485
  out += `${indent}<viz:shape${attrs}/>\n`;
@@ -1580,15 +1576,15 @@ function* writeGexf(
1580
1576
  yield ` <nodes count="${snapshot.nodeCount}">\n`;
1581
1577
  for (let i = 0; i < snapshot.nodeCount; i++) {
1582
1578
  let attrs = ` id="${idText(i)}"`;
1583
- if (nodeRoles.label !== null && nodeRoles.label.isSet(i)) {
1579
+ if (nodeRoles.label?.isSet(i)) {
1584
1580
  attrs += ` label="${escapeXmlAttribute(String(nodeRoles.label.value(i)))}"`;
1585
1581
  }
1586
- if (nodeRoles.parent !== null && nodeRoles.parent.isSet(i)) {
1582
+ if (nodeRoles.parent?.isSet(i)) {
1587
1583
  attrs += ` pid="${idText(nodeRoles.parent.value(i) as number)}"`;
1588
1584
  }
1589
1585
  attrs += lifetimeAttrs(nodeRoles, i, plan);
1590
1586
  let body = attvaluesElement(plan.nodeAttrs, i, plan, " ");
1591
- if (nodeRoles.parents !== null && nodeRoles.parents.isSet(i)) {
1587
+ if (nodeRoles.parents?.isSet(i)) {
1592
1588
  const parents = listItems(nodeRoles.parents, i) as readonly number[];
1593
1589
  if (parents.length > 0) {
1594
1590
  body += " <parents>\n";
@@ -1624,7 +1620,7 @@ function* writeGexf(
1624
1620
  continue;
1625
1621
  }
1626
1622
  let attrs = "";
1627
- if (edgeRoles.id !== null && edgeRoles.id.isSet(e)) {
1623
+ if (edgeRoles.id?.isSet(e)) {
1628
1624
  attrs += ` id="${escapeXmlAttribute(String(edgeRoles.id.value(e)))}"`;
1629
1625
  } else if (version === "1.2") {
1630
1626
  attrs += ` id="e${e}"`;
@@ -1637,10 +1633,10 @@ function* writeGexf(
1637
1633
  if (weight !== null) {
1638
1634
  attrs += ` weight="${weight}"`;
1639
1635
  }
1640
- if (edgeRoles.label !== null && edgeRoles.label.isSet(e)) {
1636
+ if (edgeRoles.label?.isSet(e)) {
1641
1637
  attrs += ` label="${escapeXmlAttribute(String(edgeRoles.label.value(e)))}"`;
1642
1638
  }
1643
- if (version === "1.3" && edgeRoles.kind !== null && edgeRoles.kind.isSet(e)) {
1639
+ if (version === "1.3" && edgeRoles.kind?.isSet(e)) {
1644
1640
  attrs += ` kind="${escapeXmlAttribute(String(edgeRoles.kind.value(e)))}"`;
1645
1641
  }
1646
1642
  attrs += lifetimeAttrs(edgeRoles, e, plan);
@@ -223,7 +223,7 @@ export {
223
223
  MISSING_ID_CODE,
224
224
  NO_GRAPH_CODE,
225
225
  UNKNOWN_PARENT_CODE,
226
- };
226
+ } from "../../common/codes.js";
227
227
 
228
228
  /** The GEXF versions graph-io knows, and the version a namespace implies when `version` is missing. */
229
229
  const VERSIONS: ReadonlySet<string> = new Set(["1.0", "1.1", "1.2", "1.3"]);
@@ -740,7 +740,7 @@ class GexfReader implements XmlHandler {
740
740
  // ---------------------------------------------------------------- events
741
741
 
742
742
  start(name: string, attrs: ReadonlyMap<string, string>, line: number, ns: string | null = ""): void {
743
- const parent = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];
743
+ const parent = this.ctx.at(-1) ?? null;
744
744
  const local = localName(name);
745
745
  if (
746
746
  ns === null &&
@@ -870,7 +870,7 @@ class GexfReader implements XmlHandler {
870
870
  * @param line - the line
871
871
  */
872
872
  text(text: string, line: number): void {
873
- const ctx = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];
873
+ const ctx = this.ctx.at(-1) ?? null;
874
874
  switch (ctx) {
875
875
  case Ctx.MetaText:
876
876
  this.metaText += text;
@@ -1267,7 +1267,7 @@ class GexfReader implements XmlHandler {
1267
1267
  }
1268
1268
  this.checkAttributes("attribute", attrs, line);
1269
1269
  const group = this.attributeGroup;
1270
- if (group === null || group.domain === null) {
1270
+ if (!group?.domain) {
1271
1271
  // the group's class was refused; its attributes are dropped with it
1272
1272
  this.ctx.push(Ctx.Skip);
1273
1273
  return;
@@ -1465,7 +1465,7 @@ class GexfReader implements XmlHandler {
1465
1465
  private beginNode(attrs: ReadonlyMap<string, string>, line: number): void {
1466
1466
  const { report, sink } = this;
1467
1467
  this.checkAbort();
1468
- const enclosing = this.nodeStack.length === 0 ? INVALID_INDEX : this.nodeStack[this.nodeStack.length - 1].index;
1468
+ const enclosing = this.nodeStack.at(-1)?.index ?? INVALID_INDEX;
1469
1469
  const idText = attrs.get("id");
1470
1470
  const where: IssueLocation = { line, element: idText ?? attrs.get("label") ?? null };
1471
1471
  this.countInSection("node");
@@ -1332,7 +1332,7 @@ function* gmlParts(context: WriteContext): Generator<string, void, undefined> {
1332
1332
  w.line(" ", "id", formatInteger(ids.idAt(i) as number));
1333
1333
  if (ids.isChanged(i)) {
1334
1334
  w.line(" ", ORIGINAL_ID_KEY, originalIdText(ids.originalAt(i)));
1335
- } else if (context.originalIds !== null && context.originalIds.isSet(i)) {
1335
+ } else if (context.originalIds?.isSet(i)) {
1336
1336
  const original = context.originalIds.value(i);
1337
1337
  if (typeof original === "string" || typeof original === "number") {
1338
1338
  w.line(" ", ORIGINAL_ID_KEY, originalIdText(original));
@@ -1357,7 +1357,7 @@ function* gmlParts(context: WriteContext): Generator<string, void, undefined> {
1357
1357
  w.raw(" edge [");
1358
1358
  w.line(" ", "source", formatInteger(ids.idAt(el.src[e]) as number));
1359
1359
  w.line(" ", "target", formatInteger(ids.idAt(el.dst[e]) as number));
1360
- if (context.edgeIds !== null && context.edgeIds.isSet(e)) {
1360
+ if (context.edgeIds?.isSet(e)) {
1361
1361
  w.cell(" ", "id", context.edgeIds, e);
1362
1362
  }
1363
1363
  if (context.weights.isExplicit(e)) {
@@ -1388,8 +1388,8 @@ function* gmlParts(context: WriteContext): Generator<string, void, undefined> {
1388
1388
  */
1389
1389
  function writeGraphics(w: GmlWriter, context: WriteContext, i: number): void {
1390
1390
  const { position, graphics } = context;
1391
- const hasPosition = position !== null && position.isSet(i);
1392
- const graphicsValue = graphics !== null && graphics.isSet(i) ? graphics.values[i] : undefined;
1391
+ const hasPosition = position?.isSet(i) === true;
1392
+ const graphicsValue = graphics?.isSet(i) ? graphics.values[i] : undefined;
1393
1393
  if (!hasPosition) {
1394
1394
  if (graphics !== null && graphicsValue !== undefined) {
1395
1395
  w.cell(" ", "graphics", graphics, i);
@@ -615,7 +615,7 @@ export function parseRecord(tokens: GmlTokens, open: number): Record<string, unk
615
615
  */
616
616
  function storeValue(frame: RecordFrame, key: string, value: unknown): void {
617
617
  const { record } = frame;
618
- if (frame.listKeys !== null && frame.listKeys.has(key)) {
618
+ if (frame.listKeys?.has(key)) {
619
619
  (record[key] as unknown[]).push(value);
620
620
  } else if (key in record) {
621
621
  record[key] = [record[key], value];
@@ -1173,7 +1173,7 @@ function keyElement(key: KeyPlan, indent: string): string {
1173
1173
  }
1174
1174
  const { column } = key;
1175
1175
  const desc = column?.meta.extra.desc;
1176
- const hasDefault = column !== null && column.meta.default !== undefined;
1176
+ const hasDefault = column?.meta.default !== undefined;
1177
1177
  if (column === null || (typeof desc !== "string" && !hasDefault)) {
1178
1178
  return `${text}/>\n`;
1179
1179
  }
@@ -1264,7 +1264,7 @@ function* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, v
1264
1264
 
1265
1265
  yield '<?xml version="1.0" encoding="UTF-8"?>\n';
1266
1266
  let root = `<graphml xmlns="${GRAPHML_NAMESPACE}"`;
1267
- const namespaces: Record<string, string> = { ...(plan.meta?.namespaces ?? {}) };
1267
+ const namespaces: Record<string, string> = { ...plan.meta?.namespaces };
1268
1268
  if (
1269
1269
  (plan.nodeColumns.some((c) => c.yfiles) ||
1270
1270
  plan.edgeColumns.some((c) => c.yfiles) ||
@@ -1371,7 +1371,7 @@ function* writeGraphml(snapshot: GraphSnapshot, plan: Plan): Generator<string, v
1371
1371
  * @returns the port name, or null when unset
1372
1372
  */
1373
1373
  function portText(column: Column | null, e: number): string | null {
1374
- if (column === null || !column.isSet(e)) {
1374
+ if (!column?.isSet(e)) {
1375
1375
  return null;
1376
1376
  }
1377
1377
  const value = column.value(e);
@@ -509,7 +509,7 @@ class GraphmlReader implements XmlHandler {
509
509
  * @param ns - the element's namespace (null: an undeclared prefix)
510
510
  */
511
511
  start(name: string, attrs: ReadonlyMap<string, string>, line: number, ns: string | null = ""): void {
512
- const parent = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];
512
+ const parent = this.ctx.at(-1) ?? null;
513
513
  switch (parent) {
514
514
  case Ctx.Capture:
515
515
  this.captureStart(name, attrs);
@@ -636,7 +636,7 @@ class GraphmlReader implements XmlHandler {
636
636
  * @param line - the line
637
637
  */
638
638
  text(text: string, line: number): void {
639
- const ctx = this.ctx.length === 0 ? null : this.ctx[this.ctx.length - 1];
639
+ const ctx = this.ctx.at(-1) ?? null;
640
640
  switch (ctx) {
641
641
  case Ctx.Capture:
642
642
  this.content.tree?.text(text);
@@ -79,7 +79,7 @@ export class XmlTreeBuilder {
79
79
  * @param text - the text
80
80
  */
81
81
  text(text: string): void {
82
- const frame = this.frames.length > 0 ? this.frames[this.frames.length - 1] : this.root;
82
+ const frame = this.frames.at(-1) ?? this.root;
83
83
  frame.text += text;
84
84
  }
85
85
 
@@ -91,7 +91,7 @@ export class XmlTreeBuilder {
91
91
  reason: "tree builder underflow",
92
92
  });
93
93
  }
94
- const parent = this.frames.length > 0 ? this.frames[this.frames.length - 1] : this.root;
94
+ const parent = this.frames.at(-1) ?? this.root;
95
95
  attachChild(parent, frame.name, valueOf(frame));
96
96
  }
97
97
 
@@ -1246,7 +1246,7 @@ function idText(id: NodeId): string {
1246
1246
  */
1247
1247
  function edgeIdText(p: Plan, e: number, c: Cursor): string | null {
1248
1248
  const column = p.edgeIds;
1249
- if (column === null || !column.isSet(e)) {
1249
+ if (!column?.isSet(e)) {
1250
1250
  return null;
1251
1251
  }
1252
1252
  return cellText(column, e, c.ids, c.nonfinite);
@@ -615,7 +615,7 @@ function withoutPath(value: unknown, segments: readonly string[]): unknown {
615
615
  * @returns the key
616
616
  */
617
617
  function pathEdgesKey(json: ResolvedJsonOptions, edgesPath: readonly string[]): string {
618
- return json.edgesKey ?? (edgesPath[edgesPath.length - 1] === "links" ? "links" : "edges");
618
+ return json.edgesKey ?? (edgesPath.at(-1) === "links" ? "links" : "edges");
619
619
  }
620
620
 
621
621
  /**
@@ -897,7 +897,7 @@ class ExportPlan {
897
897
  */
898
898
  spaceOf(index: number): string | null {
899
899
  const { idSpace } = this;
900
- if (idSpace === null || !idSpace.isSet(index)) {
900
+ if (!idSpace?.isSet(index)) {
901
901
  return null;
902
902
  }
903
903
  const value = idSpace.value(index);
@@ -1165,7 +1165,7 @@ class ExportPlan {
1165
1165
  */
1166
1166
  private labelsText(index: number): string | null {
1167
1167
  const { labels } = this;
1168
- if (labels === null || !labels.isSet(index)) {
1168
+ if (!labels?.isSet(index)) {
1169
1169
  return null;
1170
1170
  }
1171
1171
  if (labels.dtype === "list") {
@@ -1203,7 +1203,7 @@ class ExportPlan {
1203
1203
  }
1204
1204
  return texts.join(this.options.arrayDelimiter);
1205
1205
  }
1206
- const text = companion !== null && companion.isSet(row) ? textOf(companion, row) : null;
1206
+ const text = companion?.isSet(row) ? textOf(companion, row) : null;
1207
1207
  return formatScalar(column.dtype === "json" ? column.values[row] : column.value(row), scalar, text);
1208
1208
  }
1209
1209
  }
@@ -335,7 +335,7 @@ function labelNotes(snapshot: GraphSnapshot, nodePlan: readonly PlannedColumn[],
335
335
  }
336
336
  let gained = 0;
337
337
  for (let i = 0; i < snapshot.nodeCount; i++) {
338
- if (labels === null || !labels.isSet(i)) {
338
+ if (!labels?.isSet(i)) {
339
339
  gained++;
340
340
  }
341
341
  }
@@ -542,7 +542,7 @@ function firstModeOf(snapshot: GraphSnapshot): number | null {
542
542
  * @returns the label text, or null
543
543
  */
544
544
  function labelOf(labels: Column | null, ids: SanitizedIds, i: number, needed: boolean): string | null {
545
- if (labels !== null && labels.isSet(i)) {
545
+ if (labels?.isSet(i)) {
546
546
  return cellText(labels, i);
547
547
  }
548
548
  if (needed || ids.isChanged(i)) {
@@ -778,7 +778,7 @@ function* writeVertices(
778
778
  parts.push(coordinates);
779
779
  }
780
780
  }
781
- if (shape !== null && shape.isSet(i)) {
781
+ if (shape?.isSet(i)) {
782
782
  const keyword = cellText(shape, i);
783
783
  if (SHAPES.has(keyword)) {
784
784
  parts.push(keyword);
@@ -861,7 +861,7 @@ function* writeLines(snapshot: GraphSnapshot, edgePlan: readonly PlannedColumn[]
861
861
  // a mutual pair (design section 3.6): both directions, written once as an undirected edge
862
862
  const directed = snapshot.directed && folding.sourceDirected(e) && !folding.isMutual(e);
863
863
  const kind = directed ? "arcs" : "edges";
864
- const relationName = relation !== null && relation.isSet(e) ? cellText(relation, e) : null;
864
+ const relationName = relation?.isSet(e) ? cellText(relation, e) : null;
865
865
  if (!sectionOpen || kind !== currentKind || relationName !== currentRelation) {
866
866
  currentKind = kind;
867
867
  currentRelation = relationName;
@@ -346,7 +346,7 @@ export class XgmmlParser implements XmlHandler {
346
346
  */
347
347
  start(rawName: string, rawAttrs: ReadonlyMap<string, string>, line: number): void {
348
348
  this.enterScope(rawAttrs);
349
- const top = this.frames.length === 0 ? null : this.frames[this.frames.length - 1];
349
+ const top = this.frames.at(-1) ?? null;
350
350
  if (top === null) {
351
351
  this.startRoot(rawName, rawAttrs, line);
352
352
  return;
@@ -401,7 +401,7 @@ export class XgmmlParser implements XmlHandler {
401
401
  end(name: string, _line: number): void {
402
402
  this.scopes.pop();
403
403
  const frame = this.frames.pop();
404
- const below = this.frames.length === 0 ? null : this.frames[this.frames.length - 1];
404
+ const below = this.frames.at(-1) ?? null;
405
405
  switch (frame?.kind) {
406
406
  case "capture":
407
407
  frame.att.xml = `${frame.att.xml ?? ""}</${name}>`;
@@ -424,7 +424,7 @@ export class XgmmlParser implements XmlHandler {
424
424
  return;
425
425
  case "line":
426
426
  if (below?.kind === "graphics") {
427
- below.target.graphics = { ...(below.target.graphics ?? {}), Line: frame.points };
427
+ below.target.graphics = { ...below.target.graphics, Line: frame.points };
428
428
  }
429
429
  return;
430
430
  default:
@@ -437,7 +437,7 @@ export class XgmmlParser implements XmlHandler {
437
437
  * @param line - the line
438
438
  */
439
439
  text(text: string, line: number): void {
440
- const top = this.frames.length === 0 ? null : this.frames[this.frames.length - 1];
440
+ const top = this.frames.at(-1) ?? null;
441
441
  if (top === null || top.kind === "skip") {
442
442
  return;
443
443
  }
@@ -967,7 +967,7 @@ export class XgmmlParser implements XmlHandler {
967
967
  * @param line - the line
968
968
  */
969
969
  private beginGraphics(target: GraphicsTarget, attrs: Map<string, string>, line: number): void {
970
- const graphics: Record<string, unknown> = { ...(target.graphics ?? {}) };
970
+ const graphics: Record<string, unknown> = { ...target.graphics };
971
971
  for (const [key, value] of attrs) {
972
972
  if ("x" in target && (key === "x" || key === "y" || key === "z")) {
973
973
  if (target[key] !== null && target[key] !== undefined) {
@@ -1046,7 +1046,7 @@ export class XgmmlParser implements XmlHandler {
1046
1046
  if (target.graphics !== null && att.name in target.graphics) {
1047
1047
  this.duplicateGraphics(att.name, att.line);
1048
1048
  }
1049
- target.graphics = { ...(target.graphics ?? {}), [att.name]: attJson(att) };
1049
+ target.graphics = { ...target.graphics, [att.name]: attJson(att) };
1050
1050
  }
1051
1051
 
1052
1052
  /**
@@ -1229,7 +1229,7 @@ export class XgmmlEmitter {
1229
1229
  this.graphColumns.addAtt(0, att, where);
1230
1230
  }
1231
1231
  this.graphColumns.write(this.sink, () => 0);
1232
- const json: Record<string, unknown> = { ...(this.extras.graphJson ?? {}) };
1232
+ const json: Record<string, unknown> = { ...this.extras.graphJson };
1233
1233
  if (g.graphics !== null && Object.keys(g.graphics).length > 0) {
1234
1234
  json[GRAPHICS_COLUMN] = g.graphics;
1235
1235
  }
@@ -1267,7 +1267,7 @@ export class XgmmlEmitter {
1267
1267
  directed: this.doc.root.attrs.get("directed") ?? null,
1268
1268
  rdf: Object.keys(rdf).length > 0 ? { ...rdf } : null,
1269
1269
  },
1270
- ...(this.extras.metaExtra ?? {}),
1270
+ ...this.extras.metaExtra,
1271
1271
  },
1272
1272
  });
1273
1273
  }
@@ -971,7 +971,7 @@ function slot(writes: readonly ColumnWrite[], kind: ColumnWrite["kind"]): Column
971
971
  * @returns the value
972
972
  */
973
973
  function cellOf(column: Column | null, row: number): unknown {
974
- return column !== null && column.isSet(row) ? column.value(row) : null;
974
+ return column?.isSet(row) ? column.value(row) : null;
975
975
  }
976
976
 
977
977
  /**
@@ -439,7 +439,7 @@ function sniffXgmml(head: Uint8Array): number {
439
439
  const root = /<(?![?!])([A-Za-z_][\w.-]*:)?([A-Za-z_][\w.-]*)[\s/>]/.exec(
440
440
  text.replaceAll(/<!--[\s\S]*?(-->|$)/g, ""),
441
441
  );
442
- if (root === null || root[2] !== "graph") {
442
+ if (root?.[2] !== "graph") {
443
443
  return 0;
444
444
  }
445
445
  const tagEnd = text.indexOf(">", root.index);
package/src/registry.ts CHANGED
@@ -1610,7 +1610,7 @@ async function peekHead(input: ImportInput, bytes: number, signal: AbortSignal |
1610
1610
  let size = 0;
1611
1611
  let finished = false;
1612
1612
  while (size < bytes) {
1613
- if (signal !== null && signal.aborted) {
1613
+ if (signal?.aborted) {
1614
1614
  await source.return?.();
1615
1615
  throwIfAborted(signal);
1616
1616
  }
@@ -1622,7 +1622,7 @@ async function peekHead(input: ImportInput, bytes: number, signal: AbortSignal |
1622
1622
  buffered.push(next.value);
1623
1623
  size += typeof next.value === "string" ? next.value.length : next.value.byteLength;
1624
1624
  }
1625
- if (!finished && signal !== null && signal.aborted) {
1625
+ if (!finished && signal?.aborted) {
1626
1626
  // an abort that landed on the read completing the head: close the source before rethrowing
1627
1627
  await source.return?.();
1628
1628
  throwIfAborted(signal);
package/src/sniff.ts CHANGED
@@ -472,7 +472,7 @@ function scanKeys(text: string): Map<KeyPath, Set<string>> {
472
472
  if (ch === "{" || ch === "[") {
473
473
  let label = "";
474
474
  if (kinds.length > 0) {
475
- label = kinds[kinds.length - 1] === "object" ? (pendingKey ?? "") : String(counts[counts.length - 1]);
475
+ label = kinds.at(-1) === "object" ? (pendingKey ?? "") : String(counts.at(-1));
476
476
  }
477
477
  kinds.push(ch === "{" ? "object" : "array");
478
478
  labels.push(label);