@jsenv/navi 0.29.392 → 0.29.393

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29164,39 +29164,43 @@ const idUsageMap = new Map();
29164
29164
  // Keys found in the entry with nobody to claim them, already reported.
29165
29165
  const orphanKeysReported = new Set();
29166
29166
  const useNavStateWithWarnings = (id, options) => {
29167
- const idRef = useRef(undefined);
29168
- if (idRef.current !== id) {
29169
- const oldId = idRef.current;
29170
- idUsageMap.delete(oldId);
29171
- idRef.current = id;
29167
+ const ownerRef = useRef(null);
29168
+ if (!ownerRef.current) {
29169
+ ownerRef.current = {};
29170
+ }
29171
+ const owner = ownerRef.current;
29172
+ // Claimed during render so warnAboutOrphanGeneratedKeys sees every id of
29173
+ // the commit, including the ones whose effect has not run yet. The conflict
29174
+ // is judged in the effect: when a screen replaces another in one commit,
29175
+ // preact renders the new children before unmounting the old ones, so at
29176
+ // render time the id may still be held by a component about to go.
29177
+ if (id !== undefined && !idUsageMap.has(id)) {
29178
+ idUsageMap.set(id, { owner, stackTrace: new Error().stack });
29179
+ }
29172
29180
 
29181
+ useEffect(() => {
29182
+ if (id === undefined) {
29183
+ return undefined;
29184
+ }
29173
29185
  const usage = idUsageMap.get(id);
29174
- if (!usage) {
29175
- idUsageMap.set(id, {
29176
- stackTrace: new Error().stack,
29177
- });
29178
- } else {
29186
+ if (usage && usage.owner !== owner) {
29179
29187
  console.warn(
29180
29188
  `useNavState ID conflict detected!
29181
29189
  ID "${id}" is already in use by another component.
29182
29190
  This can cause UI state conflicts and unexpected behavior.
29183
29191
  Consider using unique IDs for each component instance.`,
29184
29192
  );
29185
- }
29186
- }
29187
-
29188
- useEffect(() => {
29189
- // Registered here as well as in the render above: preact/compat's
29190
- // Suspense parks a subtree by running every hook cleanup in it, and the
29191
- // render resuming it carries the same id.
29192
- if (!idUsageMap.has(id)) {
29193
- idUsageMap.set(id, {
29194
- stackTrace: new Error().stack,
29195
- });
29193
+ } else {
29194
+ // Also set when absent: preact/compat's Suspense parks a subtree by
29195
+ // running every hook cleanup in it, and the render resuming it carries
29196
+ // the same id.
29197
+ idUsageMap.set(id, { owner, stackTrace: new Error().stack });
29196
29198
  }
29197
29199
  warnAboutOrphanGeneratedKeys();
29198
29200
  return () => {
29199
- idUsageMap.delete(id);
29201
+ if (idUsageMap.get(id)?.owner === owner) {
29202
+ idUsageMap.delete(id);
29203
+ }
29200
29204
  };
29201
29205
  }, [id]);
29202
29206