← tsb playground
attrs — User-Defined Metadata
Attach arbitrary key→value metadata to any Series or DataFrame
— mirrors
pandas.DataFrame.attrs and
pandas.Series.attrs.
Design note: Because tsb objects are immutable (their data, index,
and dtype are frozen), attrs are stored in a WeakMap registry rather than as
instance properties. This means attrs are attached & detached without touching the object
itself, and garbage-collected automatically when the object is collected.
Basic usage
import {
getAttrs, setAttrs, updateAttrs, copyAttrs, withAttrs,
clearAttrs, hasAttrs, getAttr, setAttr, deleteAttr,
attrsCount, attrsKeys, mergeAttrs,
} from "tsb";
import { DataFrame, Series } from "tsb";
// ─── annotate a DataFrame ─────────────────────────────────────────────────
const df = DataFrame.fromColumns({
temperature: [22.1, 23.5, 21.8],
humidity: [55, 60, 58],
});
setAttrs(df, {
source: "weather_station_42",
unit: "Celsius",
notes: "Morning readings",
});
getAttrs(df);
// → { source: "weather_station_42", unit: "Celsius", notes: "Morning readings" }
getAttr(df, "unit"); // → "Celsius"
getAttr(df, "missing"); // → undefined
attrsCount(df); // → 3
attrsKeys(df); // → ["source", "unit", "notes"]
hasAttrs(df); // → true
Merging and updating
// updateAttrs merges new keys, preserves existing
updateAttrs(df, { version: 2, notes: "Updated notes" });
getAttrs(df);
// → { source: "weather_station_42", unit: "Celsius", notes: "Updated notes", version: 2 }
// setAttr / deleteAttr for single keys
setAttr(df, "sensor_id", "WS-042");
deleteAttr(df, "notes");
getAttrs(df);
// → { source: "weather_station_42", unit: "Celsius", version: 2, sensor_id: "WS-042" }
Propagating metadata to derived objects
// copyAttrs: copy all attrs from one object to another
const s = new Series({ data: [22.1, 23.5, 21.8], name: "temperature" });
setAttrs(s, { unit: "Celsius", source: "sensor_A" });
const derived = new Series({ data: [71.8, 74.3, 71.2], name: "fahrenheit" });
copyAttrs(s, derived);
getAttrs(derived);
// → { unit: "Celsius", source: "sensor_A" }
// Then update the copy
setAttr(derived, "unit", "Fahrenheit");
getAttrs(derived); // → { unit: "Fahrenheit", source: "sensor_A" }
getAttrs(s); // → { unit: "Celsius", source: "sensor_A" } ← unchanged
Fluent helper — withAttrs
// withAttrs sets attrs and returns the same object reference
// Handy for inline annotation
const annotated = withAttrs(
DataFrame.fromColumns({ x: [1, 2, 3] }),
{ source: "lab_experiment", date: "2026-04-09" },
);
annotated === annotated; // true — same reference, not a copy
getAttrs(annotated);
// → { source: "lab_experiment", date: "2026-04-09" }
Merging from multiple sources
// mergeAttrs: combine attrs from multiple objects into a target
const s1 = new Series({ data: [1, 2, 3], name: "a" });
const s2 = new Series({ data: [4, 5, 6], name: "b" });
setAttrs(s1, { source: "sensor_A", unit: "kg" });
setAttrs(s2, { source: "sensor_B", scale: 2.5 });
const combined = DataFrame.fromColumns({ a: [1, 2, 3], b: [4, 5, 6] });
mergeAttrs([s1, s2], combined);
// Later sources win on conflicts: source="sensor_B"
getAttrs(combined);
// → { source: "sensor_B", unit: "kg", scale: 2.5 }
Clearing metadata
setAttrs(df, { x: 1, y: 2 });
hasAttrs(df); // → true
attrsCount(df); // → 2
clearAttrs(df);
hasAttrs(df); // → false
getAttrs(df); // → {}
API reference
| Function | Description |
| getAttrs(obj) | Return a shallow copy of all stored attrs (empty {} if none) |
| setAttrs(obj, attrs) | Overwrite attrs completely with the given record |
| updateAttrs(obj, updates) | Merge updates into existing attrs (existing keys preserved) |
| withAttrs(obj, attrs) | Fluent: set attrs and return the same object |
| copyAttrs(source, target) | Copy all attrs from source to target |
| mergeAttrs(sources[], target) | Merge attrs from multiple sources; later sources win |
| clearAttrs(obj) | Remove all attrs from obj |
| hasAttrs(obj) | Return true if any attrs are set |
| getAttr(obj, key) | Get a single attr value (undefined if missing) |
| setAttr(obj, key, value) | Set a single attr, preserving other keys |
| deleteAttr(obj, key) | Delete a single attr key |
| attrsCount(obj) | Number of stored attr keys |
| attrsKeys(obj) | Array of stored attr key names |
Comparison with pandas
| pandas | tsb |
df.attrs | getAttrs(df) |
df.attrs = {"k": "v"} | setAttrs(df, { k: "v" }) |
df.attrs["k"] = "v" | setAttr(df, "k", "v") |
df.attrs["k"] | getAttr(df, "k") |
del df.attrs["k"] | deleteAttr(df, "k") |
df.attrs.update(d) | updateAttrs(df, d) |
df.attrs.clear() | clearAttrs(df) |