Spaces:
Configuration error
Configuration error
| // One answer to "did this actually change?". | |
| // | |
| // Several places need it for the same reason: a write is not free. Assigning an | |
| // equal value to a store ref still fires the url sync and lands a history | |
| // entry, and handing the manager an equal scene still tears components down and | |
| // rebuilds them. Decoded values arrive as fresh arrays and objects every time, | |
| // so identity alone never says no. | |
| interface Comparable { | |
| [key: string]: unknown; | |
| } | |
| /** | |
| * Structural comparison, short-circuiting on identity. Deliberately not | |
| * JSON-based: `enabledSatellites` can hold thousands of names with Starlink | |
| * enabled, and serialising that on every toggle to avoid a write is the wrong | |
| * trade. This walks and stops at the first difference, allocating nothing for | |
| * the common case of two lists of strings. | |
| */ | |
| export function sameValue(a: unknown, b: unknown): boolean { | |
| if (a === b) { | |
| return true; | |
| } | |
| // Checked before the object branch: an array and a plain object are both | |
| // typeof "object", and an empty one of each has zero keys. | |
| if (Array.isArray(a) || Array.isArray(b)) { | |
| return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((entry, index) => sameValue(entry, b[index])); | |
| } | |
| if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) { | |
| return false; | |
| } | |
| const keys = Object.keys(a); | |
| return keys.length === Object.keys(b).length && keys.every((key) => sameValue((a as Comparable)[key], (b as Comparable)[key])); | |
| } | |