Skip to content

feat(datamodel): introduce side-effect free element accessors#87

Merged
char0n merged 3 commits intomainfrom
char0n/element-accessors
Feb 12, 2026
Merged

feat(datamodel): introduce side-effect free element accessors#87
char0n merged 3 commits intomainfrom
char0n/element-accessors

Conversation

@char0n
Copy link
Member

@char0n char0n commented Feb 12, 2026

No description provided.

@char0n char0n requested a review from Copilot February 12, 2026 09:02
@char0n char0n self-assigned this Feb 12, 2026
@char0n char0n added the enhancement New feature or request label Feb 12, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request attempts to introduce side-effect-free element accessors by modifying the getMetaProperty method and the id, classes, and links property getters in the Element class. The changes aim to prevent automatic creation and storage of meta properties when they don't exist.

Changes:

  • Modified getMetaProperty to return a new refracted element without storing it when a property doesn't exist
  • Updated id, classes, and links getters to explicitly call setMetaProperty before accessing properties
  • Updated documentation comment for getMetaProperty

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +484 to +485
if (!this.hasMetaProperty(name)) {
if (defaultValue === undefined) {
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getMetaProperty uses defaultValue === undefined to decide whether a default was provided. This makes getMetaProperty(name, undefined) indistinguishable from calling it without a default, which changes behavior compared to passing an explicit default. Use arguments.length (or similar) to distinguish “no default argument” from “default explicitly set to undefined”.

Suggested change
if (!this.hasMetaProperty(name)) {
if (defaultValue === undefined) {
const hasDefaultArg = arguments.length >= 2;
if (!this.hasMetaProperty(name)) {
if (!hasDefaultArg) {

Copilot uses AI. Check for mistakes.
Comment on lines +481 to 495
public getMetaProperty(name: string, defaultValue: unknown): Element;
public getMetaProperty(name: string): Element | undefined;
public getMetaProperty(name: string, defaultValue?: unknown): Element | undefined {
if (!this.hasMetaProperty(name)) {
if (defaultValue === undefined) {
return undefined;
}
const element = this.refract(defaultValue);
if (element && this.isFrozen) {
element.freeze();
return element;
}
this.meta.set(name, defaultValue);
return element;
}
return this.meta.get(name)!;
}
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overload getMetaProperty(name, defaultValue): Element is not guaranteed by the implementation: if the meta key exists with an explicit undefined value (possible via setMetaProperty/ObjectElement.set), this.meta.get(name) returns undefined, even when a defaultValue is provided. Either prevent storing undefined for meta properties, treat undefined values as “missing” when reading (so the default applies), or relax the overload return type to Element | undefined to match runtime behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +478 to +479
* Note: Each call with a default creates a new instance. Use setMetaProperty
* first if you need reference equality across multiple accesses.
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc note “Each call with a default creates a new instance” is misleading once the property exists (the stored value is returned and the default is ignored). Consider clarifying that this only applies when the property is missing, to avoid confusing callers about reference equality semantics.

Suggested change
* Note: Each call with a default creates a new instance. Use setMetaProperty
* first if you need reference equality across multiple accesses.
* Note: When the property is missing, each call that supplies a default
* creates a new instance (the value is not cached). Once the property
* exists, the stored value is returned and the default is ignored. Use
* setMetaProperty first if you need reference equality across multiple
* accesses.

Copilot uses AI. Check for mistakes.
@char0n char0n merged commit f93b066 into main Feb 12, 2026
7 checks passed
@char0n char0n deleted the char0n/element-accessors branch February 12, 2026 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant