@loaders.gl/graphs 5.0.0-alpha.9 → 5.0.0-beta.2

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 (84) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +123 -4
  3. package/THIRD-PARTY-NOTICES.md +17 -0
  4. package/dist/dot-loader-types.cjs +59 -0
  5. package/dist/dot-loader-types.cjs.map +7 -0
  6. package/dist/dot-loader-types.d.ts +25 -8
  7. package/dist/dot-loader-types.d.ts.map +1 -1
  8. package/dist/dot-loader-types.js +2 -2
  9. package/dist/dot-loader-types.js.map +1 -1
  10. package/dist/dot-loader.cjs +638 -47
  11. package/dist/dot-loader.cjs.map +3 -3
  12. package/dist/dot-loader.d.ts +10 -6
  13. package/dist/dot-loader.d.ts.map +1 -1
  14. package/dist/dot-loader.js +3 -3
  15. package/dist/dot-loader.js.map +1 -1
  16. package/dist/dot-types.d.ts +6 -1
  17. package/dist/dot-types.d.ts.map +1 -1
  18. package/dist/gexf-loader-types.cjs +59 -0
  19. package/dist/gexf-loader-types.cjs.map +7 -0
  20. package/dist/gexf-loader-types.d.ts +53 -0
  21. package/dist/gexf-loader-types.d.ts.map +1 -0
  22. package/dist/gexf-loader-types.js +26 -0
  23. package/dist/gexf-loader-types.js.map +1 -0
  24. package/dist/gexf-loader.cjs +2940 -0
  25. package/dist/gexf-loader.cjs.map +6 -0
  26. package/dist/gexf-loader.d.ts +24 -0
  27. package/dist/gexf-loader.d.ts.map +1 -0
  28. package/dist/gexf-loader.js +13 -0
  29. package/dist/gexf-loader.js.map +1 -0
  30. package/dist/gexf-types.d.ts +16 -0
  31. package/dist/gexf-types.d.ts.map +1 -0
  32. package/dist/gexf-types.js +5 -0
  33. package/dist/gexf-types.js.map +1 -0
  34. package/dist/graph-types.d.ts +28 -0
  35. package/dist/graph-types.d.ts.map +1 -1
  36. package/dist/graphml-loader-types.cjs +59 -0
  37. package/dist/graphml-loader-types.cjs.map +7 -0
  38. package/dist/graphml-loader-types.d.ts +24 -8
  39. package/dist/graphml-loader-types.d.ts.map +1 -1
  40. package/dist/graphml-loader-types.js +2 -2
  41. package/dist/graphml-loader-types.js.map +1 -1
  42. package/dist/graphml-loader.cjs +2303 -69
  43. package/dist/graphml-loader.cjs.map +3 -3
  44. package/dist/graphml-loader.d.ts +10 -6
  45. package/dist/graphml-loader.d.ts.map +1 -1
  46. package/dist/graphml-loader.js +3 -3
  47. package/dist/graphml-loader.js.map +1 -1
  48. package/dist/index.cjs +56 -1085
  49. package/dist/index.cjs.map +4 -3
  50. package/dist/index.d.ts +7 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +1 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/lib/build-graph-tables.d.ts +4 -0
  55. package/dist/lib/build-graph-tables.d.ts.map +1 -0
  56. package/dist/lib/build-graph-tables.js +143 -0
  57. package/dist/lib/build-graph-tables.js.map +1 -0
  58. package/dist/lib/parse-dot.d.ts +3 -1
  59. package/dist/lib/parse-dot.d.ts.map +1 -1
  60. package/dist/lib/parse-dot.js +38 -21
  61. package/dist/lib/parse-dot.js.map +1 -1
  62. package/dist/lib/parse-gexf.d.ts +5 -0
  63. package/dist/lib/parse-gexf.d.ts.map +1 -0
  64. package/dist/lib/parse-gexf.js +382 -0
  65. package/dist/lib/parse-gexf.js.map +1 -0
  66. package/dist/lib/parse-graphml.d.ts +2 -1
  67. package/dist/lib/parse-graphml.d.ts.map +1 -1
  68. package/dist/lib/parse-graphml.js +54 -31
  69. package/dist/lib/parse-graphml.js.map +1 -1
  70. package/package.json +18 -8
  71. package/src/dot-loader-types.ts +15 -5
  72. package/src/dot-loader.ts +7 -4
  73. package/src/dot-types.ts +7 -1
  74. package/src/gexf-loader-types.ts +41 -0
  75. package/src/gexf-loader.ts +17 -0
  76. package/src/gexf-types.ts +21 -0
  77. package/src/graph-types.ts +35 -0
  78. package/src/graphml-loader-types.ts +14 -5
  79. package/src/graphml-loader.ts +7 -4
  80. package/src/index.ts +9 -0
  81. package/src/lib/build-graph-tables.ts +208 -0
  82. package/src/lib/parse-dot.ts +44 -21
  83. package/src/lib/parse-gexf.ts +390 -0
  84. package/src/lib/parse-graphml.ts +92 -40
@@ -1,7 +1,9 @@
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;
6
8
  var __esm = (fn, res, err) => function __init() {
7
9
  if (err) throw err[0];
@@ -23,6 +25,14 @@ var __copyProps = (to, from, except, desc) => {
23
25
  }
24
26
  return to;
25
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
+ ));
26
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
37
 
28
38
  // src/dot-loader-types.ts
@@ -46,30 +56,457 @@ var init_dot_loader_types = __esm({
46
56
  worker: false,
47
57
  dataType: null,
48
58
  batchType: null,
49
- options: {},
59
+ options: { dot: { shape: "arrow-table" } },
50
60
  preload
51
61
  };
52
62
  }
53
63
  });
54
64
 
65
+ // ../core/src/schema-utils/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
+ "../core/src/schema-utils/lib/schema/convert-arrow-schema.ts"() {
320
+ "use strict";
321
+ arrow = __toESM(require("apache-arrow"), 1);
322
+ }
323
+ });
324
+
325
+ // ../core/src/schema-utils/index.ts
326
+ var init_schema_utils = __esm({
327
+ "../core/src/schema-utils/index.ts"() {
328
+ "use strict";
329
+ init_convert_arrow_schema();
330
+ }
331
+ });
332
+
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_schema_utils();
475
+ }
476
+ });
477
+
55
478
  // src/lib/parse-dot.ts
56
- function parseDOT(input) {
479
+ function parseDOT(input, shape = "plain-graph-data") {
57
480
  const parsed = parseDOTDocument(input);
58
- const subgraphs = Array.from(parsed.subgraphs.values(), (subgraph) => ({
59
- ...subgraph,
60
- attributes: { ...subgraph.attributes }
61
- }));
62
481
  return {
63
- shape: "plain-graph-data",
64
- nodes: Array.from(parsed.nodes.values(), (node) => ({
482
+ ...buildGraphTables(iterateNodes(parsed), iterateEdges(parsed), shape),
483
+ metadata: {
484
+ id: parsed.id,
485
+ directed: parsed.directed,
486
+ strict: parsed.strict,
487
+ attributes: { ...parsed.graphAttributes },
488
+ subgraphs: Array.from(parsed.subgraphs.values(), (subgraph) => ({
489
+ ...subgraph,
490
+ attributes: { ...subgraph.attributes }
491
+ }))
492
+ }
493
+ };
494
+ }
495
+ function* iterateNodes(parsed) {
496
+ for (const node of parsed.nodes.values()) {
497
+ yield {
65
498
  id: node.id,
66
499
  ...typeof node.attributes.label === "string" ? { label: node.attributes.label } : {},
67
500
  attributes: {
68
501
  ...node.attributes,
69
502
  ...node.subgraphs.size ? { subgraphs: Array.from(node.subgraphs, (id) => describeSubgraph(id, parsed.subgraphs)) } : {}
70
503
  }
71
- })),
72
- edges: parsed.edges.map((edge) => ({
504
+ };
505
+ }
506
+ }
507
+ function* iterateEdges(parsed) {
508
+ for (const edge of parsed.edges) {
509
+ yield {
73
510
  id: edge.id,
74
511
  sourceId: edge.sourceId,
75
512
  targetId: edge.targetId,
@@ -79,15 +516,8 @@ function parseDOT(input) {
79
516
  ...edge.attributes,
80
517
  ...edge.subgraphs.length ? { subgraphs: edge.subgraphs.map((id) => describeSubgraph(id, parsed.subgraphs)) } : {}
81
518
  }
82
- })),
83
- metadata: {
84
- id: parsed.id,
85
- directed: parsed.directed,
86
- strict: parsed.strict,
87
- attributes: { ...parsed.graphAttributes },
88
- subgraphs
89
- }
90
- };
519
+ };
520
+ }
91
521
  }
92
522
  function describeSubgraph(id, descriptors) {
93
523
  const subgraph = descriptors.get(id);
@@ -239,6 +669,10 @@ function readQuotedString(input, startIndex) {
239
669
  function readEscapedCharacter(input, startIndex) {
240
670
  const next = input[startIndex];
241
671
  switch (next) {
672
+ case "\n":
673
+ return { value: "", nextIndex: startIndex + 1 };
674
+ case "\r":
675
+ return { value: "", nextIndex: startIndex + (input[startIndex + 1] === "\n" ? 2 : 1) };
242
676
  case "n":
243
677
  case "l":
244
678
  case "L":
@@ -255,7 +689,7 @@ function readEscapedCharacter(input, startIndex) {
255
689
  if (typeof next === "undefined") {
256
690
  throw new Error("Unterminated escape sequence in DOT source.");
257
691
  }
258
- return { value: next, nextIndex: startIndex + 1 };
692
+ return { value: `\\${next}`, nextIndex: startIndex + 1 };
259
693
  }
260
694
  }
261
695
  }
@@ -374,6 +808,7 @@ var DOTParser, IDENTIFIER_TERMINATORS;
374
808
  var init_parse_dot = __esm({
375
809
  "src/lib/parse-dot.ts"() {
376
810
  "use strict";
811
+ init_build_graph_tables();
377
812
  DOTParser = class {
378
813
  /** Tokens for DOT parsing. */
379
814
  tokens;
@@ -577,6 +1012,10 @@ var init_parse_dot = __esm({
577
1012
  const existingEdge = this.result.strict ? this.strictEdges.get(strictKey) : void 0;
578
1013
  if (existingEdge) {
579
1014
  existingEdge.attributes = { ...existingEdge.attributes, ...explicitAttributes };
1015
+ const explicitId = explicitAttributes.id ?? explicitAttributes.Id ?? explicitAttributes.ID;
1016
+ if (typeof explicitId === "string" || typeof explicitId === "number") {
1017
+ existingEdge.id = String(explicitId);
1018
+ }
580
1019
  existingEdge.directed = deriveDirectedFlag(existingEdge.attributes, directed);
581
1020
  existingEdge.subgraphs = Array.from(/* @__PURE__ */ new Set([...existingEdge.subgraphs, ...membership]));
582
1021
  continue;
@@ -755,9 +1194,18 @@ var init_dot_loader = __esm({
755
1194
  init_parse_dot();
756
1195
  DOTLoaderWithParser = {
757
1196
  ...DOTLoader,
758
- parse: async (data) => parseDOT(new TextDecoder().decode(data)),
759
- parseSync: (data) => parseDOT(new TextDecoder().decode(data)),
760
- parseTextSync: parseDOT
1197
+ parse: async (data, options) => {
1198
+ var _a;
1199
+ return parseDOT(new TextDecoder().decode(data), ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
1200
+ },
1201
+ parseSync: (data, options) => {
1202
+ var _a;
1203
+ return parseDOT(new TextDecoder().decode(data), ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
1204
+ },
1205
+ parseTextSync: (data, options) => {
1206
+ var _a;
1207
+ return parseDOT(data, ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
1208
+ }
761
1209
  };
762
1210
  }
763
1211
  });
@@ -770,7 +1218,7 @@ __export(dot_loader_exports2, {
770
1218
  module.exports = __toCommonJS(dot_loader_exports2);
771
1219
 
772
1220
  // dist/dot-loader-types.js
773
- var VERSION2 = true ? "5.0.0-alpha.9" : "latest";
1221
+ var VERSION2 = true ? "5.0.0-beta.2" : "latest";
774
1222
  async function preload2() {
775
1223
  const { DOTLoaderWithParser: DOTLoaderWithParser3 } = await Promise.resolve().then(() => (init_dot_loader(), dot_loader_exports));
776
1224
  return DOTLoaderWithParser3;
@@ -786,28 +1234,161 @@ var DOTLoader2 = {
786
1234
  worker: false,
787
1235
  dataType: null,
788
1236
  batchType: null,
789
- options: {},
1237
+ options: { dot: { shape: "arrow-table" } },
790
1238
  preload: preload2
791
1239
  };
792
1240
 
1241
+ // dist/lib/build-graph-tables.js
1242
+ var import_apache_arrow2 = require("apache-arrow");
1243
+ init_schema_utils();
1244
+ function buildGraphTables2(nodes, edges, shape, declarations) {
1245
+ if (shape === "plain-graph-data") {
1246
+ return { shape, nodes: Array.from(nodes), edges: Array.from(edges) };
1247
+ }
1248
+ if (shape !== "arrow-table" && shape !== "object-row-table") {
1249
+ throw new Error(`Unsupported graph shape: ${shape}`);
1250
+ }
1251
+ const nodeTable = buildGraphTable2(nodes, false, shape, declarations == null ? void 0 : declarations.nodes);
1252
+ const edgeTable = buildGraphTable2(edges, true, shape, declarations == null ? void 0 : declarations.edges);
1253
+ return {
1254
+ shape: "tables",
1255
+ tables: [
1256
+ { name: "nodes", table: nodeTable },
1257
+ { name: "edges", table: edgeTable }
1258
+ ]
1259
+ };
1260
+ }
1261
+ function buildGraphTable2(records, isEdge, shape, declarations) {
1262
+ const columnNames = isEdge ? ["id", "sourceId", "targetId", "directed", "label", "attributes"] : ["id", "label", "attributes"];
1263
+ const columns = new Map(columnNames.map((name) => [name, []]));
1264
+ for (const record of records) {
1265
+ for (const name of columnNames) {
1266
+ const value = record[name];
1267
+ columns.get(name).push(name === "id" || name === "sourceId" || name === "targetId" ? String(value) : value ?? null);
1268
+ }
1269
+ }
1270
+ if (shape === "object-row-table") {
1271
+ return {
1272
+ shape,
1273
+ data: columns.get("id").map((_, index) => Object.fromEntries(columnNames.map((name) => [name, columns.get(name)[index]])))
1274
+ };
1275
+ }
1276
+ const vectors = /* @__PURE__ */ Object.create(null);
1277
+ for (const [name, values] of columns) {
1278
+ const type = name === "attributes" ? inferAttributeType2(values, declarations) : name === "directed" ? new import_apache_arrow2.Bool() : new import_apache_arrow2.Utf8();
1279
+ vectors[name] = (0, import_apache_arrow2.vectorFromArray)(values.map((value) => normalizeValue2(value, type)), type);
1280
+ }
1281
+ const data = new import_apache_arrow2.Table(vectors);
1282
+ return { shape, schema: convertArrowToSchema(data.schema), data };
1283
+ }
1284
+ function inferAttributeType2(values, declarations) {
1285
+ const names = new Set(declarations == null ? void 0 : declarations.keys());
1286
+ for (const value of values) {
1287
+ if (value && typeof value === "object") {
1288
+ for (const name of Object.keys(value)) {
1289
+ names.add(name);
1290
+ }
1291
+ }
1292
+ }
1293
+ return new import_apache_arrow2.Struct(Array.from(names, (name) => {
1294
+ const fieldValues = values.map((value) => (value == null ? void 0 : value[name]) ?? null);
1295
+ return new import_apache_arrow2.Field(name, inferValueType2(fieldValues, declarations == null ? void 0 : declarations.get(name)), true);
1296
+ }));
1297
+ }
1298
+ function inferValueType2(values, declaration) {
1299
+ const present = values.filter((value) => value !== null && value !== void 0);
1300
+ if (declaration && typeof declaration === "object") {
1301
+ if (!present.every((value) => Array.isArray(value)))
1302
+ return new import_apache_arrow2.Utf8();
1303
+ return new import_apache_arrow2.List(new import_apache_arrow2.Field("item", inferValueType2(present.flatMap((value) => value), declaration.list), true));
1304
+ }
1305
+ if (declaration) {
1306
+ const declaredTypes = {
1307
+ boolean: new import_apache_arrow2.Bool(),
1308
+ int: new import_apache_arrow2.Int32(),
1309
+ long: new import_apache_arrow2.Int64(),
1310
+ float: new import_apache_arrow2.Float32(),
1311
+ double: new import_apache_arrow2.Float64(),
1312
+ string: new import_apache_arrow2.Utf8()
1313
+ };
1314
+ const valid = present.every((value) => {
1315
+ switch (declaration) {
1316
+ case "boolean":
1317
+ return typeof value === "boolean";
1318
+ case "int":
1319
+ return typeof value === "number" && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647;
1320
+ case "long":
1321
+ return typeof value === "bigint" && value >= -(2n ** 63n) && value < 2n ** 63n;
1322
+ case "float":
1323
+ case "double":
1324
+ return typeof value === "number";
1325
+ case "string":
1326
+ return typeof value === "string";
1327
+ }
1328
+ });
1329
+ return valid ? declaredTypes[declaration] : new import_apache_arrow2.Utf8();
1330
+ }
1331
+ if (present.length && present.every((value) => typeof value === "boolean"))
1332
+ return new import_apache_arrow2.Bool();
1333
+ if (present.length && present.every((value) => typeof value === "number"))
1334
+ return new import_apache_arrow2.Float64();
1335
+ if (present.length && present.every((value) => Array.isArray(value))) {
1336
+ return new import_apache_arrow2.List(new import_apache_arrow2.Field("item", inferValueType2(present.flatMap((value) => value)), true));
1337
+ }
1338
+ if (present.length && present.every((value) => typeof value === "object" && !Array.isArray(value))) {
1339
+ return inferAttributeType2(present);
1340
+ }
1341
+ return new import_apache_arrow2.Utf8();
1342
+ }
1343
+ function normalizeValue2(value, type) {
1344
+ if (value === null || value === void 0)
1345
+ return null;
1346
+ if (type instanceof import_apache_arrow2.Struct) {
1347
+ return Object.fromEntries(type.children.map((field) => [
1348
+ field.name,
1349
+ normalizeValue2(value[field.name], field.type)
1350
+ ]));
1351
+ }
1352
+ if (type instanceof import_apache_arrow2.List)
1353
+ return value.map((item) => normalizeValue2(item, type.valueType));
1354
+ if (type instanceof import_apache_arrow2.Utf8 && typeof value !== "string") {
1355
+ return typeof value === "object" ? JSON.stringify(value) : String(value);
1356
+ }
1357
+ return value;
1358
+ }
1359
+
793
1360
  // dist/lib/parse-dot.js
794
- function parseDOT2(input) {
1361
+ function parseDOT2(input, shape = "plain-graph-data") {
795
1362
  const parsed = parseDOTDocument2(input);
796
- const subgraphs = Array.from(parsed.subgraphs.values(), (subgraph) => ({
797
- ...subgraph,
798
- attributes: { ...subgraph.attributes }
799
- }));
800
1363
  return {
801
- shape: "plain-graph-data",
802
- nodes: Array.from(parsed.nodes.values(), (node) => ({
1364
+ ...buildGraphTables2(iterateNodes2(parsed), iterateEdges2(parsed), shape),
1365
+ metadata: {
1366
+ id: parsed.id,
1367
+ directed: parsed.directed,
1368
+ strict: parsed.strict,
1369
+ attributes: { ...parsed.graphAttributes },
1370
+ subgraphs: Array.from(parsed.subgraphs.values(), (subgraph) => ({
1371
+ ...subgraph,
1372
+ attributes: { ...subgraph.attributes }
1373
+ }))
1374
+ }
1375
+ };
1376
+ }
1377
+ function* iterateNodes2(parsed) {
1378
+ for (const node of parsed.nodes.values()) {
1379
+ yield {
803
1380
  id: node.id,
804
1381
  ...typeof node.attributes.label === "string" ? { label: node.attributes.label } : {},
805
1382
  attributes: {
806
1383
  ...node.attributes,
807
1384
  ...node.subgraphs.size ? { subgraphs: Array.from(node.subgraphs, (id) => describeSubgraph2(id, parsed.subgraphs)) } : {}
808
1385
  }
809
- })),
810
- edges: parsed.edges.map((edge) => ({
1386
+ };
1387
+ }
1388
+ }
1389
+ function* iterateEdges2(parsed) {
1390
+ for (const edge of parsed.edges) {
1391
+ yield {
811
1392
  id: edge.id,
812
1393
  sourceId: edge.sourceId,
813
1394
  targetId: edge.targetId,
@@ -817,15 +1398,8 @@ function parseDOT2(input) {
817
1398
  ...edge.attributes,
818
1399
  ...edge.subgraphs.length ? { subgraphs: edge.subgraphs.map((id) => describeSubgraph2(id, parsed.subgraphs)) } : {}
819
1400
  }
820
- })),
821
- metadata: {
822
- id: parsed.id,
823
- directed: parsed.directed,
824
- strict: parsed.strict,
825
- attributes: { ...parsed.graphAttributes },
826
- subgraphs
827
- }
828
- };
1401
+ };
1402
+ }
829
1403
  }
830
1404
  function describeSubgraph2(id, descriptors) {
831
1405
  const subgraph = descriptors.get(id);
@@ -1036,6 +1610,10 @@ var DOTParser2 = class {
1036
1610
  const existingEdge = this.result.strict ? this.strictEdges.get(strictKey) : void 0;
1037
1611
  if (existingEdge) {
1038
1612
  existingEdge.attributes = { ...existingEdge.attributes, ...explicitAttributes };
1613
+ const explicitId = explicitAttributes.id ?? explicitAttributes.Id ?? explicitAttributes.ID;
1614
+ if (typeof explicitId === "string" || typeof explicitId === "number") {
1615
+ existingEdge.id = String(explicitId);
1616
+ }
1039
1617
  existingEdge.directed = deriveDirectedFlag2(existingEdge.attributes, directed);
1040
1618
  existingEdge.subgraphs = Array.from(/* @__PURE__ */ new Set([...existingEdge.subgraphs, ...membership]));
1041
1619
  continue;
@@ -1340,6 +1918,10 @@ function readQuotedString2(input, startIndex) {
1340
1918
  function readEscapedCharacter2(input, startIndex) {
1341
1919
  const next = input[startIndex];
1342
1920
  switch (next) {
1921
+ case "\n":
1922
+ return { value: "", nextIndex: startIndex + 1 };
1923
+ case "\r":
1924
+ return { value: "", nextIndex: startIndex + (input[startIndex + 1] === "\n" ? 2 : 1) };
1343
1925
  case "n":
1344
1926
  case "l":
1345
1927
  case "L":
@@ -1356,7 +1938,7 @@ function readEscapedCharacter2(input, startIndex) {
1356
1938
  if (typeof next === "undefined") {
1357
1939
  throw new Error("Unterminated escape sequence in DOT source.");
1358
1940
  }
1359
- return { value: next, nextIndex: startIndex + 1 };
1941
+ return { value: `\\${next}`, nextIndex: startIndex + 1 };
1360
1942
  }
1361
1943
  }
1362
1944
  }
@@ -1475,8 +2057,17 @@ function deriveDirectedFlag2(attributes, defaultDirected) {
1475
2057
  // dist/dot-loader.js
1476
2058
  var DOTLoaderWithParser2 = {
1477
2059
  ...DOTLoader2,
1478
- parse: async (data) => parseDOT2(new TextDecoder().decode(data)),
1479
- parseSync: (data) => parseDOT2(new TextDecoder().decode(data)),
1480
- parseTextSync: parseDOT2
2060
+ parse: async (data, options) => {
2061
+ var _a;
2062
+ return parseDOT2(new TextDecoder().decode(data), ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
2063
+ },
2064
+ parseSync: (data, options) => {
2065
+ var _a;
2066
+ return parseDOT2(new TextDecoder().decode(data), ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
2067
+ },
2068
+ parseTextSync: (data, options) => {
2069
+ var _a;
2070
+ return parseDOT2(data, ((_a = options == null ? void 0 : options.dot) == null ? void 0 : _a.shape) ?? "arrow-table");
2071
+ }
1481
2072
  };
1482
2073
  //# sourceMappingURL=dot-loader.cjs.map