PageSourceSearch

https://one-vv8137.com/resources/v1/app/static/mf/shared/vue/3.5.35/vue-guarded.esm-browser.prod.js

js one-vv8137.com collected 2026-10-10 02:44:18 UTC 3,574 bytes, 143 lines download raw bytes

1// Guarded Vue runtime — detects/suppresses infinite watcher loops in production. See patches/vue+3.5.26.md
2
3export * from './vue.esm-browser.prod.js';
4
5import {
6  getCurrentInstance,
7  watch as _watch,
8  watchEffect as _watchEffect,
9} from './vue.esm-browser.prod.js';
10
11let globalEnabled = true;
12
13const tickCounters = new Map();
14let resetScheduled = false;
15
16function scheduleCounterReset() {
17  if (!resetScheduled) {
18    resetScheduled = true;
19    queueMicrotask(() => {
20      tickCounters.clear();
21      resetScheduled = false;
22    });
23  }
24}
25
26function incrementAndGet(id) {
27  scheduleCounterReset();
28  const count = (tickCounters.get(id) || 0) + 1;
29  tickCounters.set(id, count);
30  return count;
31}
32
33function resolveComponentName() {
34  try {
35    const instance = getCurrentInstance();
36    return (
37      instance?.type?.__name ??
38      instance?.type?.name ??
39      undefined
40    );
41  } catch {
42    return undefined;
43  }
44}
45
46let globalOnLoop;
47
48function defaultOnLoop(info) {
49  console.error(
50    `[WatcherLoopGuard] Watcher loop detected (>${info.limit} calls/tick)\n` +
51      `  Component: ${info.componentName ?? '<unknown>'}\n` +
52      `  Source: ${info.source}` +
53      (info.watchValues
54        ? `\n  New value: ${JSON.stringify(info.watchValues.newValue)}\n  Old value: ${JSON.stringify(info.watchValues.oldValue)}`
55        : ''),
56    '\n' + info.stack,
57  );
58}
59
60function createGuard(sourceDesc, limit, onLoop) {
61  const id = Symbol('watcher-guard');
62  const componentName = resolveComponentName();
63
64  return (watchValues) => {
65    if (!globalEnabled) return true;
66
67    const count = incrementAndGet(id);
68
69    if (count > limit) {
70      if (count === limit + 1) {
71        const info = {
72          count,
73          limit,
74          componentName,
75          source: sourceDesc,
76          stack: new Error('WatcherLoopGuard').stack || '',
77          watchValues,
78        };
79        onLoop(info);
80        if (globalOnLoop) globalOnLoop(info);
81      }
82      return false;
83    }
84
85    return true;
86  };
87}
88
89function createGuardedWatch(config) {
90  const limit = config?.limit ?? 100;
91  const onLoop = config?.onLoop ?? defaultOnLoop;
92
93  return function guardedWatch(source, callback, options) {
94    const sourceDesc =
95      typeof source === 'function'
96        ? `source: ${source.toString().slice(0, 100)}`
97        : `callback: ${callback.toString().slice(0, 100)}`;
98    const check = createGuard(sourceDesc, limit, onLoop);
99
100    const wrappedCallback = (...args) => {
101      if (!check({ newValue: args[0], oldValue: args[1] })) return;
102      return callback(...args);
103    };
104
105    return _watch(source, wrappedCallback, options);
106  };
107}
108
109function createGuardedWatchEffect(config) {
110  const limit = config?.limit ?? 100;
111  const onLoop = config?.onLoop ?? defaultOnLoop;
112
113  return (effect, options) => {
114    const check = createGuard(effect.toString().slice(0, 200), limit, onLoop);
115
116    return _watchEffect((onCleanup) => {
117      if (!check()) return;
118      effect(onCleanup);
119    }, options);
120  };
121}
122
123const _cfg = typeof window !== 'undefined' && window.INITIAL_DATA?.watcherLoopGuard;
124
125if (_cfg && _cfg.enabled === false) {
126  globalEnabled = false;
127}
128
129const _limit = _cfg?.limit;
130
131export const watch = createGuardedWatch(_limit ? { limit: _limit } : {});
132export const watchEffect = createGuardedWatchEffect(_limit ? { limit: _limit } : {});
133
134if (typeof window !== 'undefined') {
135  window.__watcherLoopGuard = {
136    setEnabled: (v) => {
137      globalEnabled = !!v;
138    },
139    setOnLoop: (fn) => {
140      globalOnLoop = typeof fn === 'function' ? fn : undefined;
141    },
142  };
143}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.