Low-Level Buffer Access
The chainable attribute writers are the recommended default for examples and
application code, but the low-level buffer API is still essential. Use
withBufferAccess(...) when you need to write millions of values, integrate a
custom parser, fill several typed arrays in a carefully controlled loop, or
avoid intermediate JavaScript objects.
The key rule is: allocate first, view second. WASM memory can grow after
allocation-prone calls, and growth can invalidate TypedArray views. Helios
Network enforces this by requiring direct buffer access inside
withBufferAccess(...), where allocation-prone operations can throw instead of
silently invalidating a view.
Fast Bulk Attribute Writes
Define attributes and perform any allocation-prone setup before entering
withBufferAccess(...). Inside the callback, take the views, write them, and
leave. Bump attribute versions once after the bulk write so downstream renderers
and mappers know the data changed.
When To Prefer Each API
Use chainable writers when:
- values come from ordinary row data;
- examples need to stay readable;
- attribute schemas can be inferred or expressed with simple options;
- callbacks are clear enough and performance is not dominated by the writer.
Use withBufferAccess(...) when:
- you are filling large typed arrays;
- you need one tight loop over multiple buffers;
- you are adapting an existing binary parser or scientific data format;
- you need explicit control over every allocation and version bump.
Both APIs write into the same graph. The high-level helpers use safe buffer access internally; the low-level API exposes that mechanism directly.
{"importMap": {"helios-web": "../vendor/helios/helios-web.es.js", "helios-network": "../vendor/helios/helios-network.js"}, "examples": [{"id": "examples--helios-network--buffer-access.md--example-1", "title": "Use Direct WASM Buffer Views", "render": false, "console": true, "autorun": true, "layout": "split", "width": null, "height": "470px", "headerName": null, "headerCode": "", "bodyName": "helios_network_buffer_access", "bodyCode": "import HeliosNetwork, { AttributeType } from \"helios-network\";\n\nconst network = await HeliosNetwork.create({ directed: false });\nconst nodes = network.addNodes(10);\nconst edges = network.addEdges(Array.from(nodes).map((node, index) => [\n node,\n nodes[(index + 1) % nodes.length],\n]));\n\nnetwork.defineNodeAttribute('score', AttributeType.Float, 1);\nnetwork.defineEdgeAttribute('weight', AttributeType.Float, 1);\n\nnetwork.withBufferAccess(() => {\n const score = network.getNodeAttributeBuffer('score').view;\n const weight = network.getEdgeAttributeBuffer('weight').view;\n\n nodes.forEach((node, index) => {\n score[node] = index / (nodes.length - 1);\n });\n edges.forEach((edge, index) => {\n weight[edge] = 1 + index * 0.1;\n });\n}, { nodeIndices: true, edgeIndices: true });\n\nnetwork.bumpNodeAttributeVersion('score');\nnetwork.bumpEdgeAttributeVersion('weight');\n\nconsole.log({\n score: network.getNodeAttributeInfo('score'),\n weight: network.getEdgeAttributeInfo('weight'),\n});", "headerRefs": [], "bodyRefs": []}]}