fix: make update operator lazy

This commit is contained in:
2026-01-14 18:39:36 +08:00
parent 55825788b8
commit 62abfff439
2 changed files with 26 additions and 6 deletions

View File

@@ -50,7 +50,7 @@ export const select = (obj: NixValue, attrpath: NixValue[]): NixValue => {
let attrs = forceAttrs(obj); let attrs = forceAttrs(obj);
for (const attr of attrpath.slice(0, -1)) { for (const attr of attrpath.slice(0, -1)) {
const key = forceString(attr) const key = forceString(attr);
if (!(key in attrs)) { if (!(key in attrs)) {
throw new Error(`Attribute '${key}' not found`); throw new Error(`Attribute '${key}' not found`);
} }
@@ -63,7 +63,7 @@ export const select = (obj: NixValue, attrpath: NixValue[]): NixValue => {
attrs = cur; attrs = cur;
} }
const last = forceString(attrpath[attrpath.length - 1]) const last = forceString(attrpath[attrpath.length - 1]);
if (!(last in attrs)) { if (!(last in attrs)) {
throw new Error(`Attribute '${last}' not found`); throw new Error(`Attribute '${last}' not found`);
} }
@@ -74,9 +74,9 @@ export const selectWithDefault = (obj: NixValue, attrpath: NixValue[], default_v
let attrs = forceAttrs(obj); let attrs = forceAttrs(obj);
for (const attr of attrpath.slice(0, -1)) { for (const attr of attrpath.slice(0, -1)) {
const key = forceString(attr) const key = forceString(attr);
if (!(key in attrs)) { if (!(key in attrs)) {
return default_val return default_val;
} }
const cur = force(attrs[key]); const cur = force(attrs[key]);
if (!isAttrs(cur)) { if (!isAttrs(cur)) {
@@ -87,7 +87,7 @@ export const selectWithDefault = (obj: NixValue, attrpath: NixValue[], default_v
const last = forceString(attrpath[attrpath.length - 1]); const last = forceString(attrpath[attrpath.length - 1]);
if (last in attrs) { if (last in attrs) {
return attrs[last] return attrs[last];
} }
return default_val; return default_val;
}; };

View File

@@ -175,6 +175,26 @@ export const op = {
}, },
update: (a: NixValue, b: NixValue): NixAttrs => { update: (a: NixValue, b: NixValue): NixAttrs => {
return { ...forceAttrs(a), ...forceAttrs(b) }; const forcedA = forceAttrs(a);
const forcedB = forceAttrs(b);
const newAttrs: NixAttrs = {};
for (const key in forcedA) {
Object.defineProperty(newAttrs, key, {
get: () => force(forcedA[key]),
enumerable: true,
configurable: true,
});
}
for (const key in forcedB) {
Object.defineProperty(newAttrs, key, {
get: () => force(forcedB[key]),
enumerable: true,
configurable: true,
});
}
return newAttrs;
}, },
}; };