@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,886 @@
1
+ /**
2
+ * The frozen snapshot and its side structures (design sections 3, 4, 7, 8.1, 9, 10 and 12.2): the id
3
+ * map, the flags, the arena layout, the views, the derived graphs, the GraphSnapshot contract itself
4
+ * and the inputs of the snapshot factories.
5
+ *
6
+ * GraphSnapshotContract and NodeIdMapContract are the instance contracts of the GraphSnapshot and
7
+ * NodeIdMap classes implemented in src/snapshot/graph-snapshot.ts and src/ids/node-id-map.ts (design
8
+ * section 12.1 makes them classes so the JSDoc-on-method lint applies). The public names
9
+ * GraphSnapshot and NodeIdMap are the classes themselves, re-exported type-only from here so every
10
+ * type on this surface (DerivedGraph.snapshot, SnapshotParts.ids, ...) names the class the barrel
11
+ * exports. The imports are type-only, so the import graph stays free of runtime cycles.
12
+ */
13
+
14
+ import { type SNAPSHOT_BRAND } from "../constants.js";
15
+ import { type NodeIdMap } from "../ids/node-id-map.js";
16
+ import { type GraphSnapshot } from "../snapshot/graph-snapshot.js";
17
+ import {
18
+ type AttributeTable,
19
+ type ColumnDecl,
20
+ type ColumnInput,
21
+ type ColumnReducer,
22
+ type EdgeId,
23
+ type EdgeMask,
24
+ type F32,
25
+ type F64,
26
+ type GraphMeta,
27
+ type GraphMetaPatch,
28
+ type IdCoercion,
29
+ type Loose,
30
+ type NodeId,
31
+ type NodeMask,
32
+ type TypedArrayData,
33
+ type U8,
34
+ type U32,
35
+ type ValidationLevel,
36
+ type WeightReducer,
37
+ } from "./columns.js";
38
+ import { type ToBytesOptions, type ToWireOptions, type WireSnapshot } from "./wire.js";
39
+
40
+ export type { GraphSnapshot, NodeIdMap };
41
+
42
+ // ============================================================ id map
43
+
44
+ /**
45
+ * Storage kind of a NodeIdMap, chosen at freeze by inspecting the ids once (design section 4.2):
46
+ * "identity" (id === index + offset, zero bytes), "dense" (distinct integers with maxId + 1 <= 2n),
47
+ * "numeric" (any numbers), "string" (all strings) or "mixed".
48
+ */
49
+ export type NodeIdMapKind = "identity" | "dense" | "numeric" | "string" | "mixed";
50
+
51
+ /**
52
+ * Bijection between node ids and node indices for one snapshot, kept outside the CSR (invariant
53
+ * I11: ids.indexOf(ids.idOf(i)) === i for every i, size === nodeCount, SameValueZero equality, no
54
+ * NaN). Immutable. Lookups by id return INVALID_INDEX on a miss rather than -1 or undefined so the
55
+ * sentinel is the same one used in every u32 result vector (decision C9).
56
+ *
57
+ * Instance contract of the NodeIdMap class in src/ids/node-id-map.ts, which implements it; the
58
+ * public barrel exports the class and every public type names the class.
59
+ */
60
+ export interface NodeIdMapContract extends Iterable<NodeId> {
61
+ /** The storage kind (design section 4.2). */
62
+ readonly kind: NodeIdMapKind;
63
+ /** Number of ids; equals nodeCount. */
64
+ readonly size: number;
65
+ /** identity only: id === index + offset (0 or 1 in practice); 0 for every other kind. */
66
+ readonly offset: number;
67
+ /**
68
+ * The id of a node index.
69
+ * @param index - the node index
70
+ * @returns the id; E_INDEX_RANGE when index >= size
71
+ */
72
+ idOf(index: number): NodeId;
73
+ /**
74
+ * Total lookup by id.
75
+ * @param id - the node id
76
+ * @returns the node index, or INVALID_INDEX when absent
77
+ */
78
+ indexOf(id: NodeId): number;
79
+ /**
80
+ * Whether an id is present.
81
+ * @param id - the node id
82
+ * @returns true when present
83
+ */
84
+ has(id: NodeId): boolean;
85
+ /**
86
+ * Checked lookup by id, for algorithms that today throw "node not found".
87
+ * @param id - the node id
88
+ * @returns the node index; E_UNKNOWN_NODE when absent
89
+ */
90
+ requireIndex(id: NodeId): number;
91
+ /**
92
+ * Bulk lookup.
93
+ * @param ids - the ids to resolve
94
+ * @param onMissing - "invalid" (default) writes INVALID_INDEX for a miss; "throw" raises E_UNKNOWN_NODE
95
+ * @returns a fresh U32 of indices in input order
96
+ */
97
+ indicesOf(ids: Iterable<NodeId>, onMissing?: "invalid" | "throw"): U32;
98
+ /**
99
+ * Bulk decode of a range of ids in one pass.
100
+ * @param start - first index (default 0)
101
+ * @param end - one past the last index (default size)
102
+ * @returns the ids in index order
103
+ */
104
+ idsSlice(start?: number, end?: number): NodeId[];
105
+ /**
106
+ * Every id in index order.
107
+ * @returns a fresh array
108
+ */
109
+ toArray(): NodeId[];
110
+ /**
111
+ * Iterate the ids in index order.
112
+ * @returns an iterator over the ids
113
+ */
114
+ [Symbol.iterator](): IterableIterator<NodeId>;
115
+ /**
116
+ * Key an index-aligned result vector by id (boundary helper, decision C11).
117
+ * @param values - one value per node index
118
+ * @returns a Map from id to value
119
+ */
120
+ toMap<T>(values: ArrayLike<T>): Map<NodeId, T>;
121
+ /**
122
+ * Key an index-aligned result vector by String(id), for legacy Map<string, T> result shapes.
123
+ * @param values - one value per node index
124
+ * @returns a Map from String(id) to value
125
+ */
126
+ toStringMap<T>(values: ArrayLike<T>): Map<string, T>;
127
+ /**
128
+ * Key an index-aligned result vector by String(id), for legacy record result shapes only.
129
+ * @param values - one value per node index
130
+ * @returns a record from String(id) to value
131
+ */
132
+ toRecord<T>(values: ArrayLike<T>): Record<string, T>;
133
+ /**
134
+ * Iterate [id, value] pairs of an index-aligned result vector.
135
+ * @param values - one value per node index
136
+ * @returns an iterator over the pairs in index order
137
+ */
138
+ entries<T>(values: ArrayLike<T>): IterableIterator<[NodeId, T]>;
139
+ /**
140
+ * String(idOf(i)) -> i, built lazily once, for legacy string-typed id parameters.
141
+ * @returns the read-only string index
142
+ */
143
+ stringIndex(): ReadonlyMap<string, number>;
144
+ /**
145
+ * Bytes of typed storage; excludes the reverse Map and JS strings.
146
+ * @returns the byte count
147
+ */
148
+ byteLength(): number;
149
+ }
150
+
151
+ // ============================================================ flags, arena, views
152
+
153
+ /**
154
+ * Flags kernels branch on (design section 3.8). Each is defined by a predicate over the arrays,
155
+ * computed at freeze or by validation, never guessed; there is no flag whose value may be "unknown"
156
+ * (invariant I9). The three weight flags describe the f32 ARC ARRAY (`weights`): when an f64
157
+ * role-"weight" shadow column is kept (design section 3.7) its exact values can differ from the
158
+ * rounded arc values (1 + 2^-30 rounds to 1), so a consumer that substitutes the shadow for the arc
159
+ * weights must not branch on these flags.
160
+ */
161
+ export interface SnapshotFlags {
162
+ /** Some row contains two arcs with equal colIdx (parallel edges). */
163
+ readonly multigraph: boolean;
164
+ /** selfLoopCount > 0. */
165
+ readonly hasSelfLoops: boolean;
166
+ /**
167
+ * directed && arcToEdge[a] === a for all a (and edgeToArc is the identity). Always false when !directed, even when
168
+ * arcCount === edgeCount.
169
+ */
170
+ readonly arcToEdgeIsIdentity: boolean;
171
+ /** weights !== null. */
172
+ readonly weighted: boolean;
173
+ /** weights === null, or every value === 1. Lets SSSP degrade to BFS. */
174
+ readonly allWeightsOne: boolean;
175
+ /** weights === null, or every value >= 0. Dijkstra / delta-stepping legal. */
176
+ readonly nonNegativeWeights: boolean;
177
+ /** weights === null, or every value is finite. */
178
+ readonly finiteWeights: boolean;
179
+ }
180
+
181
+ /** Flag claims a caller passes to fromCsr(); verified unless validate is "none" (design section 8.1). */
182
+ export type FlagClaims = Loose<SnapshotFlags>;
183
+
184
+ /** The five core arrays, in the hot-to-cold order they occupy the arena (design section 10.3). */
185
+ export type CoreArrayName = "rowPtr" | "colIdx" | "weights" | "arcToEdge" | "edgeToArc";
186
+
187
+ /** One core array's location inside the arena buffer, in absolute bytes (design section 10.3). */
188
+ export interface ArenaSegment {
189
+ /** Absolute byte offset in ArenaLayout.buffer; a multiple of 256 relative to ArenaLayout.byteOffset. */
190
+ readonly byteOffset: number;
191
+ /** Byte length of the array (unpadded). */
192
+ readonly byteLength: number;
193
+ }
194
+
195
+ /**
196
+ * One ArrayBuffer holding the core arrays at 256-byte-aligned offsets, hot to cold: rowPtr, colIdx,
197
+ * weights, arcToEdge, edgeToArc (design section 10.3, invariant I10). A GPU package uploads the first
198
+ * hotByteLength bytes in one writeBuffer call and binds each segment as a storage-buffer window. A
199
+ * zero-length array, an absent weights array and an identity permutation have a null segment and
200
+ * are never in the arena.
201
+ */
202
+ export interface ArenaLayout {
203
+ /** The backing buffer. */
204
+ readonly buffer: ArrayBuffer;
205
+ /** Start of the arena inside buffer: 0 for builder output; bytes.byteOffset + B for a container. */
206
+ readonly byteOffset: number;
207
+ /** Total padded length of the arena. */
208
+ readonly byteLength: number;
209
+ /** Segment alignment in bytes. */
210
+ readonly alignment: 256;
211
+ /** Absolute offsets in buffer per core array; null = absent, zero-length, or identity (never in the arena). */
212
+ readonly segments: Readonly<Record<CoreArrayName, ArenaSegment | null>>;
213
+ /**
214
+ * End of the weights segment (or colIdx when unweighted) relative to byteOffset: the prefix a traversal kernel
215
+ * needs.
216
+ */
217
+ readonly hotByteLength: number;
218
+ }
219
+
220
+ /**
221
+ * Names of the lazily computed, cached views (design section 7.2), as accepted by prepare(),
222
+ * cachedViews() and the wire includeViews option. "degreeOrder" and "reverseDegreeOrder" are the two
223
+ * cached results of degreeOrder({ of }); "symmetric" is the result of isSymmetric(). The scalar
224
+ * views "totalWeight" and "symmetric" are ignored by includeViews and always recomputed.
225
+ */
226
+ export type ViewName =
227
+ | "reverse"
228
+ | "coo"
229
+ | "edgeList"
230
+ | "outDegree"
231
+ | "inDegree"
232
+ | "degree"
233
+ | "weightedOutDegree"
234
+ | "weightedInDegree"
235
+ | "weightedDegree"
236
+ | "selfLoopWeight"
237
+ | "totalWeight"
238
+ | "selfLoopArcs"
239
+ | "selfLoopsPerNode"
240
+ | "mate"
241
+ | "degreeOrder"
242
+ | "reverseDegreeOrder"
243
+ | "symmetric";
244
+
245
+ /** Options of degreeOrder(): which adjacency's out-degree orders the nodes (design section 7.2). */
246
+ export interface DegreeOrderOptions {
247
+ /** "forward" (default) orders by rowPtr; "reverse" by reverse().rowPtr, i.e. the in-degree, for pull kernels. */
248
+ readonly of?: "forward" | "reverse" | undefined;
249
+ }
250
+
251
+ /**
252
+ * The structural row-walking interface implemented by GraphSnapshot and by ReverseView (design
253
+ * section 7.2), so an algorithm that only walks rows takes either without a wrapper: an
254
+ * in-neighbour BFS is the out-neighbour BFS over reverse(). Rows are sorted by target with ties in
255
+ * ascending arcToEdge order (invariant I4); no INVALID_INDEX appears in any array (I2).
256
+ */
257
+ export interface AdjacencyView {
258
+ /** Whether the graph is directed (design section 3.6). */
259
+ readonly directed: boolean;
260
+ /** Number of nodes n. */
261
+ readonly nodeCount: number;
262
+ /** Number of arcs: colIdx.length === rowPtr[nodeCount] (invariant I1). */
263
+ readonly arcCount: number;
264
+ /** nodeCount + 1 row offsets; rowPtr[0] === 0, non-decreasing (invariant I1). */
265
+ readonly rowPtr: U32;
266
+ /** Target node index of every arc, sorted within each row (invariants I2, I4); length 0 when arcCount === 0. */
267
+ readonly colIdx: U32;
268
+ /** Logical edge of every arc (invariant I5). */
269
+ readonly arcToEdge: U32;
270
+ /** Per-arc f32 weights, or null when every weight is 1 (design section 3.7, invariant I8). */
271
+ readonly weights: F32 | null;
272
+ }
273
+
274
+ /**
275
+ * The in-adjacency of a snapshot (design section 7.2): rows sorted by source, weights gathered when
276
+ * weighted. For an undirected snapshot the forward arrays themselves are returned (invariant I7)
277
+ * with an identity fwdArc, and arcToEdge is the very same array as the snapshot's.
278
+ */
279
+ export interface ReverseView extends AdjacencyView {
280
+ /** Reverse arc k -> forward arc index; the identity for undirected snapshots (materialised lazily). */
281
+ readonly fwdArc: U32;
282
+ }
283
+
284
+ /** Per-arc COO form: src is the only new array; dst aliases colIdx (design section 7.2). */
285
+ export interface CooView {
286
+ /** Source node index of every arc (the row containing it). */
287
+ readonly src: U32;
288
+ /** Target node index of every arc; aliases colIdx. */
289
+ readonly dst: U32;
290
+ /** Logical edge of every arc; aliases the snapshot's arcToEdge. */
291
+ readonly arcToEdge: U32;
292
+ /** Per-arc weights; aliases the snapshot's weights. */
293
+ readonly weights: F32 | null;
294
+ }
295
+
296
+ /**
297
+ * Every logical edge once, in declared orientation (design section 7.2): the binding an
298
+ * each-edge-once edge-parallel kernel uses on directed and undirected snapshots alike.
299
+ */
300
+ export interface EdgeListView {
301
+ /** Declared source of every logical edge. */
302
+ readonly src: U32;
303
+ /** Declared target of every logical edge. */
304
+ readonly dst: U32;
305
+ /** The arc holding the declared orientation; aliases edgeToArc. */
306
+ readonly arc: U32;
307
+ /**
308
+ * Per-edge weights gathered through edgeToArc (aliased when the permutation is the identity); null when unweighted.
309
+ */
310
+ readonly weights: F32 | null;
311
+ }
312
+
313
+ /**
314
+ * Nodes permuted by descending out-degree of the chosen adjacency with cuGraph's tier thresholds
315
+ * 1024 / 32 / 1 (design section 7.2): perm is the GPU load-balancing binding, segmentOffsets =
316
+ * [0, hiEnd, midEnd, lowEnd, n] is read on the CPU to size the three dispatches.
317
+ */
318
+ export interface DegreeOrderView {
319
+ /** Node indices in descending degree order; length n. */
320
+ readonly perm: U32;
321
+ /** The five tier boundaries [0, hiEnd, midEnd, lowEnd, n]. */
322
+ readonly segmentOffsets: U32;
323
+ }
324
+
325
+ // ============================================================ derived graphs
326
+
327
+ /**
328
+ * A new snapshot produced from an existing one by a structural mapping the caller specifies, plus
329
+ * index maps back to the source (design section 7.3). Never cached by the format. Every map is null
330
+ * when the corresponding index space is unchanged; edgeRemap maps every merged edge to its survivor
331
+ * so a per-edge result of the derived graph writes back onto source edges with
332
+ * `out[e] = vec[edgeRemap[e]]`, and edgeRemap[edgeOrigin[d]] === d for every derived edge d.
333
+ */
334
+ export interface DerivedGraph {
335
+ /** The derived snapshot; `this` for the identity cases (transpose / toUndirected of an undirected snapshot). */
336
+ readonly snapshot: GraphSnapshot;
337
+ /**
338
+ * New node index -> source node index (contract: the LOWEST source index of the block); null when the node space is
339
+ * unchanged.
340
+ */
341
+ readonly nodeOrigin: U32 | null;
342
+ /**
343
+ * New edge index -> source edge index (a merged edge: its SURVIVOR's source index, never INVALID_INDEX); null when
344
+ * unchanged.
345
+ */
346
+ readonly edgeOrigin: U32 | null;
347
+ /** Source node index -> new index (contract: the block) or INVALID_INDEX (dropped); null when unchanged. */
348
+ readonly nodeRemap: U32 | null;
349
+ /**
350
+ * Source edge index -> new index; a merged / collapsed edge maps to its SURVIVOR, a dropped edge to INVALID_INDEX;
351
+ * null when unchanged.
352
+ */
353
+ readonly edgeRemap: U32 | null;
354
+ /** contract only: source nodes per new node; null otherwise. */
355
+ readonly blockSizes: U32 | null;
356
+ /** How many source edges were dropped and how many merged. */
357
+ readonly report: { readonly droppedEdges: number; readonly mergedEdges: number };
358
+ }
359
+
360
+ /** Options of toUndirected() (design section 7.3). */
361
+ export interface ToUndirectedOptions {
362
+ /** Keep only pairs present in both directions (cuGraph symmetrize(reciprocal)). */
363
+ readonly reciprocal?: boolean | undefined;
364
+ /** How the weights of a collapsed reciprocal pair combine; default "first" (the lower index's weight). */
365
+ readonly weights?: WeightReducer | undefined;
366
+ }
367
+
368
+ /** Options of simplified() (design section 7.3): one edge per (u, v) group, survivor = lowest index. */
369
+ export interface SimplifyOptions {
370
+ /** How the weights of a parallel group combine; default "first". */
371
+ readonly weights?: WeightReducer | undefined;
372
+ /** Whether self-loops survive; default "keep". */
373
+ readonly selfLoops?: "keep" | "drop" | undefined;
374
+ /** Per-column reducers for the other edge columns; default: the survivor's row. */
375
+ readonly edgeReducers?: Readonly<Record<string, ColumnReducer>> | undefined;
376
+ }
377
+
378
+ /**
379
+ * Options of contract(partition) (design section 7.3): the Leiden / Louvain aggregation and
380
+ * condensationGraph primitive. Semantics are at the logical-edge level: an intra-block edge becomes
381
+ * one self-loop with weight w, an inter-block edge one edge between the blocks.
382
+ */
383
+ export interface ContractOptions {
384
+ /** How merged edge weights combine; default "sum" (on an unweighted source "sum" yields multiplicities). */
385
+ readonly weights?: WeightReducer | undefined;
386
+ /** Whether intra-block edges become self-loops; default "keep". */
387
+ readonly selfLoops?: "keep" | "drop" | undefined;
388
+ /** Whether parallel inter-block edges merge; default "merge". */
389
+ readonly parallel?: "merge" | "keep" | undefined;
390
+ /** Node columns to keep and how to reduce them; default: drop node columns. */
391
+ readonly nodeReducers?: Readonly<Record<string, ColumnReducer>> | undefined;
392
+ /** Edge columns to keep and how to reduce them; default: drop edge columns. */
393
+ readonly edgeReducers?: Readonly<Record<string, ColumnReducer>> | undefined;
394
+ }
395
+
396
+ // ============================================================ checks and memory
397
+
398
+ /** Options of validate() (design section 11.4). */
399
+ export interface ValidateOptions {
400
+ /** "structure" or "full" per the level table of design section 9.5; default "full". */
401
+ readonly level?: "structure" | "full" | undefined;
402
+ /**
403
+ * Compare the FNV-1a checksums recorded by freeze({ checksum: true }); E_INVALID_SNAPSHOT (details.reason
404
+ * "no-checksum") when none were recorded.
405
+ */
406
+ readonly checksum?: boolean | undefined;
407
+ }
408
+
409
+ /** Options of byteLength(): which side structures to include beyond the core (design section 7.2). */
410
+ export interface ByteLengthOptions {
411
+ /** Include cached views. */
412
+ readonly views?: boolean | undefined;
413
+ /** Include attribute columns. */
414
+ readonly columns?: boolean | undefined;
415
+ /** Include the id map's typed storage. */
416
+ readonly ids?: boolean | undefined;
417
+ }
418
+
419
+ // ============================================================ snapshot
420
+
421
+ /**
422
+ * The frozen graph (design section 3): a CSR core over 4-byte typed arrays, the id map, the
423
+ * attribute tables, the flags and a per-instance view cache. Topology, counts, flags, id map and
424
+ * immutable columns never change after freeze() returns (invariant I17); the column SET of nodes /
425
+ * edges / graph and the CONTENTS of columns declared mutable are mutable side tables (design section
426
+ * 5.8). Every view is a pure function of the core, memoised once and SHARED: writing into a view is
427
+ * a contract violation; call .slice() for scratch. Index-taking queries are total for in-range
428
+ * arguments and unchecked otherwise (design section 11.1); every core accessor throws E_DETACHED
429
+ * after a consuming transfer.
430
+ *
431
+ * Instance contract of the GraphSnapshot class in src/snapshot/graph-snapshot.ts, which implements
432
+ * it; the public barrel exports the class and every public type names the class. isGraphSnapshot()
433
+ * recognises instances structurally through SNAPSHOT_BRAND and formatVersion, never instanceof.
434
+ */
435
+ export interface GraphSnapshotContract extends AdjacencyView {
436
+ /** Symbol.for brand read by isGraphSnapshot() (design section 7.5). */
437
+ readonly [SNAPSHOT_BRAND]: true;
438
+ /** Process-unique identity of the CORE; shared by withColumns() snapshots (design section 5.8). */
439
+ readonly serial: number;
440
+ /** Debugging aid supplied at freeze. */
441
+ readonly label: string | null;
442
+ /** The data-model major (design section 13.5). */
443
+ readonly formatVersion: 1;
444
+ /** Whether the graph is directed; no tri-state (decision C3). */
445
+ readonly directed: boolean;
446
+ /** n, <= MAX_COUNT (invariant I3). */
447
+ readonly nodeCount: number;
448
+ /** Number of logical edges; every edge column has edgeCount rows (invariant I13). */
449
+ readonly edgeCount: number;
450
+ /** colIdx.length: edgeCount when directed, 2 * edgeCount - selfLoopCount when undirected (invariants I6, I7). */
451
+ readonly arcCount: number;
452
+ /** Logical edges with source === target. */
453
+ readonly selfLoopCount: number;
454
+ /** nodeCount + 1 row offsets (invariant I1). */
455
+ readonly rowPtr: U32;
456
+ /** Target node index of each arc, sorted within each row (invariants I2, I4); length 0 when arcCount === 0. */
457
+ readonly colIdx: U32;
458
+ /**
459
+ * arcCount f32 weights; null when unweighted (every weight is 1). Both arcs of an undirected edge carry the same
460
+ * value (I7).
461
+ */
462
+ readonly weights: F32 | null;
463
+ /**
464
+ * arcCount entries: logical edge of each arc (invariant I5); materialised on first access when
465
+ * flags.arcToEdgeIsIdentity.
466
+ */
467
+ readonly arcToEdge: U32;
468
+ /**
469
+ * edgeCount entries: the arc holding the declared orientation (invariant I5); materialised on first access when
470
+ * identity.
471
+ */
472
+ readonly edgeToArc: U32;
473
+ /** Flags kernels branch on (design section 3.8, invariant I9). */
474
+ readonly flags: SnapshotFlags;
475
+ /** The id map (design section 4, invariant I11). */
476
+ readonly ids: NodeIdMap;
477
+ /** Node attribute table, rowCount === nodeCount (invariant I12). */
478
+ readonly nodes: AttributeTable;
479
+ /** Edge attribute table, rowCount === edgeCount, indexed by logical edge (invariants I12, I13). */
480
+ readonly edges: AttributeTable;
481
+ /** Graph attribute table, rowCount === 1 (design section 5.9). */
482
+ readonly graph: AttributeTable;
483
+ /** Extension tables such as GEXF temporal tables, keyed by name (design section 5.10). */
484
+ readonly extensions: ReadonlyMap<string, AttributeTable>;
485
+ /** Graph-level metadata (design section 5.9). */
486
+ readonly meta: GraphMeta;
487
+ /**
488
+ * The arena holding the core arrays (design section 10.3); null when the arrays were adopted from separate buffers.
489
+ */
490
+ readonly arena: ArenaLayout | null;
491
+ /** rowPtr.length === 0: the core was transferred away (design section 9.4); derived, never a stored bit. */
492
+ readonly detached: boolean;
493
+
494
+ // queries (3.9)
495
+
496
+ /**
497
+ * The out-arc range of a node: [rowPtr[u], rowPtr[u + 1]]. Allocates a tuple; hot loops read
498
+ * rowPtr directly.
499
+ * @param u - the node index
500
+ * @returns the half-open arc range as [start, end]
501
+ */
502
+ outArcs(u: number): readonly [start: number, end: number];
503
+ /**
504
+ * rowPtr[u + 1] - rowPtr[u]: the out-arc count (a self-loop counted once, design section 3.4).
505
+ * @param u - the node index
506
+ * @returns the out-degree
507
+ */
508
+ outDegreeOf(u: number): number;
509
+ /**
510
+ * Binary search for the first arc u -> v (the lowest logical edge index among parallels).
511
+ * @param u - the source node index
512
+ * @param v - the target node index
513
+ * @returns the arc index, or INVALID_INDEX when absent
514
+ */
515
+ findArc(u: number, v: number): number;
516
+ /**
517
+ * Whether an arc u -> v exists.
518
+ * @param u - the source node index
519
+ * @param v - the target node index
520
+ * @returns findArc(u, v) !== INVALID_INDEX
521
+ */
522
+ hasArc(u: number, v: number): boolean;
523
+ /**
524
+ * The half-open arc range [lo, hi) of every arc u -> v; empty when lo === hi. Allocates a tuple.
525
+ * @param u - the source node index
526
+ * @param v - the target node index
527
+ * @returns the range as [lo, hi]
528
+ */
529
+ arcsBetween(u: number, v: number): readonly [lo: number, hi: number];
530
+ /**
531
+ * Number of parallel arcs u -> v.
532
+ * @param u - the source node index
533
+ * @param v - the target node index
534
+ * @returns hi - lo of arcsBetween(u, v)
535
+ */
536
+ multiplicity(u: number, v: number): number;
537
+ /**
538
+ * The row containing an arc: O(1) after coo(), else a binary search on rowPtr.
539
+ * @param a - the arc index
540
+ * @returns the source node index
541
+ */
542
+ arcSource(a: number): number;
543
+ /**
544
+ * Declared source of a logical edge: arcSource(edgeToArc[e]).
545
+ * @param e - the logical edge index
546
+ * @returns the source node index
547
+ */
548
+ edgeSource(e: number): number;
549
+ /**
550
+ * Declared target of a logical edge: colIdx[edgeToArc[e]].
551
+ * @param e - the logical edge index
552
+ * @returns the target node index
553
+ */
554
+ edgeTarget(e: number): number;
555
+ /**
556
+ * Lookup through the role "id" edge column, backed by a Map built on first call (design section 4.6).
557
+ * @param id - the edge id
558
+ * @returns the logical edge index, or INVALID_INDEX on a miss or when no id column exists
559
+ */
560
+ edgeIndexOf(id: EdgeId): number;
561
+
562
+ // views (7.2)
563
+
564
+ /**
565
+ * The in-adjacency, rows sorted by source; the forward arrays themselves when undirected. Cached.
566
+ * @returns the reverse view
567
+ */
568
+ reverse(): ReverseView;
569
+ /**
570
+ * Per-arc COO form; src is the only new array. Cached.
571
+ * @returns the COO view
572
+ */
573
+ coo(): CooView;
574
+ /**
575
+ * Every logical edge once in declared orientation. Cached.
576
+ * @returns the edge list view
577
+ */
578
+ edgeList(): EdgeListView;
579
+ /**
580
+ * rowPtr differences materialised; a self-loop counted once. Cached and shared.
581
+ * @returns Uint32Array(n)
582
+ */
583
+ outDegree(): U32;
584
+ /**
585
+ * Arcs targeting each node, via reverse().rowPtr; the same object as outDegree() when undirected. Cached and
586
+ * shared.
587
+ * @returns Uint32Array(n)
588
+ */
589
+ inDegree(): U32;
590
+ /**
591
+ * Graph-theoretic degree (NetworkX convention, design section 3.4): in + out when directed; out plus self-loops
592
+ * when undirected. Cached and shared.
593
+ * @returns Uint32Array(n)
594
+ */
595
+ degree(): U32;
596
+ /**
597
+ * Row sums of weights (a self-loop arc counted once); outDegree widened when unweighted. F64 for CPU precision; may
598
+ * be 0 for a node with out-arcs. Cached and shared.
599
+ * @returns Float64Array(n)
600
+ */
601
+ weightedOutDegree(): F64;
602
+ /**
603
+ * Weight sums over incoming arcs; the same object as weightedOutDegree() when undirected. Cached and shared.
604
+ * @returns Float64Array(n)
605
+ */
606
+ weightedInDegree(): F64;
607
+ /**
608
+ * NetworkX weighted degree: weightedOutDegree + (directed ? weightedInDegree : selfLoopWeight), so sum === 2 *
609
+ * totalWeight() when undirected. Cached and shared.
610
+ * @returns Float64Array(n)
611
+ */
612
+ weightedDegree(): F64;
613
+ /**
614
+ * Sum of weights over each node's self-loop arcs (selfLoopsPerNode widened when unweighted). Cached and shared.
615
+ * @returns Float64Array(n)
616
+ */
617
+ selfLoopWeight(): F64;
618
+ /**
619
+ * Sum of weights over logical edges (each undirected edge once). Cached.
620
+ * @returns the total weight
621
+ */
622
+ totalWeight(): number;
623
+ /**
624
+ * The arcs a with colIdx[a] === row(a), found by binary search per row. Cached and shared.
625
+ * @returns Uint32Array(selfLoopCount)
626
+ */
627
+ selfLoopArcs(): U32;
628
+ /**
629
+ * Self-loop arcs per node. Cached and shared.
630
+ * @returns Uint32Array(n)
631
+ */
632
+ selfLoopsPerNode(): U32;
633
+ /**
634
+ * Point query: self-loop arcs at one node, O(log d).
635
+ * @param u - the node index
636
+ * @returns the count
637
+ */
638
+ selfLoopsAt(u: number): number;
639
+ /**
640
+ * For every arc, the arc storing the opposite orientation of the same edge (a self-loop maps to itself); a lockstep
641
+ * walk (design section 6.4). Undirected only. Cached and shared.
642
+ * @returns Uint32Array(arcCount); E_DIRECTED on a directed snapshot
643
+ */
644
+ mate(): U32;
645
+ /**
646
+ * Nodes ordered by descending out-degree of the forward or reverse adjacency with the cuGraph tier boundaries. Both
647
+ * variants cached.
648
+ * @param options - which adjacency's degree to order by
649
+ * @returns the permutation and its tier offsets
650
+ */
651
+ degreeOrder(options?: DegreeOrderOptions): DegreeOrderView;
652
+ /**
653
+ * Whether the arc set is closed under reversal with equal weights (forward row v equals reverse row v for every v);
654
+ * true without work when undirected. Cached.
655
+ * @returns true when symmetric
656
+ */
657
+ isSymmetric(): boolean;
658
+ /**
659
+ * Compute a set of views eagerly (inside freeze() through FreezeOptions.prepare, or off the critical path).
660
+ * @param views - the views to materialise
661
+ * @returns this snapshot
662
+ */
663
+ prepare(views: readonly ViewName[]): this;
664
+ /** Release every cached view and every cached gpuView copy; they are recomputed on demand. */
665
+ dropCaches(): void;
666
+ /**
667
+ * Which views are resident.
668
+ * @returns the names of the cached views
669
+ */
670
+ cachedViews(): readonly ViewName[];
671
+
672
+ // derived graphs (7.3)
673
+
674
+ /**
675
+ * Every directed edge becomes undirected; reciprocal pairs collapse to one edge keeping the lower index's row
676
+ * (keep-first). Returns `{ snapshot: this, null maps }` on an undirected snapshot.
677
+ * @param options - reciprocal filtering and the weight reducer
678
+ * @returns the derived graph
679
+ */
680
+ toUndirected(options?: ToUndirectedOptions): DerivedGraph;
681
+ /**
682
+ * Orientation of every edge swapped: the reverse view's arrays become the core. Returns this on an undirected
683
+ * snapshot.
684
+ * @returns the derived graph (same node and edge spaces)
685
+ */
686
+ transpose(): DerivedGraph;
687
+ /**
688
+ * One edge per (u, v) group (parallels are adjacent by invariant I4), survivor = lowest index; flags.multigraph is
689
+ * false afterwards.
690
+ * @param options - reducers and self-loop policy
691
+ * @returns the derived graph
692
+ */
693
+ simplified(options?: SimplifyOptions): DerivedGraph;
694
+ /**
695
+ * Every edge with source !== target.
696
+ * @returns the derived graph
697
+ */
698
+ withoutSelfLoops(): DerivedGraph;
699
+ /**
700
+ * Keep the logical edges whose mask bit is set (a rebuild; iterative algorithms keep their own alive bitmap
701
+ * instead).
702
+ * @param keep - packed bitmap over logical edges; E_MASK_LENGTH when shorter than ceil(edgeCount / 32) words
703
+ * @returns the derived graph
704
+ */
705
+ filterEdges(keep: EdgeMask): DerivedGraph;
706
+ /**
707
+ * The subgraph induced by a node selection: an index list (order = new index order; E_INDEX_RANGE for an
708
+ * out-of-range or repeated index) or a packed mask (ascending order; E_MASK_LENGTH when short). Edges with both
709
+ * endpoints kept.
710
+ * @param selection - the node indices or a mask
711
+ * @returns the derived graph (compact new node space)
712
+ */
713
+ inducedSubgraph(selection: U32 | { readonly mask: NodeMask }): DerivedGraph;
714
+ /**
715
+ * Contract the nodes of each partition block into one node (design section 7.3): labels already forming 0..k-1 are
716
+ * kept as block indices, any other labelling is renumbered in first-seen order; E_PARTITION for a wrong length or
717
+ * an INVALID_INDEX label.
718
+ * @param partition - one label per node
719
+ * @param options - weight reducer, self-loop and parallel policies, column reducers
720
+ * @returns the derived graph with blockSizes and an identity id map
721
+ */
722
+ contract(partition: U32, options?: ContractOptions): DerivedGraph;
723
+ /**
724
+ * Permute the node space: perm[newIndex] = oldIndex; the id map follows; edge order is preserved. Never implicit
725
+ * (decision C18).
726
+ * @param perm - a permutation of 0..n-1; E_INVALID_PERMUTATION otherwise
727
+ * @returns the derived graph
728
+ */
729
+ relabel(perm: U32): DerivedGraph;
730
+ /**
731
+ * A new snapshot object sharing the core, the id map and the serial with a CLONED column set plus the given columns
732
+ * (the only operation that clones the column set).
733
+ * @param nodes - node columns to add, keyed by name
734
+ * @param edges - edge columns to add, keyed by name
735
+ * @returns the new snapshot
736
+ */
737
+ withColumns(
738
+ nodes?: Readonly<Record<string, TypedArrayData | ColumnInput>>,
739
+ edges?: Readonly<Record<string, TypedArrayData | ColumnInput>>,
740
+ ): GraphSnapshot;
741
+
742
+ // memory, transfer, checks (9, 11)
743
+
744
+ /**
745
+ * Resident bytes of the core, plus the side structures selected by the options.
746
+ * @param options - which side structures to include
747
+ * @returns the byte count
748
+ */
749
+ byteLength(options?: ByteLengthOptions): number;
750
+ /**
751
+ * A 64-bit content hash of the core arrays (two 32-bit FNV-1a lanes) as 16 hex characters, computed lazily and
752
+ * cached (design section 9.3).
753
+ * @returns the hash
754
+ */
755
+ contentHash(): string;
756
+ /**
757
+ * The distinct, exclusively owned backing buffers of the core, id map, typed columns, string stores and extensions:
758
+ * the postMessage transfer list (design section 9.1).
759
+ * @returns the buffers
760
+ */
761
+ transferables(): ArrayBuffer[];
762
+ /**
763
+ * The plain-object wire form: a JSON-serialisable manifest plus ArrayBuffers (design section 9.1). Allocates
764
+ * nothing for typed data except lazily kept representations on first use.
765
+ * @param options - transfer mode, views and columns to include
766
+ * @returns the wire snapshot; E_UNSUPPORTED on a big-endian host
767
+ */
768
+ toWire(options?: ToWireOptions): WireSnapshot;
769
+ /**
770
+ * The GSNP byte container as one contiguous buffer (design section 9.2).
771
+ * @param options - views to include
772
+ * @returns the container bytes; E_UNSUPPORTED on a big-endian host
773
+ */
774
+ toBytes(options?: ToBytesOptions): U8;
775
+ /**
776
+ * The GSNP container as a sequence: header plus manifest, then each 256-padded segment in manifest order, for
777
+ * streaming writers.
778
+ * @param options - views to include
779
+ * @returns the chunks
780
+ */
781
+ toByteChunks(options?: ToBytesOptions): Iterable<U8>;
782
+ /**
783
+ * Check the invariants (design section 11.4); throws E_INVALID_SNAPSHOT with details.invariant and the location on
784
+ * the first violation.
785
+ * @param options - level and checksum comparison
786
+ */
787
+ validate(options?: ValidateOptions): void;
788
+ }
789
+
790
+ // ============================================================ factory inputs (8.1)
791
+
792
+ /**
793
+ * COO typed arrays with dense indices: the 20 ms path of fromEdgeArrays() (design section 8.1). No
794
+ * id Map is built unless `ids` is given.
795
+ */
796
+ export interface EdgeArraysInput {
797
+ /** Whether the graph is directed. */
798
+ readonly directed: boolean;
799
+ /** Required unless `ids` is given; isolates are preserved. */
800
+ readonly nodeCount?: number | undefined;
801
+ /** Optional external ids in index order (length = nodeCount). */
802
+ readonly ids?: readonly NodeId[] | F64 | undefined;
803
+ /** Source node index of every edge. */
804
+ readonly src: U32;
805
+ /** Target node index of every edge. */
806
+ readonly dst: U32;
807
+ /** Per-edge weights; F64 is downcast to f32 and an f64 shadow column kept only when not f32-exact. */
808
+ readonly weights?: F32 | F64 | undefined;
809
+ /** Node columns, keyed by name. */
810
+ readonly nodeColumns?: Readonly<Record<string, TypedArrayData | ColumnInput>> | undefined;
811
+ /** Edge columns, keyed by name. */
812
+ readonly edgeColumns?: Readonly<Record<string, TypedArrayData | ColumnInput>> | undefined;
813
+ /** Graph metadata. */
814
+ readonly meta?: GraphMetaPatch | undefined;
815
+ }
816
+
817
+ /**
818
+ * Prebuilt CSR arrays adopted by fromCsr() without copying by default (design section 8.1): the
819
+ * caller transfers ownership and must not mutate them afterwards.
820
+ */
821
+ export interface CsrInput {
822
+ /** Whether the graph is directed. */
823
+ readonly directed: boolean;
824
+ /** Number of nodes. */
825
+ readonly nodeCount: number;
826
+ /** nodeCount + 1 row offsets. */
827
+ readonly rowPtr: U32;
828
+ /** Target node index of every arc. */
829
+ readonly colIdx: U32;
830
+ /** Per-arc weights, or null / absent when unweighted. */
831
+ readonly weights?: F32 | null | undefined;
832
+ /** Absent => identity (directed only; undirected input must supply it). */
833
+ readonly arcToEdge?: U32 | undefined;
834
+ /** Absent => derived in one O(m) pass (or identity). */
835
+ readonly edgeToArc?: U32 | undefined;
836
+ /** Defaults to arcCount (directed) or is derived from arcToEdge. */
837
+ readonly edgeCount?: number | undefined;
838
+ /** Optional external ids in index order. */
839
+ readonly ids?: readonly NodeId[] | F64 | undefined;
840
+ /** Node columns, keyed by name. */
841
+ readonly nodeColumns?: Readonly<Record<string, TypedArrayData | ColumnInput>> | undefined;
842
+ /** Edge columns, keyed by name. */
843
+ readonly edgeColumns?: Readonly<Record<string, TypedArrayData | ColumnInput>> | undefined;
844
+ /** Graph metadata. */
845
+ readonly meta?: GraphMetaPatch | undefined;
846
+ /** Flag claims; verified unless validate === "none". */
847
+ readonly flags?: FlagClaims | undefined;
848
+ }
849
+
850
+ /** Options of fromCsr() (design section 8.1). */
851
+ export interface FromCsrOptions {
852
+ /** Validation level; default "full" because adopted arrays typically come from a file or the network. */
853
+ readonly validate?: ValidationLevel | undefined;
854
+ /** Copy the arrays instead of adopting them; default false. */
855
+ readonly copy?: boolean | undefined;
856
+ /**
857
+ * Default true: check invariant I4 and rebuild through the freeze pipeline when rows are unsorted; false asserts
858
+ * sorted rows.
859
+ */
860
+ readonly sortRows?: boolean | undefined;
861
+ }
862
+
863
+ /**
864
+ * Plain records, the node-link shape every JSON dialect parses into and what graphty-element's data
865
+ * sources emit (design section 8.1).
866
+ */
867
+ export interface RecordsInput {
868
+ /** Whether the graph is directed. */
869
+ readonly directed: boolean;
870
+ /** Node records; optional when every node appears as an edge endpoint. */
871
+ readonly nodes?: Iterable<Readonly<Record<string, unknown>>> | undefined;
872
+ /** Edge records. */
873
+ readonly edges: Iterable<Readonly<Record<string, unknown>>>;
874
+ /** Node id key; default "id"; null = node index is array position and endpoints are indices (d3 v3). */
875
+ readonly nodeId?: string | null | undefined;
876
+ /** Edge source key; default "source", falling back to "src" / "from". */
877
+ readonly edgeSource?: string | undefined;
878
+ /** Edge target key; default "target", falling back to "dst" / "to". */
879
+ readonly edgeTarget?: string | undefined;
880
+ /** Edge weight key; default "weight"; null = unweighted. */
881
+ readonly edgeWeight?: string | null | undefined;
882
+ /** Column handling; default "infer" (design section 5.1 widening). */
883
+ readonly columns?: "infer" | "json" | "none" | readonly ColumnDecl[] | undefined;
884
+ /** Id coercion; default "keep" (values are already typed). */
885
+ readonly ids?: IdCoercion | undefined;
886
+ }