@loaders.gl/graphs 4.5.3 → 5.0.0-alpha.11

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 (77) hide show
  1. package/LICENSE +14 -3
  2. package/README.md +122 -10
  3. package/dist/dot-loader-types.d.ts +40 -3
  4. package/dist/dot-loader-types.d.ts.map +1 -1
  5. package/dist/dot-loader-types.js +8 -2
  6. package/dist/dot-loader-types.js.map +1 -1
  7. package/dist/dot-loader.cjs +1449 -108
  8. package/dist/dot-loader.cjs.map +3 -4
  9. package/dist/dot-loader.d.ts +11 -6
  10. package/dist/dot-loader.d.ts.map +1 -1
  11. package/dist/dot-loader.js +3 -3
  12. package/dist/dot-loader.js.map +1 -1
  13. package/dist/dot-types.d.ts +6 -1
  14. package/dist/dot-types.d.ts.map +1 -1
  15. package/dist/gexf-loader-types.d.ts +53 -0
  16. package/dist/gexf-loader-types.d.ts.map +1 -0
  17. package/dist/gexf-loader-types.js +26 -0
  18. package/dist/gexf-loader-types.js.map +1 -0
  19. package/dist/gexf-loader.cjs +1304 -0
  20. package/dist/gexf-loader.cjs.map +6 -0
  21. package/dist/gexf-loader.d.ts +24 -0
  22. package/dist/gexf-loader.d.ts.map +1 -0
  23. package/dist/gexf-loader.js +13 -0
  24. package/dist/gexf-loader.js.map +1 -0
  25. package/dist/gexf-types.d.ts +16 -0
  26. package/dist/gexf-types.d.ts.map +1 -0
  27. package/dist/gexf-types.js +5 -0
  28. package/dist/gexf-types.js.map +1 -0
  29. package/dist/graph-types.d.ts +28 -0
  30. package/dist/graph-types.d.ts.map +1 -1
  31. package/dist/graphml-loader-types.d.ts +39 -3
  32. package/dist/graphml-loader-types.d.ts.map +1 -1
  33. package/dist/graphml-loader-types.js +8 -2
  34. package/dist/graphml-loader-types.js.map +1 -1
  35. package/dist/graphml-loader.cjs +1006 -61
  36. package/dist/graphml-loader.cjs.map +3 -4
  37. package/dist/graphml-loader.d.ts +11 -6
  38. package/dist/graphml-loader.d.ts.map +1 -1
  39. package/dist/graphml-loader.js +3 -3
  40. package/dist/graphml-loader.js.map +1 -1
  41. package/dist/index.cjs +1452 -470
  42. package/dist/index.cjs.map +3 -4
  43. package/dist/index.d.ts +9 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +3 -2
  46. package/dist/index.js.map +1 -1
  47. package/dist/lib/build-graph-tables.d.ts +4 -0
  48. package/dist/lib/build-graph-tables.d.ts.map +1 -0
  49. package/dist/lib/build-graph-tables.js +143 -0
  50. package/dist/lib/build-graph-tables.js.map +1 -0
  51. package/dist/lib/parse-dot.d.ts +3 -1
  52. package/dist/lib/parse-dot.d.ts.map +1 -1
  53. package/dist/lib/parse-dot.js +41 -24
  54. package/dist/lib/parse-dot.js.map +1 -1
  55. package/dist/lib/parse-gexf.d.ts +5 -0
  56. package/dist/lib/parse-gexf.d.ts.map +1 -0
  57. package/dist/lib/parse-gexf.js +380 -0
  58. package/dist/lib/parse-gexf.js.map +1 -0
  59. package/dist/lib/parse-graphml.d.ts +2 -1
  60. package/dist/lib/parse-graphml.d.ts.map +1 -1
  61. package/dist/lib/parse-graphml.js +50 -27
  62. package/dist/lib/parse-graphml.js.map +1 -1
  63. package/package.json +15 -6
  64. package/src/dot-loader-types.ts +21 -4
  65. package/src/dot-loader.ts +7 -4
  66. package/src/dot-types.ts +7 -1
  67. package/src/gexf-loader-types.ts +41 -0
  68. package/src/gexf-loader.ts +17 -0
  69. package/src/gexf-types.ts +21 -0
  70. package/src/graph-types.ts +35 -0
  71. package/src/graphml-loader-types.ts +20 -4
  72. package/src/graphml-loader.ts +7 -4
  73. package/src/index.ts +11 -2
  74. package/src/lib/build-graph-tables.ts +208 -0
  75. package/src/lib/parse-dot.ts +47 -24
  76. package/src/lib/parse-gexf.ts +388 -0
  77. package/src/lib/parse-graphml.ts +86 -34
package/dist/index.cjs CHANGED
@@ -1,8 +1,18 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res, err) => function __init() {
9
+ if (err) throw err[0];
10
+ try {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ } catch (e) {
13
+ throw err = [e], e;
14
+ }
15
+ };
6
16
  var __export = (target, all) => {
7
17
  for (var name in all)
8
18
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -15,46 +25,458 @@ var __copyProps = (to, from, except, desc) => {
15
25
  }
16
26
  return to;
17
27
  };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
18
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
37
 
20
- // dist/index.js
21
- var dist_exports = {};
22
- __export(dist_exports, {
23
- DOTLoader: () => DOTLoaderWithParser,
24
- GraphMLLoader: () => GraphMLLoaderWithParser
38
+ // src/graphml-loader-types.ts
39
+ async function preload() {
40
+ const { GraphMLLoaderWithParser: GraphMLLoaderWithParser2 } = await Promise.resolve().then(() => (init_graphml_loader(), graphml_loader_exports));
41
+ return GraphMLLoaderWithParser2;
42
+ }
43
+ var VERSION, GraphMLLoader;
44
+ var init_graphml_loader_types = __esm({
45
+ "src/graphml-loader-types.ts"() {
46
+ "use strict";
47
+ VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
48
+ GraphMLLoader = {
49
+ name: "GraphML",
50
+ id: "graphml",
51
+ module: "graphs",
52
+ version: VERSION,
53
+ extensions: ["graphml"],
54
+ mimeTypes: ["application/graphml+xml"],
55
+ text: true,
56
+ worker: false,
57
+ dataType: null,
58
+ batchType: null,
59
+ options: { graphml: { shape: "arrow-table" } },
60
+ preload
61
+ };
62
+ }
25
63
  });
26
- module.exports = __toCommonJS(dist_exports);
27
64
 
28
- // dist/graphml-loader-types.js
29
- var VERSION = true ? "4.5.3" : "latest";
30
- var GraphMLLoader = {
31
- name: "GraphML",
32
- id: "graphml",
33
- module: "graphs",
34
- version: VERSION,
35
- extensions: ["graphml"],
36
- mimeTypes: ["application/graphml+xml"],
37
- text: true,
38
- worker: false,
39
- dataType: null,
40
- batchType: null,
41
- options: {}
42
- };
65
+ // ../schema-utils/src/lib/schema/convert-arrow-schema.ts
66
+ function convertArrowToSchema(arrowSchema) {
67
+ return serializeArrowSchema(arrowSchema);
68
+ }
69
+ function serializeArrowSchema(arrowSchema) {
70
+ return {
71
+ fields: arrowSchema.fields.map((arrowField) => serializeArrowField(arrowField)),
72
+ metadata: serializeArrowMetadata(arrowSchema.metadata)
73
+ };
74
+ }
75
+ function serializeArrowMetadata(arrowMetadata) {
76
+ return Object.fromEntries(arrowMetadata);
77
+ }
78
+ function serializeArrowField(field) {
79
+ return {
80
+ name: field.name,
81
+ type: serializeArrowType(field.type),
82
+ nullable: field.nullable,
83
+ metadata: serializeArrowMetadata(field.metadata)
84
+ };
85
+ }
86
+ function serializeArrowType(arrowType) {
87
+ if (isArrowViewType(arrowType, "BinaryView")) {
88
+ return "binary-view";
89
+ }
90
+ if (isArrowViewType(arrowType, "Utf8View")) {
91
+ return "utf8-view";
92
+ }
93
+ if (isOptionalArrowType(arrowType, "LargeList")) {
94
+ const largeListType = arrowType;
95
+ return {
96
+ type: "large-list",
97
+ children: [serializeArrowField(largeListType.valueField)]
98
+ };
99
+ }
100
+ switch (arrowType.constructor) {
101
+ case arrow.Null:
102
+ return "null";
103
+ case arrow.Binary:
104
+ return "binary";
105
+ case arrow.FixedSizeBinary:
106
+ return {
107
+ type: "fixed-size-binary",
108
+ byteWidth: arrowType.byteWidth
109
+ };
110
+ case arrow.Bool:
111
+ return "bool";
112
+ case arrow.Int:
113
+ const intType = arrowType;
114
+ return `${intType.isSigned ? "" : "u"}int${intType.bitWidth}`;
115
+ case arrow.Int8:
116
+ return "int8";
117
+ case arrow.Int16:
118
+ return "int16";
119
+ case arrow.Int32:
120
+ return "int32";
121
+ case arrow.Int64:
122
+ return "int64";
123
+ case arrow.Uint8:
124
+ return "uint8";
125
+ case arrow.Uint16:
126
+ return "uint16";
127
+ case arrow.Uint32:
128
+ return "uint32";
129
+ case arrow.Uint64:
130
+ return "uint64";
131
+ case arrow.Float:
132
+ const precision = arrowType.precision;
133
+ switch (precision) {
134
+ case arrow.Precision.HALF:
135
+ return "float16";
136
+ case arrow.Precision.SINGLE:
137
+ return "float32";
138
+ case arrow.Precision.DOUBLE:
139
+ return "float64";
140
+ default:
141
+ return "float16";
142
+ }
143
+ case arrow.Float16:
144
+ return "float16";
145
+ case arrow.Float32:
146
+ return "float32";
147
+ case arrow.Float64:
148
+ return "float64";
149
+ case arrow.Utf8:
150
+ return "utf8";
151
+ case arrow.Decimal:
152
+ const decimal = arrowType;
153
+ return {
154
+ type: "decimal",
155
+ bitWidth: decimal.bitWidth,
156
+ precision: decimal.precision,
157
+ scale: decimal.scale
158
+ };
159
+ case arrow.Date_:
160
+ const dateUnit = arrowType.unit;
161
+ return dateUnit === arrow.DateUnit.DAY ? "date-day" : "date-millisecond";
162
+ case arrow.DateDay:
163
+ return "date-day";
164
+ case arrow.DateMillisecond:
165
+ return "date-millisecond";
166
+ case arrow.Time:
167
+ const timeUnit = arrowType.unit;
168
+ switch (timeUnit) {
169
+ case arrow.TimeUnit.SECOND:
170
+ return "time-second";
171
+ case arrow.TimeUnit.MILLISECOND:
172
+ return "time-millisecond";
173
+ case arrow.TimeUnit.MICROSECOND:
174
+ return "time-microsecond";
175
+ case arrow.TimeUnit.NANOSECOND:
176
+ return "time-nanosecond";
177
+ default:
178
+ return "time-second";
179
+ }
180
+ case arrow.TimeMillisecond:
181
+ return "time-millisecond";
182
+ case arrow.TimeSecond:
183
+ return "time-second";
184
+ case arrow.TimeMicrosecond:
185
+ return "time-microsecond";
186
+ case arrow.TimeNanosecond:
187
+ return "time-nanosecond";
188
+ case arrow.Timestamp:
189
+ const timeStampUnit = arrowType.unit;
190
+ switch (timeStampUnit) {
191
+ case arrow.TimeUnit.SECOND:
192
+ return "timestamp-second";
193
+ case arrow.TimeUnit.MILLISECOND:
194
+ return "timestamp-millisecond";
195
+ case arrow.TimeUnit.MICROSECOND:
196
+ return "timestamp-microsecond";
197
+ case arrow.TimeUnit.NANOSECOND:
198
+ return "timestamp-nanosecond";
199
+ default:
200
+ return "timestamp-second";
201
+ }
202
+ case arrow.TimestampSecond:
203
+ return "timestamp-second";
204
+ case arrow.TimestampMillisecond:
205
+ return "timestamp-millisecond";
206
+ case arrow.TimestampMicrosecond:
207
+ return "timestamp-microsecond";
208
+ case arrow.TimestampNanosecond:
209
+ return "timestamp-nanosecond";
210
+ case arrow.Interval:
211
+ const intervalUnit = arrowType.unit;
212
+ switch (intervalUnit) {
213
+ case arrow.IntervalUnit.DAY_TIME:
214
+ return "interval-daytime";
215
+ case arrow.IntervalUnit.YEAR_MONTH:
216
+ return "interval-yearmonth";
217
+ default:
218
+ return "interval-daytime";
219
+ }
220
+ case arrow.IntervalDayTime:
221
+ return "interval-daytime";
222
+ case arrow.IntervalYearMonth:
223
+ return "interval-yearmonth";
224
+ case arrow.Map_:
225
+ const mapType = arrowType;
226
+ return {
227
+ type: "map",
228
+ keysSorted: mapType.keysSorted,
229
+ children: mapType.children.map((arrowField) => serializeArrowField(arrowField))
230
+ };
231
+ case arrow.List:
232
+ const listType = arrowType;
233
+ const listField = listType.valueField;
234
+ return {
235
+ type: "list",
236
+ children: [serializeArrowField(listField)]
237
+ };
238
+ case arrow.FixedSizeList:
239
+ const fixedSizeList = arrowType;
240
+ return {
241
+ type: "fixed-size-list",
242
+ listSize: fixedSizeList.listSize,
243
+ children: [serializeArrowField(fixedSizeList.children[0])]
244
+ };
245
+ case arrow.Struct:
246
+ const structType = arrowType;
247
+ return {
248
+ type: "struct",
249
+ children: structType.children.map((arrowField) => serializeArrowField(arrowField))
250
+ };
251
+ case arrow.SparseUnion:
252
+ case arrow.DenseUnion:
253
+ const unionType = arrowType;
254
+ return {
255
+ type: unionType instanceof arrow.DenseUnion ? "dense-union" : "sparse-union",
256
+ typeIds: unionType.typeIds,
257
+ children: unionType.children.map((arrowField) => serializeArrowField(arrowField)),
258
+ typeIdToChildIndex: { ...unionType.typeIdToChildIndex }
259
+ };
260
+ case arrow.Dictionary:
261
+ const dictionaryType = arrowType;
262
+ return {
263
+ type: "dictionary",
264
+ id: dictionaryType.id,
265
+ indices: serializeArrowDictionaryKeyType(dictionaryType.indices),
266
+ dictionary: serializeArrowType(dictionaryType.dictionary),
267
+ isOrdered: dictionaryType.isOrdered
268
+ };
269
+ default:
270
+ throw new Error(`arrow type not supported: ${arrowType.constructor.name}`);
271
+ }
272
+ }
273
+ function getOptionalArrowConstructor(typeName) {
274
+ return arrow[typeName];
275
+ }
276
+ function isArrowViewType(arrowType, viewTypeName) {
277
+ const constructor = getOptionalArrowConstructor(viewTypeName);
278
+ if (constructor && arrowType instanceof constructor) {
279
+ return true;
280
+ }
281
+ const guards = arrow.DataType;
282
+ const guard = viewTypeName === "BinaryView" ? guards.isBinaryView : guards.isUtf8View;
283
+ return Boolean(guard == null ? void 0 : guard(arrowType));
284
+ }
285
+ function isOptionalArrowType(arrowType, typeName) {
286
+ const constructor = getOptionalArrowConstructor(typeName);
287
+ return Boolean(constructor && arrowType instanceof constructor);
288
+ }
289
+ function serializeArrowDictionaryKeyType(arrowType) {
290
+ if (arrowType instanceof arrow.Int) {
291
+ const prefix = arrowType.isSigned ? "int" : "uint";
292
+ const keyType = `${prefix}${arrowType.bitWidth}`;
293
+ if (isSchemaDictionaryKeyType(keyType)) {
294
+ return keyType;
295
+ }
296
+ }
297
+ switch (arrowType.constructor) {
298
+ case arrow.Int8:
299
+ return "int8";
300
+ case arrow.Int16:
301
+ return "int16";
302
+ case arrow.Int32:
303
+ return "int32";
304
+ case arrow.Uint8:
305
+ return "uint8";
306
+ case arrow.Uint16:
307
+ return "uint16";
308
+ case arrow.Uint32:
309
+ return "uint32";
310
+ default:
311
+ throw new Error(`arrow dictionary index type not supported: ${arrowType.constructor.name}`);
312
+ }
313
+ }
314
+ function isSchemaDictionaryKeyType(keyType) {
315
+ return ["int8", "int16", "int32", "uint8", "uint16", "uint32"].includes(keyType);
316
+ }
317
+ var arrow;
318
+ var init_convert_arrow_schema = __esm({
319
+ "../schema-utils/src/lib/schema/convert-arrow-schema.ts"() {
320
+ "use strict";
321
+ arrow = __toESM(require("apache-arrow"), 1);
322
+ }
323
+ });
324
+
325
+ // ../schema-utils/src/index.ts
326
+ var init_src = __esm({
327
+ "../schema-utils/src/index.ts"() {
328
+ "use strict";
329
+ init_convert_arrow_schema();
330
+ }
331
+ });
43
332
 
44
- // dist/lib/parse-graphml.js
45
- var import_fast_xml_parser = require("fast-xml-parser");
46
- var XML_ATTRIBUTE_PREFIX = "@_";
47
- var XML_TEXT_KEY = "#text";
48
- var graphmlParser = new import_fast_xml_parser.XMLParser({
49
- ignoreAttributes: false,
50
- attributeNamePrefix: XML_ATTRIBUTE_PREFIX,
51
- textNodeName: XML_TEXT_KEY,
52
- trimValues: true,
53
- parseAttributeValue: false,
54
- parseTagValue: false,
55
- removeNSPrefix: true
333
+ // src/lib/build-graph-tables.ts
334
+ function buildGraphTables(nodes, edges, shape, declarations) {
335
+ if (shape === "plain-graph-data") {
336
+ return { shape, nodes: Array.from(nodes), edges: Array.from(edges) };
337
+ }
338
+ if (shape !== "arrow-table" && shape !== "object-row-table") {
339
+ throw new Error(`Unsupported graph shape: ${shape}`);
340
+ }
341
+ const nodeTable = buildGraphTable(nodes, false, shape, declarations == null ? void 0 : declarations.nodes);
342
+ const edgeTable = buildGraphTable(edges, true, shape, declarations == null ? void 0 : declarations.edges);
343
+ return {
344
+ shape: "tables",
345
+ tables: [
346
+ { name: "nodes", table: nodeTable },
347
+ { name: "edges", table: edgeTable }
348
+ ]
349
+ };
350
+ }
351
+ function buildGraphTable(records, isEdge, shape, declarations) {
352
+ const columnNames = isEdge ? ["id", "sourceId", "targetId", "directed", "label", "attributes"] : ["id", "label", "attributes"];
353
+ const columns = new Map(columnNames.map((name) => [name, []]));
354
+ for (const record of records) {
355
+ for (const name of columnNames) {
356
+ const value = record[name];
357
+ columns.get(name).push(
358
+ name === "id" || name === "sourceId" || name === "targetId" ? String(value) : value ?? null
359
+ );
360
+ }
361
+ }
362
+ if (shape === "object-row-table") {
363
+ return {
364
+ shape,
365
+ data: columns.get("id").map(
366
+ (_, index) => Object.fromEntries(columnNames.map((name) => [name, columns.get(name)[index]]))
367
+ )
368
+ };
369
+ }
370
+ const vectors = /* @__PURE__ */ Object.create(null);
371
+ for (const [name, values] of columns) {
372
+ const type = name === "attributes" ? inferAttributeType(values, declarations) : name === "directed" ? new import_apache_arrow.Bool() : new import_apache_arrow.Utf8();
373
+ vectors[name] = (0, import_apache_arrow.vectorFromArray)(
374
+ values.map((value) => normalizeValue(value, type)),
375
+ type
376
+ );
377
+ }
378
+ const data = new import_apache_arrow.Table(vectors);
379
+ return { shape, schema: convertArrowToSchema(data.schema), data };
380
+ }
381
+ function inferAttributeType(values, declarations) {
382
+ const names = new Set(declarations == null ? void 0 : declarations.keys());
383
+ for (const value of values) {
384
+ if (value && typeof value === "object") {
385
+ for (const name of Object.keys(value)) {
386
+ names.add(name);
387
+ }
388
+ }
389
+ }
390
+ return new import_apache_arrow.Struct(
391
+ Array.from(names, (name) => {
392
+ const fieldValues = values.map(
393
+ (value) => (value == null ? void 0 : value[name]) ?? null
394
+ );
395
+ return new import_apache_arrow.Field(name, inferValueType(fieldValues, declarations == null ? void 0 : declarations.get(name)), true);
396
+ })
397
+ );
398
+ }
399
+ function inferValueType(values, declaration) {
400
+ const present = values.filter((value) => value !== null && value !== void 0);
401
+ if (declaration && typeof declaration === "object") {
402
+ if (!present.every((value) => Array.isArray(value))) return new import_apache_arrow.Utf8();
403
+ return new import_apache_arrow.List(
404
+ new import_apache_arrow.Field(
405
+ "item",
406
+ inferValueType(
407
+ present.flatMap((value) => value),
408
+ declaration.list
409
+ ),
410
+ true
411
+ )
412
+ );
413
+ }
414
+ if (declaration) {
415
+ const declaredTypes = {
416
+ boolean: new import_apache_arrow.Bool(),
417
+ int: new import_apache_arrow.Int32(),
418
+ long: new import_apache_arrow.Int64(),
419
+ float: new import_apache_arrow.Float32(),
420
+ double: new import_apache_arrow.Float64(),
421
+ string: new import_apache_arrow.Utf8()
422
+ };
423
+ const valid = present.every((value) => {
424
+ switch (declaration) {
425
+ case "boolean":
426
+ return typeof value === "boolean";
427
+ case "int":
428
+ return typeof value === "number" && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;
429
+ case "long":
430
+ return typeof value === "bigint" && value >= -(2n ** 63n) && value < 2n ** 63n;
431
+ case "float":
432
+ case "double":
433
+ return typeof value === "number";
434
+ case "string":
435
+ return typeof value === "string";
436
+ }
437
+ });
438
+ return valid ? declaredTypes[declaration] : new import_apache_arrow.Utf8();
439
+ }
440
+ if (present.length && present.every((value) => typeof value === "boolean")) return new import_apache_arrow.Bool();
441
+ if (present.length && present.every((value) => typeof value === "number")) return new import_apache_arrow.Float64();
442
+ if (present.length && present.every((value) => Array.isArray(value))) {
443
+ return new import_apache_arrow.List(
444
+ new import_apache_arrow.Field("item", inferValueType(present.flatMap((value) => value)), true)
445
+ );
446
+ }
447
+ if (present.length && present.every((value) => typeof value === "object" && !Array.isArray(value))) {
448
+ return inferAttributeType(present);
449
+ }
450
+ return new import_apache_arrow.Utf8();
451
+ }
452
+ function normalizeValue(value, type) {
453
+ if (value === null || value === void 0) return null;
454
+ if (type instanceof import_apache_arrow.Struct) {
455
+ return Object.fromEntries(
456
+ type.children.map((field) => [
457
+ field.name,
458
+ normalizeValue(value[field.name], field.type)
459
+ ])
460
+ );
461
+ }
462
+ if (type instanceof import_apache_arrow.List)
463
+ return value.map((item) => normalizeValue(item, type.valueType));
464
+ if (type instanceof import_apache_arrow.Utf8 && typeof value !== "string") {
465
+ return typeof value === "object" ? JSON.stringify(value) : String(value);
466
+ }
467
+ return value;
468
+ }
469
+ var import_apache_arrow;
470
+ var init_build_graph_tables = __esm({
471
+ "src/lib/build-graph-tables.ts"() {
472
+ "use strict";
473
+ import_apache_arrow = require("apache-arrow");
474
+ init_src();
475
+ }
56
476
  });
57
- function parseGraphML(graphml) {
477
+
478
+ // src/lib/parse-graphml.ts
479
+ function parseGraphML(graphml, shape = "plain-graph-data") {
58
480
  const xmlText = decodeGraphML(graphml);
59
481
  const document = graphmlParser.parse(xmlText);
60
482
  const graphmlRoot = getGraphMLRoot(document);
@@ -65,17 +487,38 @@ function parseGraphML(graphml) {
65
487
  if (!graphElement) {
66
488
  throw new Error("GraphML document does not contain a <graph> element.");
67
489
  }
68
- const keyDefinitions = collectKeyDefinitions(graphmlRoot, graphElement);
490
+ const keyDefinitions = collectKeyDefinitions(
491
+ graphmlRoot,
492
+ graphElement,
493
+ shape !== "plain-graph-data"
494
+ );
69
495
  const defaultDirected = parseEdgeDefault(graphElement[`${XML_ATTRIBUTE_PREFIX}edgedefault`]);
70
- const nodes = normalizeArray(graphElement.node).map((node) => parseNode(node, keyDefinitions));
71
- const edges = normalizeArray(graphElement.edge).map((edge, index) => parseEdge(edge, index, keyDefinitions, defaultDirected));
72
- const filteredNodes = nodes.filter((node) => Boolean(node));
73
- const filteredEdges = edges.filter((edge) => Boolean(edge));
74
- return {
75
- shape: "plain-graph-data",
76
- nodes: filteredNodes,
77
- edges: filteredEdges
78
- };
496
+ const declarations = { nodes: /* @__PURE__ */ new Map(), edges: /* @__PURE__ */ new Map() };
497
+ for (const definition of keyDefinitions.values()) {
498
+ if (definition.domain === "all" || definition.domain === "node")
499
+ declarations.nodes.set(definition.name, definition.type);
500
+ if (definition.domain === "all" || definition.domain === "edge")
501
+ declarations.edges.set(definition.name, definition.type);
502
+ }
503
+ return buildGraphTables(
504
+ iterateNodes(graphElement.node, keyDefinitions),
505
+ iterateEdges(graphElement.edge, keyDefinitions, defaultDirected),
506
+ shape,
507
+ declarations
508
+ );
509
+ }
510
+ function* iterateNodes(nodes, definitions) {
511
+ for (const node of normalizeArray(nodes)) {
512
+ const record = parseNode(node, definitions);
513
+ if (record) yield record;
514
+ }
515
+ }
516
+ function* iterateEdges(edges, definitions, directed) {
517
+ let index = 0;
518
+ for (const edge of normalizeArray(edges)) {
519
+ const record = parseEdge(edge, index++, definitions, directed);
520
+ if (record) yield record;
521
+ }
79
522
  }
80
523
  function decodeGraphML(graphml) {
81
524
  if (typeof graphml === "string") {
@@ -98,16 +541,21 @@ function getGraphMLRoot(document) {
98
541
  }
99
542
  function getGraphElement(graphmlRoot) {
100
543
  const graph = graphmlRoot.graph;
544
+ if (typeof graph === "string" && !graph.trim()) {
545
+ return {};
546
+ }
101
547
  if (!graph) {
102
548
  return null;
103
549
  }
104
550
  if (Array.isArray(graph)) {
105
- const firstGraph = graph.find((entry) => isObject(entry));
106
- return isObject(firstGraph) ? firstGraph : null;
551
+ const firstGraph = graph.find(
552
+ (entry) => isObject(entry) || typeof entry === "string" && !entry.trim()
553
+ );
554
+ return isObject(firstGraph) ? firstGraph : typeof firstGraph === "string" ? {} : null;
107
555
  }
108
556
  return isObject(graph) ? graph : null;
109
557
  }
110
- function collectKeyDefinitions(graphmlRoot, graphElement) {
558
+ function collectKeyDefinitions(graphmlRoot, graphElement, lossless) {
111
559
  const keys = /* @__PURE__ */ new Map();
112
560
  for (const candidate of [
113
561
  ...normalizeArray(graphmlRoot.key),
@@ -120,8 +568,8 @@ function collectKeyDefinitions(graphmlRoot, graphElement) {
120
568
  const name = String(candidate[`${XML_ATTRIBUTE_PREFIX}attr.name`] ?? id).trim();
121
569
  const type = normalizeType(candidate[`${XML_ATTRIBUTE_PREFIX}attr.type`]);
122
570
  const defaultNode = candidate.default ?? null;
123
- const defaultValue = defaultNode !== null ? castDataValue(defaultNode, type) : void 0;
124
- keys.set(id, { id, domain, name, type, defaultValue });
571
+ const defaultValue = defaultNode !== null ? castDataValue(defaultNode, type, lossless) : void 0;
572
+ keys.set(id, { id, domain, name, type, defaultValue, lossless });
125
573
  }
126
574
  }
127
575
  }
@@ -199,12 +647,12 @@ function assignAttributeFromDataEntry(entry, keyDefinitions, attributes) {
199
647
  }
200
648
  const definition = keyDefinitions.get(keyId);
201
649
  const attributeName = (definition == null ? void 0 : definition.name) ?? keyId;
202
- const value = castDataValue(entry, (definition == null ? void 0 : definition.type) ?? "string");
650
+ const value = (definition == null ? void 0 : definition.type) === "boolean" && extractTextContent(entry) === void 0 ? false : castDataValue(entry, (definition == null ? void 0 : definition.type) ?? "string", definition == null ? void 0 : definition.lossless);
203
651
  if (value !== void 0) {
204
652
  attributes[attributeName] = value;
205
653
  }
206
654
  }
207
- function castDataValue(value, type) {
655
+ function castDataValue(value, type, lossless = false) {
208
656
  if (value === null || typeof value === "undefined") {
209
657
  return void 0;
210
658
  }
@@ -215,6 +663,9 @@ function castDataValue(value, type) {
215
663
  if (type === "boolean") {
216
664
  return parseBoolean(text);
217
665
  }
666
+ if (type === "long" && lossless) {
667
+ return /^[+-]?\d+$/.test(text.trim()) ? BigInt(text.trim()) : text;
668
+ }
218
669
  if (type === "int" || type === "long") {
219
670
  const parsed = Number.parseInt(text, 10);
220
671
  return Number.isNaN(parsed) ? text : parsed;
@@ -237,12 +688,14 @@ function extractTextContent(value) {
237
688
  }
238
689
  if (isObject(value)) {
239
690
  const text = value[XML_TEXT_KEY];
240
- if (typeof text === "string") {
241
- return text;
242
- }
243
- const nonAttributeEntries = Object.entries(value).filter(([key]) => !key.startsWith(XML_ATTRIBUTE_PREFIX));
691
+ const nonAttributeEntries = Object.entries(value).filter(
692
+ ([key]) => !key.startsWith(XML_ATTRIBUTE_PREFIX) && key !== XML_TEXT_KEY
693
+ );
244
694
  if (nonAttributeEntries.length === 0) {
245
- return void 0;
695
+ return typeof text === "string" ? text : void 0;
696
+ }
697
+ if (typeof text === "string" && text.trim()) {
698
+ nonAttributeEntries.push([XML_TEXT_KEY, text]);
246
699
  }
247
700
  return JSON.stringify(Object.fromEntries(nonAttributeEntries));
248
701
  }
@@ -303,51 +756,116 @@ function parseBoolean(value) {
303
756
  if (normalized === "false" || normalized === "0" || normalized === "no" || normalized === "n") {
304
757
  return false;
305
758
  }
306
- return Boolean(value);
759
+ return Boolean(normalized);
307
760
  }
761
+ var import_fast_xml_parser, XML_ATTRIBUTE_PREFIX, XML_TEXT_KEY, graphmlParser;
762
+ var init_parse_graphml = __esm({
763
+ "src/lib/parse-graphml.ts"() {
764
+ "use strict";
765
+ import_fast_xml_parser = require("fast-xml-parser");
766
+ init_build_graph_tables();
767
+ XML_ATTRIBUTE_PREFIX = "@_";
768
+ XML_TEXT_KEY = "#text";
769
+ graphmlParser = new import_fast_xml_parser.XMLParser({
770
+ ignoreAttributes: false,
771
+ attributeNamePrefix: XML_ATTRIBUTE_PREFIX,
772
+ textNodeName: XML_TEXT_KEY,
773
+ trimValues: false,
774
+ parseAttributeValue: false,
775
+ parseTagValue: false,
776
+ removeNSPrefix: true
777
+ });
778
+ }
779
+ });
308
780
 
309
- // dist/graphml-loader.js
310
- var GraphMLLoaderWithParser = {
311
- ...GraphMLLoader,
312
- parse: async (data) => parseGraphML(data),
313
- parseSync: parseGraphML,
314
- parseTextSync: parseGraphML
315
- };
781
+ // src/graphml-loader.ts
782
+ var graphml_loader_exports = {};
783
+ __export(graphml_loader_exports, {
784
+ GraphMLLoaderWithParser: () => GraphMLLoaderWithParser
785
+ });
786
+ var GraphMLLoaderWithParser;
787
+ var init_graphml_loader = __esm({
788
+ "src/graphml-loader.ts"() {
789
+ "use strict";
790
+ init_graphml_loader_types();
791
+ init_parse_graphml();
792
+ GraphMLLoaderWithParser = {
793
+ ...GraphMLLoader,
794
+ parse: async (data, options) => {
795
+ var _a;
796
+ return parseGraphML(data, ((_a = options == null ? void 0 : options.graphml) == null ? void 0 : _a.shape) ?? "arrow-table");
797
+ },
798
+ parseSync: (data, options) => {
799
+ var _a;
800
+ return parseGraphML(data, ((_a = options == null ? void 0 : options.graphml) == null ? void 0 : _a.shape) ?? "arrow-table");
801
+ },
802
+ parseTextSync: (data, options) => {
803
+ var _a;
804
+ return parseGraphML(data, ((_a = options == null ? void 0 : options.graphml) == null ? void 0 : _a.shape) ?? "arrow-table");
805
+ }
806
+ };
807
+ }
808
+ });
316
809
 
317
- // dist/dot-loader-types.js
318
- var VERSION2 = true ? "4.5.3" : "latest";
319
- var DOTLoader = {
320
- name: "DOT",
321
- id: "dot",
322
- module: "graphs",
323
- version: VERSION2,
324
- extensions: ["dot", "gv"],
325
- mimeTypes: ["text/vnd.graphviz", "text/x-graphviz", "application/vnd.graphviz"],
326
- text: true,
327
- worker: false,
328
- dataType: null,
329
- batchType: null,
330
- options: {}
331
- };
810
+ // src/dot-loader-types.ts
811
+ async function preload3() {
812
+ const { DOTLoaderWithParser: DOTLoaderWithParser2 } = await Promise.resolve().then(() => (init_dot_loader(), dot_loader_exports));
813
+ return DOTLoaderWithParser2;
814
+ }
815
+ var VERSION3, DOTLoader;
816
+ var init_dot_loader_types = __esm({
817
+ "src/dot-loader-types.ts"() {
818
+ "use strict";
819
+ VERSION3 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
820
+ DOTLoader = {
821
+ name: "DOT",
822
+ id: "dot",
823
+ module: "graphs",
824
+ version: VERSION3,
825
+ extensions: ["dot", "gv"],
826
+ mimeTypes: ["text/vnd.graphviz", "text/x-graphviz", "application/vnd.graphviz"],
827
+ text: true,
828
+ worker: false,
829
+ dataType: null,
830
+ batchType: null,
831
+ options: { dot: { shape: "arrow-table" } },
832
+ preload: preload3
833
+ };
834
+ }
835
+ });
332
836
 
333
- // dist/lib/parse-dot.js
334
- function parseDOT(input) {
837
+ // src/lib/parse-dot.ts
838
+ function parseDOT(input, shape = "plain-graph-data") {
335
839
  const parsed = parseDOTDocument(input);
336
- const subgraphs = Array.from(parsed.subgraphs.values(), (subgraph) => ({
337
- ...subgraph,
338
- attributes: { ...subgraph.attributes }
339
- }));
340
840
  return {
341
- shape: "plain-graph-data",
342
- nodes: Array.from(parsed.nodes.values(), (node) => ({
841
+ ...buildGraphTables(iterateNodes2(parsed), iterateEdges2(parsed), shape),
842
+ metadata: {
843
+ id: parsed.id,
844
+ directed: parsed.directed,
845
+ strict: parsed.strict,
846
+ attributes: { ...parsed.graphAttributes },
847
+ subgraphs: Array.from(parsed.subgraphs.values(), (subgraph) => ({
848
+ ...subgraph,
849
+ attributes: { ...subgraph.attributes }
850
+ }))
851
+ }
852
+ };
853
+ }
854
+ function* iterateNodes2(parsed) {
855
+ for (const node of parsed.nodes.values()) {
856
+ yield {
343
857
  id: node.id,
344
858
  ...typeof node.attributes.label === "string" ? { label: node.attributes.label } : {},
345
859
  attributes: {
346
860
  ...node.attributes,
347
861
  ...node.subgraphs.size ? { subgraphs: Array.from(node.subgraphs, (id) => describeSubgraph(id, parsed.subgraphs)) } : {}
348
862
  }
349
- })),
350
- edges: parsed.edges.map((edge) => ({
863
+ };
864
+ }
865
+ }
866
+ function* iterateEdges2(parsed) {
867
+ for (const edge of parsed.edges) {
868
+ yield {
351
869
  id: edge.id,
352
870
  sourceId: edge.sourceId,
353
871
  targetId: edge.targetId,
@@ -357,15 +875,8 @@ function parseDOT(input) {
357
875
  ...edge.attributes,
358
876
  ...edge.subgraphs.length ? { subgraphs: edge.subgraphs.map((id) => describeSubgraph(id, parsed.subgraphs)) } : {}
359
877
  }
360
- })),
361
- metadata: {
362
- id: parsed.id,
363
- directed: parsed.directed,
364
- strict: parsed.strict,
365
- attributes: { ...parsed.graphAttributes },
366
- subgraphs
367
- }
368
- };
878
+ };
879
+ }
369
880
  }
370
881
  function describeSubgraph(id, descriptors) {
371
882
  const subgraph = descriptors.get(id);
@@ -375,373 +886,10 @@ function describeSubgraph(id, descriptors) {
375
886
  parentId: subgraph.parentId
376
887
  };
377
888
  }
378
- var DOTParser = class {
379
- /** Tokens for DOT parsing. */
380
- tokens;
381
- /** Position for DOT parsing. */
382
- position = 0;
383
- /** Accumulated graph records and attributes. */
384
- result = {
385
- directed: false,
386
- strict: false,
387
- graphAttributes: /* @__PURE__ */ Object.create(null),
388
- nodes: /* @__PURE__ */ new Map(),
389
- edges: [],
390
- subgraphs: /* @__PURE__ */ new Map()
391
- };
392
- /** Scopes for DOT parsing. */
393
- scopes = [
394
- {
395
- nodeDefaults: /* @__PURE__ */ Object.create(null),
396
- edgeDefaults: /* @__PURE__ */ Object.create(null),
397
- graphAttributes: /* @__PURE__ */ Object.create(null)
398
- }
399
- ];
400
- /** Subgraph counter for DOT parsing. */
401
- subgraphCounter = 0;
402
- /** Edge counter for DOT parsing. */
403
- edgeCounter = 0;
404
- /** Edge lookup used to coalesce parallel edges in strict graphs. */
405
- strictEdges = /* @__PURE__ */ new Map();
406
- /** Persistent attributes and defaults for reopened named subgraphs. */
407
- subgraphScopes = /* @__PURE__ */ new Map();
408
- /** Explicit names reserved so anonymous subgraph IDs cannot collide with them. */
409
- namedSubgraphIds = /* @__PURE__ */ new Set();
410
- /** Initializes the token stream. */
411
- constructor(tokens) {
412
- this.tokens = tokens;
413
- for (let index = 0; index < tokens.length - 1; index++) {
414
- if (isKeyword(tokens[index], "subgraph") && isIdentifierLike(tokens[index + 1])) {
415
- this.namedSubgraphIds.add(tokens[index + 1].value);
416
- }
417
- }
418
- }
419
- /** Parses one complete DOT document. */
420
- parse() {
421
- this.parseGraph();
422
- this.consumeOptionalSemicolon();
423
- if (this.peek()) {
424
- throw new Error("Unexpected content after DOT graph.");
425
- }
426
- return this.result;
427
- }
428
- /** Reads graph identity, declaration, and statements. */
429
- parseGraph() {
430
- const strictToken = this.peek();
431
- if (strictToken && isKeyword(strictToken, "strict")) {
432
- this.consume();
433
- this.result.strict = true;
434
- }
435
- const typeToken = this.peek();
436
- if (!typeToken || !isGraphType(typeToken)) {
437
- throw new Error("DOT graph must start with graph or digraph keyword.");
438
- }
439
- this.consume();
440
- this.result.directed = isKeyword(typeToken, "digraph");
441
- const idToken = this.peek();
442
- if (idToken && isIdentifierLike(idToken)) {
443
- this.result.id = parseIdentifierValue(this.consume());
444
- }
445
- this.expect("lbrace");
446
- while (!this.match("rbrace")) {
447
- if (!this.parseStatement()) {
448
- throw new Error("Expected closing brace in DOT graph.");
449
- }
450
- }
451
- this.result.graphAttributes = { ...this.scopes[0].graphAttributes };
452
- }
453
- /** Dispatches a graph statement. */
454
- parseStatement() {
455
- if (this.consumeSemicolonIfPresent()) {
456
- return true;
457
- }
458
- const token = this.peek();
459
- if (!token) {
460
- return false;
461
- }
462
- if (this.tryParseSubgraphStatement(token)) {
463
- return true;
464
- }
465
- if (this.tryParseKeywordStatement(token)) {
466
- return true;
467
- }
468
- if (this.tryParseAssignmentStatement(token)) {
469
- return true;
470
- }
471
- if (isIdentifierLike(token)) {
472
- this.parseNodeOrEdgeStatement();
473
- this.consumeOptionalSemicolon();
474
- return true;
475
- }
476
- throw new Error(`Unexpected token: ${token.value}`);
477
- }
478
- /** Consumes an empty statement. */
479
- consumeSemicolonIfPresent() {
480
- const next = this.peek();
481
- if ((next == null ? void 0 : next.type) === "semicolon") {
482
- this.consume();
483
- return true;
484
- }
485
- return false;
486
- }
487
- /** Reads a standalone subgraph statement. */
488
- tryParseSubgraphStatement(token) {
489
- if (token.type !== "lbrace" && !isKeyword(token, "subgraph")) {
490
- return false;
491
- }
492
- this.parseSubgraph();
493
- return true;
494
- }
495
- /** Applies graph, node, or edge defaults. */
496
- tryParseKeywordStatement(token) {
497
- if (!(isKeyword(token, "graph") || isKeyword(token, "node") || isKeyword(token, "edge"))) {
498
- return false;
499
- }
500
- this.consume();
501
- const explicitAttributes = this.parseAttributeList();
502
- if (isKeyword(token, "graph")) {
503
- Object.assign(this.currentScope().graphAttributes, explicitAttributes);
504
- } else if (isKeyword(token, "node")) {
505
- Object.assign(this.currentScope().nodeDefaults, explicitAttributes);
506
- } else {
507
- Object.assign(this.currentScope().edgeDefaults, explicitAttributes);
508
- }
509
- this.consumeOptionalSemicolon();
510
- return true;
511
- }
512
- /** Reads a graph attribute assignment. */
513
- tryParseAssignmentStatement(token) {
514
- if (!isIdentifierLike(token)) {
515
- return false;
516
- }
517
- const next = this.peek(1);
518
- if ((next == null ? void 0 : next.type) !== "equals") {
519
- return false;
520
- }
521
- const key = parseIdentifierValue(this.consume());
522
- this.consume();
523
- const valueToken = this.consume();
524
- const value = parseAttributeValue(valueToken);
525
- this.currentScope().graphAttributes[key] = value;
526
- this.consumeOptionalSemicolon();
527
- return true;
528
- }
529
- /** Reads a node statement or chained edges. */
530
- parseNodeOrEdgeStatement() {
531
- const first = parseIdentifierValue(this.consume());
532
- const references = [first];
533
- const operators = [];
534
- let operatorToken = this.match("arrow");
535
- while (operatorToken) {
536
- operators.push(operatorToken.value);
537
- const referenceToken = this.consume();
538
- if (!isIdentifierLike(referenceToken)) {
539
- throw new Error("Expected node identifier in edge statement.");
540
- }
541
- references.push(parseIdentifierValue(referenceToken));
542
- operatorToken = this.match("arrow");
543
- }
544
- if (operators.length === 0) {
545
- const explicitAttributes2 = this.parseAttributeList();
546
- this.addNode(first, explicitAttributes2);
547
- return;
548
- }
549
- const explicitAttributes = this.parseAttributeList();
550
- this.addEdgeChain(references, operators, explicitAttributes);
551
- }
552
- /** Merges explicit attributes into a node. */
553
- addNode(id, explicitAttributes) {
554
- const membership = this.getCurrentSubgraphChain();
555
- const node = this.ensureNode(id, membership);
556
- node.attributes = { ...node.attributes, ...explicitAttributes };
557
- }
558
- /** Expands an edge chain into node and edge records. */
559
- addEdgeChain(nodes, operators, explicitAttributes) {
560
- const membership = this.getCurrentSubgraphChain();
561
- const defaults = this.currentScope().edgeDefaults;
562
- const attributes = { ...defaults, ...explicitAttributes };
563
- for (let index = 0; index < nodes.length - 1; index++) {
564
- const sourceId = nodes[index];
565
- const targetId = nodes[index + 1];
566
- const operator = operators[index];
567
- const directed = operator === "->";
568
- if (directed !== this.result.directed) {
569
- throw new Error("DOT edge operator must match graph or digraph declaration.");
570
- }
571
- const edgeId = deriveEdgeId(attributes, sourceId, targetId, ++this.edgeCounter);
572
- const edgeAttributes = { ...attributes };
573
- this.ensureNode(sourceId, membership);
574
- this.ensureNode(targetId, membership);
575
- const strictKey = JSON.stringify(directed ? [sourceId, targetId] : [sourceId, targetId].sort());
576
- const existingEdge = this.result.strict ? this.strictEdges.get(strictKey) : void 0;
577
- if (existingEdge) {
578
- existingEdge.attributes = { ...existingEdge.attributes, ...explicitAttributes };
579
- existingEdge.directed = deriveDirectedFlag(existingEdge.attributes, directed);
580
- existingEdge.subgraphs = Array.from(/* @__PURE__ */ new Set([...existingEdge.subgraphs, ...membership]));
581
- continue;
582
- }
583
- const directedOverride = deriveDirectedFlag(edgeAttributes, directed);
584
- const edge = {
585
- id: edgeId,
586
- sourceId,
587
- targetId,
588
- directed: directedOverride,
589
- attributes: edgeAttributes,
590
- subgraphs: membership
591
- };
592
- this.result.edges.push(edge);
593
- if (this.result.strict) {
594
- this.strictEdges.set(strictKey, edge);
595
- }
596
- }
597
- }
598
- /** Reads a nested scope with inherited defaults. */
599
- parseSubgraph() {
600
- let idToken = this.peek();
601
- let subgraphId;
602
- if (idToken && isKeyword(idToken, "subgraph")) {
603
- this.consume();
604
- idToken = this.peek();
605
- }
606
- if (idToken && isIdentifierLike(idToken)) {
607
- subgraphId = parseIdentifierValue(this.consume());
608
- } else {
609
- do {
610
- subgraphId = `subgraph_${++this.subgraphCounter}`;
611
- } while (this.namedSubgraphIds.has(subgraphId));
612
- }
613
- this.expect("lbrace");
614
- const parentId = this.findCurrentSubgraphId();
615
- let context = this.subgraphScopes.get(subgraphId);
616
- if (!context) {
617
- context = {
618
- id: subgraphId,
619
- nodeDefaults: Object.assign(/* @__PURE__ */ Object.create(null), this.currentScope().nodeDefaults),
620
- edgeDefaults: Object.assign(/* @__PURE__ */ Object.create(null), this.currentScope().edgeDefaults),
621
- graphAttributes: /* @__PURE__ */ Object.create(null)
622
- };
623
- this.subgraphScopes.set(subgraphId, context);
624
- this.result.subgraphs.set(subgraphId, {
625
- id: subgraphId,
626
- attributes: context.graphAttributes,
627
- parentId
628
- });
629
- }
630
- this.scopes.push(context);
631
- let shouldContinue = true;
632
- while (shouldContinue) {
633
- if (this.match("rbrace")) {
634
- break;
635
- }
636
- shouldContinue = this.parseStatement();
637
- if (!shouldContinue) {
638
- throw new Error("Expected closing brace in DOT subgraph.");
639
- }
640
- }
641
- this.scopes.pop();
642
- }
643
- /** Reads repeated attribute lists. */
644
- parseAttributeList() {
645
- var _a, _b;
646
- const attributes = /* @__PURE__ */ Object.create(null);
647
- while (this.match("lbrack")) {
648
- while (!this.match("rbrack")) {
649
- const keyToken = this.consume();
650
- if (!isIdentifierLike(keyToken)) {
651
- throw new Error("Expected attribute name.");
652
- }
653
- const key = parseIdentifierValue(keyToken);
654
- let value = true;
655
- if (this.match("equals")) {
656
- const valueToken = this.consume();
657
- value = parseAttributeValue(valueToken);
658
- }
659
- attributes[key] = value;
660
- if (((_a = this.peek()) == null ? void 0 : _a.type) === "comma" || ((_b = this.peek()) == null ? void 0 : _b.type) === "semicolon") {
661
- this.consume();
662
- }
663
- }
664
- }
665
- return attributes;
666
- }
667
- /** Creates an implicit node and records its subgraph memberships. */
668
- ensureNode(id, membership) {
669
- let node = this.result.nodes.get(id);
670
- if (!node) {
671
- const defaults = this.currentScope().nodeDefaults;
672
- node = { id, attributes: { ...defaults }, subgraphs: /* @__PURE__ */ new Set() };
673
- this.result.nodes.set(id, node);
674
- }
675
- membership.forEach((subgraphId) => node.subgraphs.add(subgraphId));
676
- return node;
677
- }
678
- /** Lists enclosing subgraphs. */
679
- getCurrentSubgraphChain() {
680
- const chain = [];
681
- for (const scope of this.scopes) {
682
- if (scope.id) {
683
- chain.push(scope.id);
684
- }
685
- }
686
- return chain;
687
- }
688
- /** Finds the nearest enclosing named or generated subgraph. */
689
- findCurrentSubgraphId() {
690
- for (let index = this.scopes.length - 1; index >= 0; index--) {
691
- const scope = this.scopes[index];
692
- if (scope.id) {
693
- return scope.id;
694
- }
695
- }
696
- return void 0;
697
- }
698
- /** Returns the active attribute scope. */
699
- currentScope() {
700
- return this.scopes[this.scopes.length - 1];
701
- }
702
- /** Consumes an optional statement terminator. */
703
- consumeOptionalSemicolon() {
704
- const next = this.peek();
705
- if ((next == null ? void 0 : next.type) === "semicolon") {
706
- this.consume();
707
- }
708
- }
709
- /** Requires the next token to have the requested type. */
710
- expect(type) {
711
- const token = this.consume();
712
- if (!token || token.type !== type) {
713
- throw new Error(`Expected token ${type}.`);
714
- }
715
- return token;
716
- }
717
- /** Consumes the next token or reports truncated input. */
718
- consume() {
719
- const token = this.tokens[this.position];
720
- if (!token) {
721
- throw new Error("Unexpected end of DOT input.");
722
- }
723
- this.position++;
724
- return token;
725
- }
726
- /** Consumes a token when its type matches. */
727
- match(type) {
728
- const token = this.peek();
729
- if (token && token.type === type) {
730
- this.position++;
731
- return token;
732
- }
733
- return null;
734
- }
735
- /** Inspects a token without consuming it. */
736
- peek(offset = 0) {
737
- return this.tokens[this.position + offset] ?? null;
738
- }
739
- };
740
889
  function parseDOTDocument(input) {
741
- const parser = new DOTParser(tokenize(input));
742
- return parser.parse();
890
+ const parser2 = new DOTParser(tokenize(input));
891
+ return parser2.parse();
743
892
  }
744
- var IDENTIFIER_TERMINATORS = /* @__PURE__ */ new Set(["{", "}", "[", "]", "=", ";", ",", '"', "<", "#"]);
745
893
  function tokenize(input) {
746
894
  const tokens = [];
747
895
  let index = 0;
@@ -880,6 +1028,10 @@ function readQuotedString(input, startIndex) {
880
1028
  function readEscapedCharacter(input, startIndex) {
881
1029
  const next = input[startIndex];
882
1030
  switch (next) {
1031
+ case "\n":
1032
+ return { value: "", nextIndex: startIndex + 1 };
1033
+ case "\r":
1034
+ return { value: "", nextIndex: startIndex + (input[startIndex + 1] === "\n" ? 2 : 1) };
883
1035
  case "n":
884
1036
  case "l":
885
1037
  case "L":
@@ -896,7 +1048,7 @@ function readEscapedCharacter(input, startIndex) {
896
1048
  if (typeof next === "undefined") {
897
1049
  throw new Error("Unterminated escape sequence in DOT source.");
898
1050
  }
899
- return { value: next, nextIndex: startIndex + 1 };
1051
+ return { value: `\\${next}`, nextIndex: startIndex + 1 };
900
1052
  }
901
1053
  }
902
1054
  }
@@ -1011,12 +1163,842 @@ function deriveDirectedFlag(attributes, defaultDirected) {
1011
1163
  }
1012
1164
  return defaultDirected;
1013
1165
  }
1166
+ var DOTParser, IDENTIFIER_TERMINATORS;
1167
+ var init_parse_dot = __esm({
1168
+ "src/lib/parse-dot.ts"() {
1169
+ "use strict";
1170
+ init_build_graph_tables();
1171
+ DOTParser = class {
1172
+ /** Tokens for DOT parsing. */
1173
+ tokens;
1174
+ /** Position for DOT parsing. */
1175
+ position = 0;
1176
+ /** Accumulated graph records and attributes. */
1177
+ result = {
1178
+ directed: false,
1179
+ strict: false,
1180
+ graphAttributes: /* @__PURE__ */ Object.create(null),
1181
+ nodes: /* @__PURE__ */ new Map(),
1182
+ edges: [],
1183
+ subgraphs: /* @__PURE__ */ new Map()
1184
+ };
1185
+ /** Scopes for DOT parsing. */
1186
+ scopes = [
1187
+ {
1188
+ nodeDefaults: /* @__PURE__ */ Object.create(null),
1189
+ edgeDefaults: /* @__PURE__ */ Object.create(null),
1190
+ graphAttributes: /* @__PURE__ */ Object.create(null)
1191
+ }
1192
+ ];
1193
+ /** Subgraph counter for DOT parsing. */
1194
+ subgraphCounter = 0;
1195
+ /** Edge counter for DOT parsing. */
1196
+ edgeCounter = 0;
1197
+ /** Edge lookup used to coalesce parallel edges in strict graphs. */
1198
+ strictEdges = /* @__PURE__ */ new Map();
1199
+ /** Persistent attributes and defaults for reopened named subgraphs. */
1200
+ subgraphScopes = /* @__PURE__ */ new Map();
1201
+ /** Explicit names reserved so anonymous subgraph IDs cannot collide with them. */
1202
+ namedSubgraphIds = /* @__PURE__ */ new Set();
1203
+ /** Initializes the token stream. */
1204
+ constructor(tokens) {
1205
+ this.tokens = tokens;
1206
+ for (let index = 0; index < tokens.length - 1; index++) {
1207
+ if (isKeyword(tokens[index], "subgraph") && isIdentifierLike(tokens[index + 1])) {
1208
+ this.namedSubgraphIds.add(tokens[index + 1].value);
1209
+ }
1210
+ }
1211
+ }
1212
+ /** Parses one complete DOT document. */
1213
+ parse() {
1214
+ this.parseGraph();
1215
+ this.consumeOptionalSemicolon();
1216
+ if (this.peek()) {
1217
+ throw new Error("Unexpected content after DOT graph.");
1218
+ }
1219
+ return this.result;
1220
+ }
1221
+ /** Reads graph identity, declaration, and statements. */
1222
+ parseGraph() {
1223
+ const strictToken = this.peek();
1224
+ if (strictToken && isKeyword(strictToken, "strict")) {
1225
+ this.consume();
1226
+ this.result.strict = true;
1227
+ }
1228
+ const typeToken = this.peek();
1229
+ if (!typeToken || !isGraphType(typeToken)) {
1230
+ throw new Error("DOT graph must start with graph or digraph keyword.");
1231
+ }
1232
+ this.consume();
1233
+ this.result.directed = isKeyword(typeToken, "digraph");
1234
+ const idToken = this.peek();
1235
+ if (idToken && isIdentifierLike(idToken)) {
1236
+ this.result.id = parseIdentifierValue(this.consume());
1237
+ }
1238
+ this.expect("lbrace");
1239
+ while (!this.match("rbrace")) {
1240
+ if (!this.parseStatement()) {
1241
+ throw new Error("Expected closing brace in DOT graph.");
1242
+ }
1243
+ }
1244
+ this.result.graphAttributes = { ...this.scopes[0].graphAttributes };
1245
+ }
1246
+ /** Dispatches a graph statement. */
1247
+ parseStatement() {
1248
+ if (this.consumeSemicolonIfPresent()) {
1249
+ return true;
1250
+ }
1251
+ const token = this.peek();
1252
+ if (!token) {
1253
+ return false;
1254
+ }
1255
+ if (this.tryParseSubgraphStatement(token)) {
1256
+ return true;
1257
+ }
1258
+ if (this.tryParseKeywordStatement(token)) {
1259
+ return true;
1260
+ }
1261
+ if (this.tryParseAssignmentStatement(token)) {
1262
+ return true;
1263
+ }
1264
+ if (isIdentifierLike(token)) {
1265
+ this.parseNodeOrEdgeStatement();
1266
+ this.consumeOptionalSemicolon();
1267
+ return true;
1268
+ }
1269
+ throw new Error(`Unexpected token: ${token.value}`);
1270
+ }
1271
+ /** Consumes an empty statement. */
1272
+ consumeSemicolonIfPresent() {
1273
+ const next = this.peek();
1274
+ if ((next == null ? void 0 : next.type) === "semicolon") {
1275
+ this.consume();
1276
+ return true;
1277
+ }
1278
+ return false;
1279
+ }
1280
+ /** Reads a standalone subgraph statement. */
1281
+ tryParseSubgraphStatement(token) {
1282
+ if (token.type !== "lbrace" && !isKeyword(token, "subgraph")) {
1283
+ return false;
1284
+ }
1285
+ this.parseSubgraph();
1286
+ return true;
1287
+ }
1288
+ /** Applies graph, node, or edge defaults. */
1289
+ tryParseKeywordStatement(token) {
1290
+ if (!(isKeyword(token, "graph") || isKeyword(token, "node") || isKeyword(token, "edge"))) {
1291
+ return false;
1292
+ }
1293
+ this.consume();
1294
+ const explicitAttributes = this.parseAttributeList();
1295
+ if (isKeyword(token, "graph")) {
1296
+ Object.assign(this.currentScope().graphAttributes, explicitAttributes);
1297
+ } else if (isKeyword(token, "node")) {
1298
+ Object.assign(this.currentScope().nodeDefaults, explicitAttributes);
1299
+ } else {
1300
+ Object.assign(this.currentScope().edgeDefaults, explicitAttributes);
1301
+ }
1302
+ this.consumeOptionalSemicolon();
1303
+ return true;
1304
+ }
1305
+ /** Reads a graph attribute assignment. */
1306
+ tryParseAssignmentStatement(token) {
1307
+ if (!isIdentifierLike(token)) {
1308
+ return false;
1309
+ }
1310
+ const next = this.peek(1);
1311
+ if ((next == null ? void 0 : next.type) !== "equals") {
1312
+ return false;
1313
+ }
1314
+ const key = parseIdentifierValue(this.consume());
1315
+ this.consume();
1316
+ const valueToken = this.consume();
1317
+ const value = parseAttributeValue(valueToken);
1318
+ this.currentScope().graphAttributes[key] = value;
1319
+ this.consumeOptionalSemicolon();
1320
+ return true;
1321
+ }
1322
+ /** Reads a node statement or chained edges. */
1323
+ parseNodeOrEdgeStatement() {
1324
+ const first = parseIdentifierValue(this.consume());
1325
+ const references = [first];
1326
+ const operators = [];
1327
+ let operatorToken = this.match("arrow");
1328
+ while (operatorToken) {
1329
+ operators.push(operatorToken.value);
1330
+ const referenceToken = this.consume();
1331
+ if (!isIdentifierLike(referenceToken)) {
1332
+ throw new Error("Expected node identifier in edge statement.");
1333
+ }
1334
+ references.push(parseIdentifierValue(referenceToken));
1335
+ operatorToken = this.match("arrow");
1336
+ }
1337
+ if (operators.length === 0) {
1338
+ const explicitAttributes2 = this.parseAttributeList();
1339
+ this.addNode(first, explicitAttributes2);
1340
+ return;
1341
+ }
1342
+ const explicitAttributes = this.parseAttributeList();
1343
+ this.addEdgeChain(references, operators, explicitAttributes);
1344
+ }
1345
+ /** Merges explicit attributes into a node. */
1346
+ addNode(id, explicitAttributes) {
1347
+ const membership = this.getCurrentSubgraphChain();
1348
+ const node = this.ensureNode(id, membership);
1349
+ node.attributes = { ...node.attributes, ...explicitAttributes };
1350
+ }
1351
+ /** Expands an edge chain into node and edge records. */
1352
+ addEdgeChain(nodes, operators, explicitAttributes) {
1353
+ const membership = this.getCurrentSubgraphChain();
1354
+ const defaults = this.currentScope().edgeDefaults;
1355
+ const attributes = { ...defaults, ...explicitAttributes };
1356
+ for (let index = 0; index < nodes.length - 1; index++) {
1357
+ const sourceId = nodes[index];
1358
+ const targetId = nodes[index + 1];
1359
+ const operator = operators[index];
1360
+ const directed = operator === "->";
1361
+ if (directed !== this.result.directed) {
1362
+ throw new Error("DOT edge operator must match graph or digraph declaration.");
1363
+ }
1364
+ const edgeId = deriveEdgeId(attributes, sourceId, targetId, ++this.edgeCounter);
1365
+ const edgeAttributes = { ...attributes };
1366
+ this.ensureNode(sourceId, membership);
1367
+ this.ensureNode(targetId, membership);
1368
+ const strictKey = JSON.stringify(
1369
+ directed ? [sourceId, targetId] : [sourceId, targetId].sort()
1370
+ );
1371
+ const existingEdge = this.result.strict ? this.strictEdges.get(strictKey) : void 0;
1372
+ if (existingEdge) {
1373
+ existingEdge.attributes = { ...existingEdge.attributes, ...explicitAttributes };
1374
+ const explicitId = explicitAttributes.id ?? explicitAttributes.Id ?? explicitAttributes.ID;
1375
+ if (typeof explicitId === "string" || typeof explicitId === "number") {
1376
+ existingEdge.id = String(explicitId);
1377
+ }
1378
+ existingEdge.directed = deriveDirectedFlag(existingEdge.attributes, directed);
1379
+ existingEdge.subgraphs = Array.from(/* @__PURE__ */ new Set([...existingEdge.subgraphs, ...membership]));
1380
+ continue;
1381
+ }
1382
+ const directedOverride = deriveDirectedFlag(edgeAttributes, directed);
1383
+ const edge = {
1384
+ id: edgeId,
1385
+ sourceId,
1386
+ targetId,
1387
+ directed: directedOverride,
1388
+ attributes: edgeAttributes,
1389
+ subgraphs: membership
1390
+ };
1391
+ this.result.edges.push(edge);
1392
+ if (this.result.strict) {
1393
+ this.strictEdges.set(strictKey, edge);
1394
+ }
1395
+ }
1396
+ }
1397
+ /** Reads a nested scope with inherited defaults. */
1398
+ parseSubgraph() {
1399
+ let idToken = this.peek();
1400
+ let subgraphId;
1401
+ if (idToken && isKeyword(idToken, "subgraph")) {
1402
+ this.consume();
1403
+ idToken = this.peek();
1404
+ }
1405
+ if (idToken && isIdentifierLike(idToken)) {
1406
+ subgraphId = parseIdentifierValue(this.consume());
1407
+ } else {
1408
+ do {
1409
+ subgraphId = `subgraph_${++this.subgraphCounter}`;
1410
+ } while (this.namedSubgraphIds.has(subgraphId));
1411
+ }
1412
+ this.expect("lbrace");
1413
+ const parentId = this.findCurrentSubgraphId();
1414
+ let context = this.subgraphScopes.get(subgraphId);
1415
+ if (!context) {
1416
+ context = {
1417
+ id: subgraphId,
1418
+ nodeDefaults: Object.assign(/* @__PURE__ */ Object.create(null), this.currentScope().nodeDefaults),
1419
+ edgeDefaults: Object.assign(/* @__PURE__ */ Object.create(null), this.currentScope().edgeDefaults),
1420
+ graphAttributes: /* @__PURE__ */ Object.create(null)
1421
+ };
1422
+ this.subgraphScopes.set(subgraphId, context);
1423
+ this.result.subgraphs.set(subgraphId, {
1424
+ id: subgraphId,
1425
+ attributes: context.graphAttributes,
1426
+ parentId
1427
+ });
1428
+ }
1429
+ this.scopes.push(context);
1430
+ let shouldContinue = true;
1431
+ while (shouldContinue) {
1432
+ if (this.match("rbrace")) {
1433
+ break;
1434
+ }
1435
+ shouldContinue = this.parseStatement();
1436
+ if (!shouldContinue) {
1437
+ throw new Error("Expected closing brace in DOT subgraph.");
1438
+ }
1439
+ }
1440
+ this.scopes.pop();
1441
+ }
1442
+ /** Reads repeated attribute lists. */
1443
+ parseAttributeList() {
1444
+ var _a, _b;
1445
+ const attributes = /* @__PURE__ */ Object.create(null);
1446
+ while (this.match("lbrack")) {
1447
+ while (!this.match("rbrack")) {
1448
+ const keyToken = this.consume();
1449
+ if (!isIdentifierLike(keyToken)) {
1450
+ throw new Error("Expected attribute name.");
1451
+ }
1452
+ const key = parseIdentifierValue(keyToken);
1453
+ let value = true;
1454
+ if (this.match("equals")) {
1455
+ const valueToken = this.consume();
1456
+ value = parseAttributeValue(valueToken);
1457
+ }
1458
+ attributes[key] = value;
1459
+ if (((_a = this.peek()) == null ? void 0 : _a.type) === "comma" || ((_b = this.peek()) == null ? void 0 : _b.type) === "semicolon") {
1460
+ this.consume();
1461
+ }
1462
+ }
1463
+ }
1464
+ return attributes;
1465
+ }
1466
+ /** Creates an implicit node and records its subgraph memberships. */
1467
+ ensureNode(id, membership) {
1468
+ let node = this.result.nodes.get(id);
1469
+ if (!node) {
1470
+ const defaults = this.currentScope().nodeDefaults;
1471
+ node = { id, attributes: { ...defaults }, subgraphs: /* @__PURE__ */ new Set() };
1472
+ this.result.nodes.set(id, node);
1473
+ }
1474
+ membership.forEach((subgraphId) => node.subgraphs.add(subgraphId));
1475
+ return node;
1476
+ }
1477
+ /** Lists enclosing subgraphs. */
1478
+ getCurrentSubgraphChain() {
1479
+ const chain = [];
1480
+ for (const scope of this.scopes) {
1481
+ if (scope.id) {
1482
+ chain.push(scope.id);
1483
+ }
1484
+ }
1485
+ return chain;
1486
+ }
1487
+ /** Finds the nearest enclosing named or generated subgraph. */
1488
+ findCurrentSubgraphId() {
1489
+ for (let index = this.scopes.length - 1; index >= 0; index--) {
1490
+ const scope = this.scopes[index];
1491
+ if (scope.id) {
1492
+ return scope.id;
1493
+ }
1494
+ }
1495
+ return void 0;
1496
+ }
1497
+ /** Returns the active attribute scope. */
1498
+ currentScope() {
1499
+ return this.scopes[this.scopes.length - 1];
1500
+ }
1501
+ /** Consumes an optional statement terminator. */
1502
+ consumeOptionalSemicolon() {
1503
+ const next = this.peek();
1504
+ if ((next == null ? void 0 : next.type) === "semicolon") {
1505
+ this.consume();
1506
+ }
1507
+ }
1508
+ /** Requires the next token to have the requested type. */
1509
+ expect(type) {
1510
+ const token = this.consume();
1511
+ if (!token || token.type !== type) {
1512
+ throw new Error(`Expected token ${type}.`);
1513
+ }
1514
+ return token;
1515
+ }
1516
+ /** Consumes the next token or reports truncated input. */
1517
+ consume() {
1518
+ const token = this.tokens[this.position];
1519
+ if (!token) {
1520
+ throw new Error("Unexpected end of DOT input.");
1521
+ }
1522
+ this.position++;
1523
+ return token;
1524
+ }
1525
+ /** Consumes a token when its type matches. */
1526
+ match(type) {
1527
+ const token = this.peek();
1528
+ if (token && token.type === type) {
1529
+ this.position++;
1530
+ return token;
1531
+ }
1532
+ return null;
1533
+ }
1534
+ /** Inspects a token without consuming it. */
1535
+ peek(offset = 0) {
1536
+ return this.tokens[this.position + offset] ?? null;
1537
+ }
1538
+ };
1539
+ IDENTIFIER_TERMINATORS = /* @__PURE__ */ new Set(["{", "}", "[", "]", "=", ";", ",", '"', "<", "#"]);
1540
+ }
1541
+ });
1542
+
1543
+ // src/dot-loader.ts
1544
+ var dot_loader_exports = {};
1545
+ __export(dot_loader_exports, {
1546
+ DOTLoaderWithParser: () => DOTLoaderWithParser
1547
+ });
1548
+ var DOTLoaderWithParser;
1549
+ var init_dot_loader = __esm({
1550
+ "src/dot-loader.ts"() {
1551
+ "use strict";
1552
+ init_dot_loader_types();
1553
+ init_parse_dot();
1554
+ DOTLoaderWithParser = {
1555
+ ...DOTLoader,
1556
+ parse: async (data, options) => {
1557
+ var _a;
1558
+ return parseDOT(new TextDecoder().decode(data), ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
1559
+ },
1560
+ parseSync: (data, options) => {
1561
+ var _a;
1562
+ return parseDOT(new TextDecoder().decode(data), ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
1563
+ },
1564
+ parseTextSync: (data, options) => {
1565
+ var _a;
1566
+ return parseDOT(data, ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
1567
+ }
1568
+ };
1569
+ }
1570
+ });
1571
+
1572
+ // src/gexf-loader-types.ts
1573
+ async function preload5() {
1574
+ const { GEXFLoaderWithParser: GEXFLoaderWithParser2 } = await Promise.resolve().then(() => (init_gexf_loader(), gexf_loader_exports));
1575
+ return GEXFLoaderWithParser2;
1576
+ }
1577
+ var VERSION5, GEXFLoader;
1578
+ var init_gexf_loader_types = __esm({
1579
+ "src/gexf-loader-types.ts"() {
1580
+ "use strict";
1581
+ VERSION5 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
1582
+ GEXFLoader = {
1583
+ name: "GEXF",
1584
+ id: "gexf",
1585
+ module: "graphs",
1586
+ version: VERSION5,
1587
+ extensions: ["gexf"],
1588
+ mimeTypes: ["application/gexf+xml"],
1589
+ text: true,
1590
+ worker: false,
1591
+ dataType: null,
1592
+ batchType: null,
1593
+ options: { gexf: { shape: "arrow-table" } },
1594
+ preload: preload5
1595
+ };
1596
+ }
1597
+ });
1014
1598
 
1015
- // dist/dot-loader.js
1016
- var DOTLoaderWithParser = {
1017
- ...DOTLoader,
1018
- parse: async (data) => parseDOT(new TextDecoder().decode(data)),
1019
- parseSync: (data) => parseDOT(new TextDecoder().decode(data)),
1020
- parseTextSync: parseDOT
1599
+ // src/lib/parse-gexf.ts
1600
+ function parseGEXF(input, shape = "arrow-table") {
1601
+ const text = typeof input === "string" ? input : new TextDecoder().decode(input);
1602
+ const validation = import_fast_xml_parser2.XMLValidator.validate(text);
1603
+ if (validation !== true) throw new Error(`Invalid GEXF XML: ${validation.err.msg}`);
1604
+ if (/<!DOCTYPE\s/i.test(text)) throw new Error("GEXF document types are unsupported.");
1605
+ const document = normalizeNamespaces(parser.parse(text), {});
1606
+ const root = getElement(document.gexf, "gexf");
1607
+ const version = root["@_version"];
1608
+ if (version && !["1.2", "1.2draft", "1.3"].includes(version)) {
1609
+ throw new Error(`Unsupported GEXF version: ${version}`);
1610
+ }
1611
+ const graph = getElement(root.graph, "graph");
1612
+ const directed = parseDirection(graph["@_defaultedgetype"] ?? "undirected");
1613
+ const definitions = {
1614
+ nodes: /* @__PURE__ */ new Map(),
1615
+ edges: /* @__PURE__ */ new Map()
1616
+ };
1617
+ for (const attributes of getElements(graph.attributes)) {
1618
+ const domain = attributes["@_class"];
1619
+ if (domain !== "node" && domain !== "edge")
1620
+ throw new Error("GEXF attributes require a node or edge class.");
1621
+ const scoped = domain === "node" ? definitions.nodes : definitions.edges;
1622
+ const names = new Set(Array.from(scoped.values(), (definition) => definition.name));
1623
+ for (const attribute of getElements(attributes.attribute)) {
1624
+ const identifier = requireAttribute(attribute, "id");
1625
+ const name = requireAttribute(attribute, "title");
1626
+ if (name === "gexf" || names.has(name) || scoped.has(identifier)) {
1627
+ throw new Error(`Duplicate or reserved GEXF attribute: ${name}`);
1628
+ }
1629
+ names.add(name);
1630
+ const type = parseAttributeType(requireAttribute(attribute, "type"));
1631
+ scoped.set(identifier, {
1632
+ name,
1633
+ type,
1634
+ defaultValue: attribute.default === void 0 ? void 0 : castValue(readTextContent(attribute.default), type)
1635
+ });
1636
+ }
1637
+ }
1638
+ const nodeElements = getElements(getContainer(graph.nodes).node);
1639
+ const edgeElements = getElements(getContainer(graph.edges).edge);
1640
+ const nodeIdentifiers = /* @__PURE__ */ new Set();
1641
+ for (const node of nodeElements) {
1642
+ const identifier = requireAttribute(node, "id");
1643
+ if (nodeIdentifiers.has(identifier)) throw new Error(`Duplicate GEXF node ID: ${identifier}`);
1644
+ nodeIdentifiers.add(identifier);
1645
+ }
1646
+ const edgeIdentifiers = new Set(
1647
+ edgeElements.map((edge) => edge["@_id"]).filter((identifier) => typeof identifier === "string")
1648
+ );
1649
+ const seenEdges = /* @__PURE__ */ new Set();
1650
+ function* iterateNodes3() {
1651
+ for (const node of nodeElements) yield parseRecord(node, definitions.nodes);
1652
+ }
1653
+ function* iterateEdges3() {
1654
+ for (const [index, edge] of edgeElements.entries()) {
1655
+ const sourceId = requireAttribute(edge, "source");
1656
+ const targetId = requireAttribute(edge, "target");
1657
+ if (!nodeIdentifiers.has(sourceId) || !nodeIdentifiers.has(targetId)) {
1658
+ throw new Error("GEXF edge references an undeclared node.");
1659
+ }
1660
+ let identifier = edge["@_id"] === void 0 ? void 0 : requireAttribute(edge, "id");
1661
+ if (identifier === void 0) {
1662
+ identifier = `edge-${index}`;
1663
+ while (edgeIdentifiers.has(identifier)) identifier = `_${identifier}`;
1664
+ edgeIdentifiers.add(identifier);
1665
+ }
1666
+ if (seenEdges.has(identifier)) throw new Error(`Duplicate GEXF edge ID: ${identifier}`);
1667
+ seenEdges.add(identifier);
1668
+ yield {
1669
+ ...parseRecord(edge, definitions.edges, identifier),
1670
+ sourceId,
1671
+ targetId,
1672
+ directed: edge["@_type"] === void 0 ? directed : parseDirection(edge["@_type"])
1673
+ };
1674
+ }
1675
+ }
1676
+ const metadataAttributes = /* @__PURE__ */ Object.create(null);
1677
+ const meta = getContainer(root.meta);
1678
+ for (const name of ["creator", "description", "keywords"]) {
1679
+ if (meta[name] !== void 0) metadataAttributes[name] = readTextContent(meta[name]);
1680
+ }
1681
+ if (typeof meta["@_lastmodifieddate"] === "string")
1682
+ metadataAttributes.lastmodifieddate = meta["@_lastmodifieddate"];
1683
+ const declarations = {
1684
+ nodes: new Map(
1685
+ Array.from(definitions.nodes.values(), (definition) => [definition.name, definition.type])
1686
+ ),
1687
+ edges: new Map(
1688
+ Array.from(definitions.edges.values(), (definition) => [definition.name, definition.type])
1689
+ )
1690
+ };
1691
+ return {
1692
+ ...buildGraphTables(iterateNodes3(), iterateEdges3(), shape, declarations),
1693
+ metadata: { version, directed, attributes: metadataAttributes }
1694
+ };
1695
+ }
1696
+ function normalizeNamespaces(element, inherited) {
1697
+ const namespaces = Object.assign(/* @__PURE__ */ Object.create(null), inherited);
1698
+ for (const [name, value] of Object.entries(element)) {
1699
+ if (name === "@_xmlns") namespaces[""] = String(value);
1700
+ else if (name.startsWith("@_xmlns:")) namespaces[name.slice(8)] = String(value);
1701
+ }
1702
+ const normalized = /* @__PURE__ */ Object.create(null);
1703
+ for (const [name, value] of Object.entries(element)) {
1704
+ if (name.startsWith("@_") || name === "#text" || name.startsWith("?")) {
1705
+ normalized[name] = value;
1706
+ continue;
1707
+ }
1708
+ const separator = name.indexOf(":");
1709
+ const prefix = separator < 0 ? "" : name.slice(0, separator);
1710
+ const localName = name.slice(separator + 1);
1711
+ const children = Array.isArray(value) ? value : [value];
1712
+ for (const child of children) {
1713
+ const object = typeof child === "object" && child !== null ? child : {};
1714
+ const namespace = object[prefix ? `@_xmlns:${prefix}` : "@_xmlns"] ?? namespaces[prefix];
1715
+ const match = typeof namespace === "string" ? GEXF_NAMESPACE.exec(namespace) : null;
1716
+ const key = match ? `${match[1] ? "viz:" : ""}${localName}` : namespace || prefix ? `foreign:${name}` : localName;
1717
+ const childValue = typeof child === "object" && child !== null ? match || !namespace && !prefix ? normalizeNamespaces(object, namespaces) : object : child;
1718
+ if (normalized[key] === void 0) normalized[key] = childValue;
1719
+ else
1720
+ normalized[key] = [
1721
+ ...Array.isArray(normalized[key]) ? normalized[key] : [normalized[key]],
1722
+ childValue
1723
+ ];
1724
+ }
1725
+ }
1726
+ assertStaticElement(normalized);
1727
+ return normalized;
1728
+ }
1729
+ function assertStaticElement(element) {
1730
+ if (element["@_mode"] !== void 0 && element["@_mode"] !== "static" || TEMPORAL_ATTRIBUTES.some((name) => element[`@_${name}`] !== void 0) || element.spells !== void 0) {
1731
+ throw new Error("Dynamic GEXF graphs and temporal values are unsupported.");
1732
+ }
1733
+ if (element["@_pid"] !== void 0 || element.parents !== void 0 || element["@_id"] !== void 0 && (element.nodes !== void 0 || element.edges !== void 0)) {
1734
+ throw new Error("Hierarchical GEXF graphs are unsupported.");
1735
+ }
1736
+ }
1737
+ function getElement(value, name) {
1738
+ if (value === "") return {};
1739
+ if (value && typeof value === "object" && !Array.isArray(value)) return value;
1740
+ throw new Error(`GEXF requires one <${name}> element.`);
1741
+ }
1742
+ function readTextContent(value) {
1743
+ if (typeof value === "string") return value;
1744
+ const text = getElement(value, "text")["#text"];
1745
+ return typeof text === "string" ? text : "";
1746
+ }
1747
+ function getContainer(value) {
1748
+ return value === void 0 ? {} : getElement(value, "container");
1749
+ }
1750
+ function getElements(value) {
1751
+ if (value === void 0) return [];
1752
+ return (Array.isArray(value) ? value : [value]).map((entry) => getElement(entry, "record"));
1753
+ }
1754
+ function requireAttribute(element, name) {
1755
+ const value = element[`@_${name}`];
1756
+ if (typeof value !== "string" || value === "")
1757
+ throw new Error(`GEXF requires a ${name} attribute.`);
1758
+ return value;
1759
+ }
1760
+ function parseDirection(value) {
1761
+ if (value !== "directed" && value !== "undirected")
1762
+ throw new Error(`Unsupported GEXF edge type: ${String(value)}`);
1763
+ return value === "directed";
1764
+ }
1765
+ function parseAttributeType(value) {
1766
+ if (value.startsWith("list") && !value.slice(4).startsWith("list")) {
1767
+ return { list: parseAttributeType(value.slice(4)) };
1768
+ }
1769
+ if (value === "integer" || value === "byte" || value === "short") return "int";
1770
+ if (value === "boolean" || value === "long" || value === "float" || value === "double")
1771
+ return value;
1772
+ if (["string", "anyURI", "date", "char", "bigdecimal", "biginteger"].includes(value))
1773
+ return "string";
1774
+ throw new Error(`Unsupported GEXF attribute type: ${value}`);
1775
+ }
1776
+ function castValue(text, type) {
1777
+ if (typeof type === "object") {
1778
+ return parseListValues(text).map((value) => castValue(value, type.list));
1779
+ }
1780
+ if (type === "string") return text;
1781
+ const trimmed = text.trim();
1782
+ if (type === "boolean") {
1783
+ if (trimmed === "true" || trimmed === "1") return true;
1784
+ if (trimmed === "false" || trimmed === "0") return false;
1785
+ return text;
1786
+ }
1787
+ if (type === "int" || type === "long") {
1788
+ if (!/^[+-]?\d+$/.test(trimmed)) return text;
1789
+ return type === "long" ? BigInt(trimmed) : Number.isSafeInteger(Number(trimmed)) ? Number(trimmed) : text;
1790
+ }
1791
+ if (trimmed === "INF") return Infinity;
1792
+ if (trimmed === "-INF") return -Infinity;
1793
+ if (trimmed === "NaN") return NaN;
1794
+ if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(trimmed)) return text;
1795
+ const number = Number(trimmed);
1796
+ const represented = type === "float" ? Math.fround(number) : number;
1797
+ const nonzero = /[1-9]/.test(trimmed.split(/[eE]/)[0]);
1798
+ return Number.isFinite(represented) && (represented !== 0 || !nonzero) ? number : text;
1799
+ }
1800
+ function parseListValues(text) {
1801
+ const trimmed = text.trim();
1802
+ const bracketed = trimmed.startsWith("[");
1803
+ if (bracketed !== trimmed.endsWith("]")) throw new Error("Invalid GEXF list brackets.");
1804
+ const contents = bracketed ? trimmed.slice(1, -1) : trimmed;
1805
+ if (!contents.trim()) return [];
1806
+ const values = [];
1807
+ let value = "";
1808
+ let quote = "";
1809
+ let quoted = false;
1810
+ let closed = false;
1811
+ for (let index = 0; index < contents.length; index++) {
1812
+ const character = contents[index];
1813
+ if (quote) {
1814
+ if (character === "\\" && (contents[index + 1] === quote || contents[index + 1] === "\\")) {
1815
+ value += contents[++index];
1816
+ } else if (character === quote) {
1817
+ quote = "";
1818
+ closed = true;
1819
+ } else value += character;
1820
+ } else if (character === "," || !bracketed && (character === "|" || character === ";")) {
1821
+ values.push(quoted ? value : value.trim());
1822
+ value = "";
1823
+ quoted = false;
1824
+ closed = false;
1825
+ } else if (closed) {
1826
+ if (character.trim()) throw new Error("Invalid GEXF list text after a quote.");
1827
+ } else if ((character === "'" || character === '"') && !value.trim()) {
1828
+ quote = character;
1829
+ quoted = true;
1830
+ value = "";
1831
+ } else value += character;
1832
+ }
1833
+ if (quote) throw new Error("Unterminated GEXF list quote.");
1834
+ values.push(quoted ? value : value.trim());
1835
+ return values;
1836
+ }
1837
+ function parseRecord(element, definitions, identifier) {
1838
+ const attributes = /* @__PURE__ */ Object.create(null);
1839
+ for (const definition of definitions.values()) {
1840
+ if (definition.defaultValue !== void 0)
1841
+ attributes[definition.name] = Array.isArray(definition.defaultValue) ? [...definition.defaultValue] : definition.defaultValue;
1842
+ }
1843
+ for (const attvalue of getElements(getContainer(element.attvalues).attvalue)) {
1844
+ const key = requireAttribute(attvalue, "for");
1845
+ const definition = definitions.get(key);
1846
+ if (!definition) throw new Error(`Undeclared GEXF attribute: ${key}`);
1847
+ attributes[definition.name] = castValue(requireValue(attvalue), definition.type);
1848
+ }
1849
+ const native = /* @__PURE__ */ Object.create(null);
1850
+ if (element["@_weight"] !== void 0)
1851
+ native.weight = castValue(String(element["@_weight"]), "double");
1852
+ if (element["@_kind"] !== void 0) native.kind = element["@_kind"];
1853
+ const visualization = /* @__PURE__ */ Object.create(null);
1854
+ for (const name of ["color", "position", "size", "shape", "thickness"]) {
1855
+ const value = element[`viz:${name}`];
1856
+ if (value === void 0) continue;
1857
+ const properties = /* @__PURE__ */ Object.create(null);
1858
+ for (const [key, property] of Object.entries(getElement(value, `viz:${name}`))) {
1859
+ if (key.startsWith("@_") && !key.startsWith("@_xmlns")) {
1860
+ const propertyName = key.slice(2);
1861
+ properties[propertyName] = ["r", "g", "b", "a", "x", "y", "z"].includes(propertyName) || propertyName === "value" && (name === "size" || name === "thickness") ? castValue(String(property), "double") : property;
1862
+ }
1863
+ }
1864
+ visualization[name] = properties;
1865
+ }
1866
+ if (Object.keys(visualization).length) native.viz = visualization;
1867
+ if (Object.keys(native).length) attributes.gexf = native;
1868
+ return {
1869
+ id: identifier ?? requireAttribute(element, "id"),
1870
+ label: element["@_label"],
1871
+ attributes
1872
+ };
1873
+ }
1874
+ function requireValue(element) {
1875
+ const value = element["@_value"];
1876
+ if (typeof value !== "string") throw new Error("GEXF attvalue requires a value attribute.");
1877
+ return value;
1878
+ }
1879
+ var import_fast_xml_parser2, parser, GEXF_NAMESPACE, TEMPORAL_ATTRIBUTES;
1880
+ var init_parse_gexf = __esm({
1881
+ "src/lib/parse-gexf.ts"() {
1882
+ "use strict";
1883
+ import_fast_xml_parser2 = require("fast-xml-parser");
1884
+ init_build_graph_tables();
1885
+ parser = new import_fast_xml_parser2.XMLParser({
1886
+ ignoreAttributes: false,
1887
+ parseAttributeValue: false,
1888
+ parseTagValue: false,
1889
+ trimValues: false
1890
+ });
1891
+ GEXF_NAMESPACE = /^https?:\/\/(?:www\.)?gexf.net\/1\.(?:2(?:draft)?|3)(\/viz)?$/;
1892
+ TEMPORAL_ATTRIBUTES = [
1893
+ "start",
1894
+ "end",
1895
+ "startopen",
1896
+ "endopen",
1897
+ "timestamp",
1898
+ "timestamps",
1899
+ "intervals"
1900
+ ];
1901
+ }
1902
+ });
1903
+
1904
+ // src/gexf-loader.ts
1905
+ var gexf_loader_exports = {};
1906
+ __export(gexf_loader_exports, {
1907
+ GEXFLoaderWithParser: () => GEXFLoaderWithParser
1908
+ });
1909
+ var GEXFLoaderWithParser;
1910
+ var init_gexf_loader = __esm({
1911
+ "src/gexf-loader.ts"() {
1912
+ "use strict";
1913
+ init_gexf_loader_types();
1914
+ init_parse_gexf();
1915
+ GEXFLoaderWithParser = {
1916
+ ...GEXFLoader,
1917
+ parse: async (data, options) => {
1918
+ var _a;
1919
+ return parseGEXF(data, ((_a = options == null ? void 0 : options.gexf) == null ? void 0 : _a.shape) ?? "arrow-table");
1920
+ },
1921
+ parseSync: (data, options) => {
1922
+ var _a;
1923
+ return parseGEXF(data, ((_a = options == null ? void 0 : options.gexf) == null ? void 0 : _a.shape) ?? "arrow-table");
1924
+ },
1925
+ parseTextSync: (data, options) => {
1926
+ var _a;
1927
+ return parseGEXF(data, ((_a = options == null ? void 0 : options.gexf) == null ? void 0 : _a.shape) ?? "arrow-table");
1928
+ }
1929
+ };
1930
+ }
1931
+ });
1932
+
1933
+ // dist/index.js
1934
+ var index_exports = {};
1935
+ __export(index_exports, {
1936
+ DOTLoader: () => DOTLoader2,
1937
+ GEXFLoader: () => GEXFLoader2,
1938
+ GraphMLLoader: () => GraphMLLoader2
1939
+ });
1940
+ module.exports = __toCommonJS(index_exports);
1941
+
1942
+ // dist/graphml-loader-types.js
1943
+ var VERSION2 = true ? "5.0.0-alpha.11" : "latest";
1944
+ async function preload2() {
1945
+ const { GraphMLLoaderWithParser: GraphMLLoaderWithParser2 } = await Promise.resolve().then(() => (init_graphml_loader(), graphml_loader_exports));
1946
+ return GraphMLLoaderWithParser2;
1947
+ }
1948
+ var GraphMLLoader2 = {
1949
+ name: "GraphML",
1950
+ id: "graphml",
1951
+ module: "graphs",
1952
+ version: VERSION2,
1953
+ extensions: ["graphml"],
1954
+ mimeTypes: ["application/graphml+xml"],
1955
+ text: true,
1956
+ worker: false,
1957
+ dataType: null,
1958
+ batchType: null,
1959
+ options: { graphml: { shape: "arrow-table" } },
1960
+ preload: preload2
1961
+ };
1962
+
1963
+ // dist/dot-loader-types.js
1964
+ var VERSION4 = true ? "5.0.0-alpha.11" : "latest";
1965
+ async function preload4() {
1966
+ const { DOTLoaderWithParser: DOTLoaderWithParser2 } = await Promise.resolve().then(() => (init_dot_loader(), dot_loader_exports));
1967
+ return DOTLoaderWithParser2;
1968
+ }
1969
+ var DOTLoader2 = {
1970
+ name: "DOT",
1971
+ id: "dot",
1972
+ module: "graphs",
1973
+ version: VERSION4,
1974
+ extensions: ["dot", "gv"],
1975
+ mimeTypes: ["text/vnd.graphviz", "text/x-graphviz", "application/vnd.graphviz"],
1976
+ text: true,
1977
+ worker: false,
1978
+ dataType: null,
1979
+ batchType: null,
1980
+ options: { dot: { shape: "arrow-table" } },
1981
+ preload: preload4
1982
+ };
1983
+
1984
+ // dist/gexf-loader-types.js
1985
+ var VERSION6 = true ? "5.0.0-alpha.11" : "latest";
1986
+ async function preload6() {
1987
+ const { GEXFLoaderWithParser: GEXFLoaderWithParser2 } = await Promise.resolve().then(() => (init_gexf_loader(), gexf_loader_exports));
1988
+ return GEXFLoaderWithParser2;
1989
+ }
1990
+ var GEXFLoader2 = {
1991
+ name: "GEXF",
1992
+ id: "gexf",
1993
+ module: "graphs",
1994
+ version: VERSION6,
1995
+ extensions: ["gexf"],
1996
+ mimeTypes: ["application/gexf+xml"],
1997
+ text: true,
1998
+ worker: false,
1999
+ dataType: null,
2000
+ batchType: null,
2001
+ options: { gexf: { shape: "arrow-table" } },
2002
+ preload: preload6
1021
2003
  };
1022
2004
  //# sourceMappingURL=index.cjs.map