@graphty/graph-format 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -43
  3. package/dist/graph-format.d.ts +1 -0
  4. package/dist/graph-format.d.ts.map +1 -0
  5. package/dist/graph-format.js +15798 -0
  6. package/dist/graph-format.js.map +1 -0
  7. package/dist/src/builder/arena.d.ts +85 -0
  8. package/dist/src/builder/arena.d.ts.map +1 -0
  9. package/dist/src/builder/arena.js +154 -0
  10. package/dist/src/builder/arena.js.map +1 -0
  11. package/dist/src/builder/compact.d.ts +515 -0
  12. package/dist/src/builder/compact.d.ts.map +1 -0
  13. package/dist/src/builder/compact.js +1553 -0
  14. package/dist/src/builder/compact.js.map +1 -0
  15. package/dist/src/builder/counting-sort.d.ts +96 -0
  16. package/dist/src/builder/counting-sort.d.ts.map +1 -0
  17. package/dist/src/builder/counting-sort.js +430 -0
  18. package/dist/src/builder/counting-sort.js.map +1 -0
  19. package/dist/src/builder/freeze.d.ts +72 -0
  20. package/dist/src/builder/freeze.d.ts.map +1 -0
  21. package/dist/src/builder/freeze.js +548 -0
  22. package/dist/src/builder/freeze.js.map +1 -0
  23. package/dist/src/builder/graph-builder.d.ts +602 -0
  24. package/dist/src/builder/graph-builder.d.ts.map +1 -0
  25. package/dist/src/builder/graph-builder.js +1940 -0
  26. package/dist/src/builder/graph-builder.js.map +1 -0
  27. package/dist/src/builder/options.d.ts +16 -0
  28. package/dist/src/builder/options.d.ts.map +1 -0
  29. package/dist/src/builder/options.js +21 -0
  30. package/dist/src/builder/options.js.map +1 -0
  31. package/dist/src/columns/bitmap.d.ts +96 -0
  32. package/dist/src/columns/bitmap.d.ts.map +1 -0
  33. package/dist/src/columns/bitmap.js +184 -0
  34. package/dist/src/columns/bitmap.js.map +1 -0
  35. package/dist/src/columns/column.d.ts +220 -0
  36. package/dist/src/columns/column.d.ts.map +1 -0
  37. package/dist/src/columns/column.js +2109 -0
  38. package/dist/src/columns/column.js.map +1 -0
  39. package/dist/src/columns/dictionary.d.ts +60 -0
  40. package/dist/src/columns/dictionary.d.ts.map +1 -0
  41. package/dist/src/columns/dictionary.js +102 -0
  42. package/dist/src/columns/dictionary.js.map +1 -0
  43. package/dist/src/columns/growable.d.ts +198 -0
  44. package/dist/src/columns/growable.d.ts.map +1 -0
  45. package/dist/src/columns/growable.js +296 -0
  46. package/dist/src/columns/growable.js.map +1 -0
  47. package/dist/src/columns/infer.d.ts +121 -0
  48. package/dist/src/columns/infer.d.ts.map +1 -0
  49. package/dist/src/columns/infer.js +268 -0
  50. package/dist/src/columns/infer.js.map +1 -0
  51. package/dist/src/columns/remap.d.ts +143 -0
  52. package/dist/src/columns/remap.d.ts.map +1 -0
  53. package/dist/src/columns/remap.js +588 -0
  54. package/dist/src/columns/remap.js.map +1 -0
  55. package/dist/src/columns/table.d.ts +184 -0
  56. package/dist/src/columns/table.d.ts.map +1 -0
  57. package/dist/src/columns/table.js +485 -0
  58. package/dist/src/columns/table.js.map +1 -0
  59. package/dist/src/constants.d.ts +34 -0
  60. package/dist/src/constants.d.ts.map +1 -0
  61. package/dist/src/constants.js +79 -0
  62. package/dist/src/constants.js.map +1 -0
  63. package/dist/src/errors.d.ts +76 -0
  64. package/dist/src/errors.d.ts.map +1 -0
  65. package/dist/src/errors.js +32 -0
  66. package/dist/src/errors.js.map +1 -0
  67. package/dist/src/ids/edge-id-index.d.ts +77 -0
  68. package/dist/src/ids/edge-id-index.d.ts.map +1 -0
  69. package/dist/src/ids/edge-id-index.js +155 -0
  70. package/dist/src/ids/edge-id-index.js.map +1 -0
  71. package/dist/src/ids/node-id-map.d.ts +280 -0
  72. package/dist/src/ids/node-id-map.d.ts.map +1 -0
  73. package/dist/src/ids/node-id-map.js +1139 -0
  74. package/dist/src/ids/node-id-map.js.map +1 -0
  75. package/dist/src/ids/string-store.d.ts +219 -0
  76. package/dist/src/ids/string-store.d.ts.map +1 -0
  77. package/dist/src/ids/string-store.js +526 -0
  78. package/dist/src/ids/string-store.js.map +1 -0
  79. package/dist/src/index.d.ts +30 -0
  80. package/dist/src/index.d.ts.map +1 -0
  81. package/dist/src/index.js +29 -0
  82. package/dist/src/index.js.map +1 -0
  83. package/dist/src/populate/from-csr.d.ts +61 -0
  84. package/dist/src/populate/from-csr.d.ts.map +1 -0
  85. package/dist/src/populate/from-csr.js +706 -0
  86. package/dist/src/populate/from-csr.js.map +1 -0
  87. package/dist/src/populate/from-edge-arrays.d.ts +51 -0
  88. package/dist/src/populate/from-edge-arrays.d.ts.map +1 -0
  89. package/dist/src/populate/from-edge-arrays.js +217 -0
  90. package/dist/src/populate/from-edge-arrays.js.map +1 -0
  91. package/dist/src/populate/from-records.d.ts +51 -0
  92. package/dist/src/populate/from-records.d.ts.map +1 -0
  93. package/dist/src/populate/from-records.js +447 -0
  94. package/dist/src/populate/from-records.js.map +1 -0
  95. package/dist/src/snapshot/derived.d.ts +211 -0
  96. package/dist/src/snapshot/derived.d.ts.map +1 -0
  97. package/dist/src/snapshot/derived.js +1254 -0
  98. package/dist/src/snapshot/derived.js.map +1 -0
  99. package/dist/src/snapshot/graph-meta.d.ts +23 -0
  100. package/dist/src/snapshot/graph-meta.d.ts.map +1 -0
  101. package/dist/src/snapshot/graph-meta.js +159 -0
  102. package/dist/src/snapshot/graph-meta.js.map +1 -0
  103. package/dist/src/snapshot/graph-snapshot.d.ts +509 -0
  104. package/dist/src/snapshot/graph-snapshot.d.ts.map +1 -0
  105. package/dist/src/snapshot/graph-snapshot.js +1247 -0
  106. package/dist/src/snapshot/graph-snapshot.js.map +1 -0
  107. package/dist/src/snapshot/hash.d.ts +90 -0
  108. package/dist/src/snapshot/hash.d.ts.map +1 -0
  109. package/dist/src/snapshot/hash.js +228 -0
  110. package/dist/src/snapshot/hash.js.map +1 -0
  111. package/dist/src/snapshot/queries.d.ts +74 -0
  112. package/dist/src/snapshot/queries.d.ts.map +1 -0
  113. package/dist/src/snapshot/queries.js +131 -0
  114. package/dist/src/snapshot/queries.js.map +1 -0
  115. package/dist/src/snapshot/validate.d.ts +192 -0
  116. package/dist/src/snapshot/validate.d.ts.map +1 -0
  117. package/dist/src/snapshot/validate.js +990 -0
  118. package/dist/src/snapshot/validate.js.map +1 -0
  119. package/dist/src/snapshot/views.d.ts +274 -0
  120. package/dist/src/snapshot/views.d.ts.map +1 -0
  121. package/dist/src/snapshot/views.js +856 -0
  122. package/dist/src/snapshot/views.js.map +1 -0
  123. package/dist/src/types/builder.d.ts +456 -0
  124. package/dist/src/types/builder.d.ts.map +1 -0
  125. package/dist/src/types/builder.js +11 -0
  126. package/dist/src/types/builder.js.map +1 -0
  127. package/dist/src/types/columns.d.ts +615 -0
  128. package/dist/src/types/columns.d.ts.map +1 -0
  129. package/dist/src/types/columns.js +14 -0
  130. package/dist/src/types/columns.js.map +1 -0
  131. package/dist/src/types/index.d.ts +14 -0
  132. package/dist/src/types/index.d.ts.map +1 -0
  133. package/dist/src/types/index.js +11 -0
  134. package/dist/src/types/index.js.map +1 -0
  135. package/dist/src/types/internal.d.ts +172 -0
  136. package/dist/src/types/internal.d.ts.map +1 -0
  137. package/dist/src/types/internal.js +13 -0
  138. package/dist/src/types/internal.js.map +1 -0
  139. package/dist/src/types/snapshot.d.ts +801 -0
  140. package/dist/src/types/snapshot.d.ts.map +1 -0
  141. package/dist/src/types/snapshot.js +14 -0
  142. package/dist/src/types/snapshot.js.map +1 -0
  143. package/dist/src/types/wire.d.ts +196 -0
  144. package/dist/src/types/wire.d.ts.map +1 -0
  145. package/dist/src/types/wire.js +8 -0
  146. package/dist/src/types/wire.js.map +1 -0
  147. package/dist/src/util/mask.d.ts +55 -0
  148. package/dist/src/util/mask.d.ts.map +1 -0
  149. package/dist/src/util/mask.js +71 -0
  150. package/dist/src/util/mask.js.map +1 -0
  151. package/dist/src/util/options.d.ts +22 -0
  152. package/dist/src/util/options.d.ts.map +1 -0
  153. package/dist/src/util/options.js +49 -0
  154. package/dist/src/util/options.js.map +1 -0
  155. package/dist/src/util/shared-buffers.d.ts +42 -0
  156. package/dist/src/util/shared-buffers.d.ts.map +1 -0
  157. package/dist/src/util/shared-buffers.js +52 -0
  158. package/dist/src/util/shared-buffers.js.map +1 -0
  159. package/dist/src/util/typed-array.d.ts +205 -0
  160. package/dist/src/util/typed-array.d.ts.map +1 -0
  161. package/dist/src/util/typed-array.js +289 -0
  162. package/dist/src/util/typed-array.js.map +1 -0
  163. package/dist/src/wire/bytes.d.ts +69 -0
  164. package/dist/src/wire/bytes.d.ts.map +1 -0
  165. package/dist/src/wire/bytes.js +361 -0
  166. package/dist/src/wire/bytes.js.map +1 -0
  167. package/dist/src/wire/carried-views.d.ts +111 -0
  168. package/dist/src/wire/carried-views.d.ts.map +1 -0
  169. package/dist/src/wire/carried-views.js +286 -0
  170. package/dist/src/wire/carried-views.js.map +1 -0
  171. package/dist/src/wire/from-wire.d.ts +144 -0
  172. package/dist/src/wire/from-wire.d.ts.map +1 -0
  173. package/dist/src/wire/from-wire.js +1425 -0
  174. package/dist/src/wire/from-wire.js.map +1 -0
  175. package/dist/src/wire/to-wire.d.ts +171 -0
  176. package/dist/src/wire/to-wire.d.ts.map +1 -0
  177. package/dist/src/wire/to-wire.js +652 -0
  178. package/dist/src/wire/to-wire.js.map +1 -0
  179. package/dist/tsconfig.build.tsbuildinfo +1 -0
  180. package/package.json +72 -7
  181. package/src/builder/arena.ts +192 -0
  182. package/src/builder/compact.ts +1811 -0
  183. package/src/builder/counting-sort.ts +506 -0
  184. package/src/builder/freeze.ts +689 -0
  185. package/src/builder/graph-builder.ts +2264 -0
  186. package/src/builder/options.ts +29 -0
  187. package/src/columns/bitmap.ts +196 -0
  188. package/src/columns/column.ts +2574 -0
  189. package/src/columns/dictionary.ts +114 -0
  190. package/src/columns/growable.ts +350 -0
  191. package/src/columns/infer.ts +285 -0
  192. package/src/columns/remap.ts +663 -0
  193. package/src/columns/table.ts +568 -0
  194. package/src/constants.ts +89 -0
  195. package/src/errors.ts +115 -0
  196. package/src/ids/edge-id-index.ts +179 -0
  197. package/src/ids/node-id-map.ts +1340 -0
  198. package/src/ids/string-store.ts +589 -0
  199. package/src/index.ts +139 -0
  200. package/src/lib-resizable-array-buffer.d.ts +34 -0
  201. package/src/populate/from-csr.ts +802 -0
  202. package/src/populate/from-edge-arrays.ts +257 -0
  203. package/src/populate/from-records.ts +536 -0
  204. package/src/snapshot/derived.ts +1486 -0
  205. package/src/snapshot/graph-meta.ts +167 -0
  206. package/src/snapshot/graph-snapshot.ts +1503 -0
  207. package/src/snapshot/hash.ts +241 -0
  208. package/src/snapshot/queries.ts +136 -0
  209. package/src/snapshot/validate.ts +1108 -0
  210. package/src/snapshot/views.ts +943 -0
  211. package/src/types/builder.ts +480 -0
  212. package/src/types/columns.ts +727 -0
  213. package/src/types/index.ts +14 -0
  214. package/src/types/internal.ts +195 -0
  215. package/src/types/snapshot.ts +886 -0
  216. package/src/types/wire.ts +207 -0
  217. package/src/util/mask.ts +89 -0
  218. package/src/util/options.ts +57 -0
  219. package/src/util/shared-buffers.ts +56 -0
  220. package/src/util/typed-array.ts +371 -0
  221. package/src/wire/bytes.ts +440 -0
  222. package/src/wire/carried-views.ts +327 -0
  223. package/src/wire/from-wire.ts +1690 -0
  224. package/src/wire/to-wire.ts +755 -0
@@ -0,0 +1,257 @@
1
+ /**
2
+ * `fromEdgeArrays()` (design section 8.1, entry point 1): COO typed arrays with dense node indices,
3
+ * the 20 ms path. The input goes through the builder's index-space fast path -- `addAnonymousNodes`
4
+ * (no id Map unless `ids` is given) plus one `addEdges` call -- and then the freeze pipeline of design
5
+ * section 6.3, so every builder policy (duplicate edges, self-loops, weight precision) and every
6
+ * freeze option (label, prepare, arena, checksum) applies exactly as it does to a hand-built
7
+ * builder. Attribute columns are staged in the builder too, so a merging duplicate policy or a
8
+ * dropped self-loop gathers them through the same remaps as any other column (design section 5.11).
9
+ *
10
+ * The options object is the intersection of BuilderOptionsPatch and FreezeOptions; `splitOptions`
11
+ * routes each field to the builder or to the freeze and is shared with `fromRecords`.
12
+ */
13
+
14
+ import { GraphBuilder } from "../builder/graph-builder.js";
15
+ import { columnFromValues, metaToDecl } from "../columns/column.js";
16
+ import { GraphFormatError } from "../errors.js";
17
+ import { type GraphSnapshot } from "../snapshot/graph-snapshot.js";
18
+ import {
19
+ type BuilderOptionsPatch,
20
+ type ColumnDecl,
21
+ type ColumnInput,
22
+ type EdgeArraysInput,
23
+ type FreezeOptions,
24
+ type GraphBuilderOptions,
25
+ type NodeId,
26
+ type TypedArrayData,
27
+ } from "../types/index.js";
28
+
29
+ // ============================================================ options
30
+
31
+ /** The builder half and the freeze half of a `BuilderOptionsPatch & FreezeOptions` object. */
32
+ interface SplitOptions {
33
+ /** The builder options; `directed` is the caller's input value. */
34
+ readonly builder: GraphBuilderOptions;
35
+ /** The freeze options. */
36
+ readonly freeze: FreezeOptions;
37
+ }
38
+
39
+ /**
40
+ * Route the fields of a factory options object to the builder constructor and to `freeze()`.
41
+ * `duplicateEdges` (a field of both) becomes the builder's default policy, which the freeze then
42
+ * applies; an `options.directed` must agree with the input's own `directed` (E_DIRECTED otherwise; the input is
43
+ * authoritative). Undefined fields are left to the builder's and the freeze's own defaults.
44
+ * @param directed - the input's direction
45
+ * @param options - the combined options
46
+ * @returns the two halves
47
+ */
48
+ export function splitOptions(directed: boolean, options: BuilderOptionsPatch & FreezeOptions): SplitOptions {
49
+ if (options.directed !== undefined && options.directed !== directed) {
50
+ throw new GraphFormatError(
51
+ "E_DIRECTED",
52
+ `options.directed (${String(options.directed)}) disagrees with the input's directed (${String(directed)})`,
53
+ { reason: "direction mismatch", directed, found: options.directed },
54
+ );
55
+ }
56
+ return {
57
+ builder: {
58
+ directed,
59
+ weighted: options.weighted,
60
+ weightDtype: options.weightDtype,
61
+ duplicateEdges: options.duplicateEdges,
62
+ selfLoops: options.selfLoops,
63
+ addMissingNodes: options.addMissingNodes,
64
+ expectedNodes: options.expectedNodes,
65
+ expectedEdges: options.expectedEdges,
66
+ },
67
+ freeze: {
68
+ label: options.label,
69
+ prepare: options.prepare,
70
+ arena: options.arena,
71
+ release: options.release,
72
+ profile: options.profile,
73
+ checksum: options.checksum,
74
+ },
75
+ };
76
+ }
77
+
78
+ // ============================================================ columns
79
+
80
+ /**
81
+ * Whether a column value is a typed array (as opposed to a ColumnInput).
82
+ * @param value - the column value
83
+ * @returns true for a typed array
84
+ */
85
+ function isTypedArrayData(value: TypedArrayData | ColumnInput): value is TypedArrayData {
86
+ return ArrayBuffer.isView(value);
87
+ }
88
+
89
+ /**
90
+ * Stage one caller-supplied column in the builder (design section 8.1). A typed array (bare or
91
+ * inside a ColumnInput) is bulk-set with its declaration; a JS array of values is resolved with the
92
+ * same inference `AttributeTable.set()` applies (design section 5.1 widening, list detection) and
93
+ * written row by row into a declared column, so a string / list / json column reaches the snapshot
94
+ * through the same freeze step as every other column.
95
+ * @param builder - the builder
96
+ * @param domain - "node" or "edge"
97
+ * @param rows - the table's row count (nodeCount or edge count); a JS array must have this many entries
98
+ * @param name - the column name (the record key; a `decl.name` is ignored)
99
+ * @param value - the typed array or ColumnInput
100
+ */
101
+ function stageColumn(
102
+ builder: GraphBuilder,
103
+ domain: "node" | "edge",
104
+ rows: number,
105
+ name: string,
106
+ value: TypedArrayData | ColumnInput,
107
+ ): void {
108
+ const data = isTypedArrayData(value) ? value : value.data;
109
+ const decl = isTypedArrayData(value) ? {} : value.decl;
110
+ if (ArrayBuffer.isView(data)) {
111
+ if (domain === "node") {
112
+ builder.setNodeColumn(name, data, decl);
113
+ } else {
114
+ builder.setEdgeColumn(name, data, decl);
115
+ }
116
+ return;
117
+ }
118
+ const column = columnFromValues(domain, rows, name, data, decl);
119
+ const declaration: ColumnDecl = { ...metaToDecl(column.meta), name, dtype: column.dtype };
120
+ const handle = domain === "node" ? builder.declareNodeColumn(declaration) : builder.declareEdgeColumn(declaration);
121
+ for (let row = 0; row < rows; row++) {
122
+ if (!column.isSet(row)) {
123
+ continue;
124
+ }
125
+ const cell = column.value(row);
126
+ if (domain === "node") {
127
+ builder.setNodeValue(handle, row, cell);
128
+ } else {
129
+ builder.setEdgeValue(handle, row, cell);
130
+ }
131
+ }
132
+ }
133
+
134
+ // ============================================================ the entry point
135
+
136
+ /**
137
+ * The E_COLUMN_LENGTH error for two input arrays whose lengths disagree.
138
+ * @param field - the array that is wrong
139
+ * @param expected - the length it should have
140
+ * @param found - the length it has
141
+ * @returns the error
142
+ */
143
+ function lengthError(field: string, expected: number, found: number): GraphFormatError {
144
+ return new GraphFormatError("E_COLUMN_LENGTH", `${field} has ${found} entries, expected ${expected}`, {
145
+ field,
146
+ expected,
147
+ found,
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Resolve the node count of an EdgeArraysInput: `ids.length` when ids are given (and `nodeCount`,
153
+ * when also given, must agree), else `nodeCount`, which is then required.
154
+ * @param input - the input
155
+ * @returns the node count
156
+ */
157
+ function resolveNodeCount(input: EdgeArraysInput): number {
158
+ const { nodeCount, ids } = input;
159
+ if (nodeCount !== undefined && (!Number.isInteger(nodeCount) || nodeCount < 0)) {
160
+ throw new GraphFormatError("E_INDEX_RANGE", `nodeCount ${nodeCount} is not a non-negative integer`, {
161
+ field: "nodeCount",
162
+ found: nodeCount,
163
+ });
164
+ }
165
+ if (ids !== undefined) {
166
+ if (nodeCount !== undefined && nodeCount !== ids.length) {
167
+ throw lengthError("ids", nodeCount, ids.length);
168
+ }
169
+ return ids.length;
170
+ }
171
+ if (nodeCount === undefined) {
172
+ throw new GraphFormatError("E_INDEX_RANGE", "nodeCount is required when no ids are given", {
173
+ field: "nodeCount",
174
+ });
175
+ }
176
+ return nodeCount;
177
+ }
178
+
179
+ /**
180
+ * Add the caller's ids to the builder in index order; every id must be distinct so that index i holds
181
+ * ids[i] (E_DUPLICATE_ID otherwise, naming the id and both positions).
182
+ * @param builder - the builder
183
+ * @param ids - the ids in index order
184
+ */
185
+ function addIds(builder: GraphBuilder, ids: readonly NodeId[] | Float64Array): void {
186
+ const indices = builder.addNodes(ids);
187
+ for (let i = 0; i < indices.length; i++) {
188
+ if (indices[i] !== i) {
189
+ const id = ids[i];
190
+ throw new GraphFormatError("E_DUPLICATE_ID", `ids[${i}] repeats the id of index ${indices[i]}`, {
191
+ id,
192
+ index: indices[i],
193
+ position: i,
194
+ });
195
+ }
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Build a snapshot from COO typed arrays with dense node indices (design section 8.1): the builder's
201
+ * index-space fast path (`addAnonymousNodes` + `addEdges`, no id Map unless `ids` is given) followed
202
+ * by the freeze pipeline, so the result is exactly what a builder fed the same nodes, edges, columns
203
+ * and meta would freeze to. Without `ids` the id map is `identity` with offset 0 and no storage;
204
+ * with `ids` the kind is detected at freeze (design section 4.2). Float64 weights select the f64
205
+ * staging precision unless `options.weightDtype` says otherwise, so the values are downcast to f32 in
206
+ * the arc array and an f64 shadow column is kept only when some value is not f32-exact (design
207
+ * section 3.7).
208
+ * @param input - the arrays; `nodeCount` is required unless `ids` is given (E_INDEX_RANGE); `src`,
209
+ * `dst` and `weights` must have one entry per edge (E_COLUMN_LENGTH); every index must be below the
210
+ * node count (E_UNKNOWN_NODE); no weight may be NaN (E_INVALID_WEIGHT); ids must be distinct legal
211
+ * ids (E_DUPLICATE_ID / E_INVALID_ID); columns must have the table's row count (E_COLUMN_LENGTH)
212
+ * @param options - builder policies and freeze options; `duplicateEdges` and `selfLoops` apply at the
213
+ * freeze (E_DUPLICATE_EDGE / E_SELF_LOOP under the "error" policies)
214
+ * @returns the frozen snapshot
215
+ */
216
+ export function fromEdgeArrays(
217
+ input: EdgeArraysInput,
218
+ options: BuilderOptionsPatch & FreezeOptions = {},
219
+ ): GraphSnapshot {
220
+ const { src, dst, weights } = input;
221
+ if (dst.length !== src.length) {
222
+ throw lengthError("dst", src.length, dst.length);
223
+ }
224
+ if (weights !== undefined && weights.length !== src.length) {
225
+ throw lengthError("weights", src.length, weights.length);
226
+ }
227
+ const nodeCount = resolveNodeCount(input);
228
+ const edgeCount = src.length;
229
+ const split = splitOptions(input.directed, options);
230
+ const builderOptions: GraphBuilderOptions = {
231
+ ...split.builder,
232
+ weightDtype: options.weightDtype ?? (weights instanceof Float64Array ? "f64" : undefined),
233
+ expectedNodes: options.expectedNodes ?? nodeCount,
234
+ expectedEdges: options.expectedEdges ?? edgeCount,
235
+ };
236
+ const builder = new GraphBuilder(builderOptions);
237
+ if (input.ids === undefined) {
238
+ builder.addAnonymousNodes(nodeCount);
239
+ } else {
240
+ addIds(builder, input.ids);
241
+ }
242
+ builder.addEdges(src, dst, weights);
243
+ if (input.nodeColumns !== undefined) {
244
+ for (const name of Object.keys(input.nodeColumns)) {
245
+ stageColumn(builder, "node", nodeCount, name, input.nodeColumns[name]);
246
+ }
247
+ }
248
+ if (input.edgeColumns !== undefined) {
249
+ for (const name of Object.keys(input.edgeColumns)) {
250
+ stageColumn(builder, "edge", edgeCount, name, input.edgeColumns[name]);
251
+ }
252
+ }
253
+ if (input.meta !== undefined) {
254
+ builder.setMeta(input.meta);
255
+ }
256
+ return builder.freeze(split.freeze);
257
+ }