@wix/zero-config-implementation 1.8.0 → 1.9.0

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.
@@ -9,41 +9,23 @@ import type { ExtractedElement } from './extractors/core/tree-builder'
9
9
  // Prop Spy (for tracking prop access)
10
10
  // ─────────────────────────────────────────────────────────────────────────────
11
11
 
12
- export const PROP_SPY_SYMBOL = Symbol.for('__prop_spy__')
13
-
14
12
  export interface PropSpyMeta {
15
13
  path: string
16
14
  propName: string
17
- uniqueId: string
18
15
  originalValue: unknown
19
16
  }
20
17
 
21
- export interface PropSpy<T = unknown> {
22
- [PROP_SPY_SYMBOL]: true
23
- __meta: PropSpyMeta
24
- valueOf: () => T
25
- toString: () => string
26
- toJSON: () => T
27
- [Symbol.toPrimitive]?: (hint: string) => T | string | number
28
- }
29
-
30
18
  // ─────────────────────────────────────────────────────────────────────────────
31
19
  // Tracking Stores
32
20
  // ─────────────────────────────────────────────────────────────────────────────
33
21
 
34
- export interface PropReadInfo {
35
- components: Set<string>
36
- value: unknown
37
- }
38
-
39
22
  export interface PropWriteInfo {
40
23
  elements: Map<string, { tag: string; elementId: string }>
41
24
  attributes: Map<string, { attr: string; concatenated: boolean }>
42
25
  }
43
26
 
44
27
  export interface TrackingStores {
45
- reads: Map<string, PropReadInfo>
46
- writes: Map<string, PropWriteInfo>
28
+ propUsages: Map<string, PropWriteInfo>
47
29
  }
48
30
 
49
31
  // ─────────────────────────────────────────────────────────────────────────────
@@ -58,7 +40,8 @@ export interface DOMBinding {
58
40
  }
59
41
 
60
42
  export interface CoupledProp extends PropInfo {
61
- bindings: DOMBinding[]
43
+ /** Full stores.propUsages key for this prop, e.g. "props.linkUrl". */
44
+ propPath: string
62
45
  logicOnly: boolean
63
46
  }
64
47
 
@@ -67,4 +50,5 @@ export interface CoupledComponentInfo {
67
50
  props: Record<string, CoupledProp>
68
51
  elements: ExtractedElement[]
69
52
  innerElementProps?: Map<string, Record<string, CoupledProp>>
53
+ propUsages: TrackingStores['propUsages']
70
54
  }
@@ -6,21 +6,49 @@
6
6
  import { faker } from '@faker-js/faker'
7
7
  import type { ComponentInfo, DefaultValue, PropInfo, ResolvedType } from '../../ts/types'
8
8
 
9
+ // Unique primes used as traceable number values. Each rendered number prop gets
10
+ // one; the value is distinct enough to be identified in DOM attributes later.
11
+ const TRACEABLE_PRIMES = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
12
+ const FALLBACK_NUMBER_BASE = 101
13
+ let primeIndex = 0
14
+
15
+ function nextTraceableNumber(): number {
16
+ const withinPrimeList = primeIndex < TRACEABLE_PRIMES.length
17
+ if (withinPrimeList) {
18
+ return TRACEABLE_PRIMES[primeIndex++]
19
+ }
20
+ const overflowOffset = primeIndex++ - TRACEABLE_PRIMES.length
21
+ return FALLBACK_NUMBER_BASE + overflowOffset
22
+ }
23
+
9
24
  /**
10
25
  * Reset faker's seed and internal state for reproducible results
11
26
  */
12
27
  export function resetMockCounter(): void {
13
28
  faker.seed(42)
29
+ primeIndex = 0
30
+ }
31
+
32
+ /**
33
+ * Narrow interface for registering spy markers during mock generation.
34
+ * Satisfied structurally by PropSpyContext.
35
+ */
36
+ export interface PropSpyRegistrar {
37
+ registerString(path: string, propName: string, value: string): void
38
+ registerNumber(path: string, propName: string, value: number): void
39
+ registerFunction(path: string, propName: string, value: (...args: unknown[]) => unknown): void
14
40
  }
15
41
 
16
42
  /**
17
- * Generate mock props object from ComponentInfo
43
+ * Generate mock props object from ComponentInfo.
44
+ * When a registrar is provided, string and number values are spy-instrumented
45
+ * for DOM binding detection.
18
46
  */
19
- export function generateMockProps(componentInfo: ComponentInfo): Record<string, unknown> {
47
+ export function generateMockProps(componentInfo: ComponentInfo, registrar?: PropSpyRegistrar): Record<string, unknown> {
20
48
  const mockProps: Record<string, unknown> = {}
21
49
 
22
50
  for (const [propName, propInfo] of Object.entries(componentInfo.props)) {
23
- mockProps[propName] = generateMockValue(propInfo, propName)
51
+ mockProps[propName] = generateMockValue(propInfo, propName, `props.${propName}`, registrar)
24
52
  }
25
53
 
26
54
  return mockProps
@@ -29,13 +57,13 @@ export function generateMockProps(componentInfo: ComponentInfo): Record<string,
29
57
  /**
30
58
  * Generate a mock value based on PropInfo
31
59
  */
32
- function generateMockValue(propInfo: PropInfo, propName: string): unknown {
33
- // If there's a default value, use it
34
- if (propInfo.defaultValue !== undefined) {
60
+ function generateMockValue(propInfo: PropInfo, propName: string, path: string, registrar?: PropSpyRegistrar): unknown {
61
+ // In plain mode (no registrar), honour default values for realistic rendering
62
+ if (!registrar && propInfo.defaultValue !== undefined) {
35
63
  return extractDefaultValueValue(propInfo.defaultValue)
36
64
  }
37
65
 
38
- return generateValueFromResolvedType(propInfo.resolvedType, propName)
66
+ return generateValueFromResolvedType(propInfo.resolvedType, propName, path, registrar)
39
67
  }
40
68
 
41
69
  /**
@@ -57,10 +85,15 @@ function extractDefaultValueValue(defaultValue: DefaultValue): unknown {
57
85
  /**
58
86
  * Generate a mock value from a ResolvedType
59
87
  */
60
- function generateValueFromResolvedType(resolvedType: ResolvedType, propName: string): unknown {
88
+ function generateValueFromResolvedType(
89
+ resolvedType: ResolvedType,
90
+ propName: string,
91
+ path: string,
92
+ registrar?: PropSpyRegistrar,
93
+ ): unknown {
61
94
  const kind = resolvedType.kind
62
95
 
63
- // Handle semantic types (from React or Wix packages)
96
+ // Handle semantic types (from React or Wix packages) — returned as plain objects
64
97
  if (kind === 'semantic') {
65
98
  return generateSemanticValue(resolvedType.value as string, propName)
66
99
  }
@@ -68,28 +101,28 @@ function generateValueFromResolvedType(resolvedType: ResolvedType, propName: str
68
101
  // Handle structural types
69
102
  switch (kind) {
70
103
  case 'primitive':
71
- return generatePrimitiveValue(resolvedType.value as string, propName)
104
+ return generatePrimitiveValue(resolvedType.value as string, propName, path, registrar)
72
105
 
73
106
  case 'literal':
74
107
  return resolvedType.value
75
108
 
76
109
  case 'union':
77
- return generateUnionValue(resolvedType, propName)
110
+ return generateUnionValue(resolvedType, propName, path, registrar)
78
111
 
79
112
  case 'intersection':
80
- return generateIntersectionValue(resolvedType, propName)
113
+ return generateIntersectionValue(resolvedType, propName, path, registrar)
81
114
 
82
115
  case 'array':
83
- return generateArrayValue(resolvedType, propName)
116
+ return generateArrayValue(resolvedType, propName, path, registrar)
84
117
 
85
118
  case 'object':
86
- return generateObjectValue(resolvedType, propName)
119
+ return generateObjectValue(resolvedType, propName, path, registrar)
87
120
 
88
121
  case 'enum':
89
122
  return generateEnumValue(resolvedType)
90
123
 
91
124
  case 'function':
92
- return generateMockFunction(propName)
125
+ return generateMockFunction(propName, path, registrar)
93
126
 
94
127
  default:
95
128
  // Default to a string for unknown types
@@ -155,12 +188,23 @@ function generateSemanticValue(semanticType: string, propName: string): unknown
155
188
  /**
156
189
  * Generate a primitive value
157
190
  */
158
- function generatePrimitiveValue(primitiveType: string, propName: string): unknown {
191
+ function generatePrimitiveValue(
192
+ primitiveType: string,
193
+ propName: string,
194
+ path: string,
195
+ registrar?: PropSpyRegistrar,
196
+ ): unknown {
159
197
  switch (primitiveType) {
160
- case 'string':
161
- return `mock_${propName}_${faker.string.alphanumeric(6)}`
162
- case 'number':
163
- return faker.number.int({ min: 1, max: 100 })
198
+ case 'string': {
199
+ const raw = `mock_${propName}_${faker.string.alphanumeric(6)}`
200
+ if (registrar) registrar.registerString(path, propName, raw)
201
+ return raw
202
+ }
203
+ case 'number': {
204
+ const val = nextTraceableNumber()
205
+ if (registrar) registrar.registerNumber(path, propName, val)
206
+ return val
207
+ }
164
208
  case 'boolean':
165
209
  return faker.datatype.boolean()
166
210
  case 'null':
@@ -175,7 +219,12 @@ function generatePrimitiveValue(primitiveType: string, propName: string): unknow
175
219
  /**
176
220
  * Generate a value from a union type (pick the first non-null option)
177
221
  */
178
- function generateUnionValue(resolvedType: ResolvedType, propName: string): unknown {
222
+ function generateUnionValue(
223
+ resolvedType: ResolvedType,
224
+ propName: string,
225
+ path: string,
226
+ registrar?: PropSpyRegistrar,
227
+ ): unknown {
179
228
  const types = resolvedType.types ?? []
180
229
 
181
230
  // Prefer string literals for textEnum-like unions
@@ -186,7 +235,7 @@ function generateUnionValue(resolvedType: ResolvedType, propName: string): unkno
186
235
 
187
236
  // Otherwise, use the first type
188
237
  if (types.length > 0) {
189
- return generateValueFromResolvedType(types[0], propName)
238
+ return generateValueFromResolvedType(types[0], propName, path, registrar)
190
239
  }
191
240
 
192
241
  return `mock_${propName}_${faker.string.alphanumeric(6)}`
@@ -195,14 +244,19 @@ function generateUnionValue(resolvedType: ResolvedType, propName: string): unkno
195
244
  /**
196
245
  * Generate a value from an intersection type (merge object properties)
197
246
  */
198
- function generateIntersectionValue(resolvedType: ResolvedType, propName: string): unknown {
247
+ function generateIntersectionValue(
248
+ resolvedType: ResolvedType,
249
+ propName: string,
250
+ path: string,
251
+ registrar?: PropSpyRegistrar,
252
+ ): unknown {
199
253
  const types = resolvedType.types ?? []
200
254
  const merged: Record<string, unknown> = {}
201
255
 
202
256
  for (const type of types) {
203
257
  if (type.kind === 'object' && type.properties) {
204
258
  for (const [key, propInfo] of Object.entries(type.properties)) {
205
- merged[key] = generateMockValue(propInfo, `${propName}.${key}`)
259
+ merged[key] = generateMockValue(propInfo, `${propName}.${key}`, `${path}.${key}`, registrar)
206
260
  }
207
261
  }
208
262
  }
@@ -213,29 +267,38 @@ function generateIntersectionValue(resolvedType: ResolvedType, propName: string)
213
267
  /**
214
268
  * Generate an array value
215
269
  */
216
- function generateArrayValue(resolvedType: ResolvedType, propName: string): unknown[] {
270
+ function generateArrayValue(
271
+ resolvedType: ResolvedType,
272
+ propName: string,
273
+ path: string,
274
+ registrar?: PropSpyRegistrar,
275
+ ): unknown[] {
217
276
  const elementType = resolvedType.elementType
218
277
 
219
278
  if (!elementType) {
220
279
  return [`mock_${propName}[0]_${faker.string.alphanumeric(6)}`]
221
280
  }
222
281
 
223
- // Generate 2-3 items for the array
224
282
  return [
225
- generateValueFromResolvedType(elementType, `${propName}[0]`),
226
- generateValueFromResolvedType(elementType, `${propName}[1]`),
283
+ generateValueFromResolvedType(elementType, `${propName}[0]`, `${path}[0]`, registrar),
284
+ generateValueFromResolvedType(elementType, `${propName}[1]`, `${path}[1]`, registrar),
227
285
  ]
228
286
  }
229
287
 
230
288
  /**
231
289
  * Generate an object value from properties
232
290
  */
233
- function generateObjectValue(resolvedType: ResolvedType, propName: string): Record<string, unknown> {
291
+ function generateObjectValue(
292
+ resolvedType: ResolvedType,
293
+ propName: string,
294
+ path: string,
295
+ registrar?: PropSpyRegistrar,
296
+ ): Record<string, unknown> {
234
297
  const properties = resolvedType.properties ?? {}
235
298
  const obj: Record<string, unknown> = {}
236
299
 
237
300
  for (const [key, propInfo] of Object.entries(properties)) {
238
- obj[key] = generateMockValue(propInfo, `${propName}.${key}`)
301
+ obj[key] = generateMockValue(propInfo, key, `${path}.${key}`, registrar)
239
302
  }
240
303
 
241
304
  return obj
@@ -258,11 +321,16 @@ function generateEnumValue(resolvedType: ResolvedType): unknown {
258
321
  /**
259
322
  * Generate a mock function
260
323
  */
261
- function generateMockFunction(propName: string): (...args: unknown[]) => void {
324
+ function generateMockFunction(
325
+ propName: string,
326
+ path: string,
327
+ registrar?: PropSpyRegistrar,
328
+ ): (...args: unknown[]) => void {
262
329
  const fn = function mockFn(): void {
263
330
  // No-op mock function
264
331
  }
265
332
  Object.defineProperty(fn, 'name', { value: `mock_${propName}` })
333
+ if (registrar) registrar.registerFunction(path, propName, fn)
266
334
  return fn
267
335
  }
268
336
 
@@ -109,6 +109,7 @@ export function processComponent(
109
109
  props: coupledProps,
110
110
  elements: convertElements(extractedElements),
111
111
  innerElementProps: innerElementProps.size > 0 ? innerElementProps : undefined,
112
+ propUsages: state.stores.propUsages,
112
113
  }
113
114
  } catch (error) {
114
115
  warnings.push({
@@ -128,9 +129,13 @@ export function processComponent(
128
129
  enhancedInfo = {
129
130
  componentName: componentInfo.componentName,
130
131
  props: Object.fromEntries(
131
- Object.entries(componentInfo.props).map(([name, info]) => [name, { ...info, bindings: [], logicOnly: false }]),
132
+ Object.entries(componentInfo.props).map(([name, info]) => [
133
+ name,
134
+ { ...info, logicOnly: false, propPath: `props.${name}` },
135
+ ]),
132
136
  ),
133
137
  elements: [],
138
+ propUsages: new Map(),
134
139
  }
135
140
  }
136
141
 
@@ -175,14 +180,12 @@ function buildCoupledProps(
175
180
  const result: Record<string, CoupledProp> = {}
176
181
 
177
182
  for (const [name, info] of Object.entries(componentInfo.props)) {
178
- const path = `props.${name}`
179
- const wasRead = stores.reads.has(path)
180
- const writeInfo = stores.writes.get(path)
183
+ const topLevelWriteInfo = stores.propUsages.get(`props.${name}`)
181
184
 
182
185
  result[name] = {
183
186
  ...info,
184
- logicOnly: wasRead && !writeInfo,
185
- bindings: writeInfo ? extractBindings(writeInfo) : [],
187
+ logicOnly: !topLevelWriteInfo,
188
+ propPath: `props.${name}`,
186
189
  }
187
190
  }
188
191
 
@@ -194,7 +197,7 @@ function buildCoupledProps(
194
197
  const ELEMENT_PROPS_PREFIX = 'props.elementProps.'
195
198
 
196
199
  /**
197
- * Processes stores.writes entries with paths starting with "props.elementProps."
200
+ * Processes stores.propUsages entries with paths starting with "props.elementProps."
198
201
  * to extract inner element prop bindings grouped by elementId (traceId).
199
202
  */
200
203
  function processElementPropsWrites(
@@ -206,7 +209,7 @@ function processElementPropsWrites(
206
209
  const elementPropsInfo = componentInfo.props.elementProps
207
210
  if (!elementPropsInfo) return result
208
211
 
209
- for (const [path, writeInfo] of stores.writes) {
212
+ for (const [path, writeInfo] of stores.propUsages) {
210
213
  if (!path.startsWith(ELEMENT_PROPS_PREFIX)) continue
211
214
 
212
215
  // Resolve the PropInfo for this leaf prop by walking the type tree
@@ -230,10 +233,9 @@ function processElementPropsWrites(
230
233
  propsForElement[leafName] = {
231
234
  ...propInfo,
232
235
  logicOnly: false,
233
- bindings: [],
236
+ propPath: path,
234
237
  }
235
238
  }
236
- propsForElement[leafName].bindings.push(binding)
237
239
  }
238
240
  }
239
241
 
@@ -268,7 +270,9 @@ function resolveInnerPropInfo(elementPropsPropInfo: PropInfo, relativePath: stri
268
270
  return null
269
271
  }
270
272
 
271
- function extractBindings(writeInfo: TrackingStores['writes'] extends Map<string, infer V> ? V : never): DOMBinding[] {
273
+ function extractBindings(
274
+ writeInfo: TrackingStores['propUsages'] extends Map<string, infer V> ? V : never,
275
+ ): DOMBinding[] {
272
276
  const bindings: DOMBinding[] = []
273
277
 
274
278
  for (const [key, attrInfo] of writeInfo.attributes) {
@@ -1,10 +0,0 @@
1
- import { PropSpyMeta, TrackingStores } from '../types';
2
- export interface PropSpyContext {
3
- createAuditedProps: <T extends object | null>(target: T, stores: TrackingStores, getComponent: () => string, basePath?: string) => T;
4
- getSpyMetadataByUniqueId: (id: string) => PropSpyMeta | null;
5
- }
6
- /**
7
- * Creates an encapsulated prop spy context.
8
- * Each context has its own ID counter and metadata map, avoiding global state.
9
- */
10
- export declare function createPropSpyContext(): PropSpyContext;
@@ -1,168 +0,0 @@
1
- import type { PropSpy, PropSpyMeta, TrackingStores } from '../types'
2
- import { PROP_SPY_SYMBOL } from '../types'
3
-
4
- // ─────────────────────────────────────────────────────────────────────────────
5
- // Types
6
- // ─────────────────────────────────────────────────────────────────────────────
7
-
8
- export interface PropSpyContext {
9
- createAuditedProps: <T extends object | null>(
10
- target: T,
11
- stores: TrackingStores,
12
- getComponent: () => string,
13
- basePath?: string,
14
- ) => T
15
- getSpyMetadataByUniqueId: (id: string) => PropSpyMeta | null
16
- }
17
-
18
- // ─────────────────────────────────────────────────────────────────────────────
19
- // Factory
20
- // ─────────────────────────────────────────────────────────────────────────────
21
-
22
- /**
23
- * Creates an encapsulated prop spy context.
24
- * Each context has its own ID counter and metadata map, avoiding global state.
25
- */
26
- export function createPropSpyContext(): PropSpyContext {
27
- let idCounter = 0
28
- const metadataMap = new Map<string, PropSpyMeta>()
29
-
30
- // ─────────────────────────────────────────────────────────────────────────────
31
- // Helpers
32
- // ─────────────────────────────────────────────────────────────────────────────
33
-
34
- const isPropSpy = (val: unknown): val is PropSpy => !!(val && typeof val === 'object' && PROP_SPY_SYMBOL in val)
35
-
36
- const isReactInternal = (val: unknown): boolean => {
37
- if (!val || typeof val !== 'object') return false
38
- const obj = val as Record<string, unknown>
39
- return !!(obj.$$typeof || obj._owner || obj._store || (obj.prototype as Record<string, unknown>)?.isReactComponent)
40
- }
41
-
42
- const logRead = (stores: TrackingStores, path: string, component: string, value: unknown) => {
43
- const record = stores.reads.get(path) ?? { components: new Set(), value }
44
- record.components.add(component)
45
- stores.reads.set(path, record)
46
- }
47
-
48
- const createMeta = (
49
- path: string,
50
- propName: string,
51
- originalValue: unknown,
52
- ): { meta: PropSpyMeta; uniqueId: string } => {
53
- const uniqueId = `__spy_${++idCounter}__`
54
- const meta = { path, propName, uniqueId, originalValue }
55
- return { meta, uniqueId }
56
- }
57
-
58
- // ─────────────────────────────────────────────────────────────────────────────
59
- // Primitive Wrapping
60
- // ─────────────────────────────────────────────────────────────────────────────
61
-
62
- const wrapPrimitiveOrFunction = (
63
- value: string | number | boolean | ((...args: unknown[]) => unknown),
64
- path: string,
65
- propName: string,
66
- stores: TrackingStores,
67
- getComponent: () => string,
68
- ) => {
69
- // Functions: Wrap to log execution
70
- if (typeof value === 'function') {
71
- const spy = function (this: unknown, ...args: unknown[]) {
72
- logRead(stores, path, getComponent(), value)
73
- return value.apply(this, args)
74
- }
75
- Object.defineProperties(spy, {
76
- name: { value: value.name || propName },
77
- length: { value: value.length },
78
- })
79
- return spy
80
- }
81
-
82
- const { meta, uniqueId } = createMeta(path, propName, value)
83
-
84
- // Strings: Embed markers
85
- if (typeof value === 'string') {
86
- metadataMap.set(uniqueId, meta)
87
- return `${uniqueId}${value}${uniqueId}`
88
- }
89
-
90
- // Numbers/Booleans: Wrapper Objects
91
- // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
92
- type SpyWrapper = (number | boolean) & { [PROP_SPY_SYMBOL]?: boolean; __meta?: PropSpyMeta }
93
- let spy: SpyWrapper | undefined
94
- if (typeof value === 'number') spy = new Number(value) as SpyWrapper
95
- if (typeof value === 'boolean') spy = new Boolean(value) as SpyWrapper
96
-
97
- if (spy) {
98
- spy[PROP_SPY_SYMBOL] = true
99
- spy.__meta = meta
100
- return spy
101
- }
102
-
103
- return value
104
- }
105
-
106
- // ─────────────────────────────────────────────────────────────────────────────
107
- // Core Logic
108
- // ─────────────────────────────────────────────────────────────────────────────
109
-
110
- const createAuditedProps = <T extends object | null>(
111
- target: T,
112
- stores: TrackingStores,
113
- getComponent: () => string,
114
- basePath = 'props',
115
- ): T => {
116
- if (!target || typeof target !== 'object' || isPropSpy(target)) return target
117
-
118
- return new Proxy(target, {
119
- get(obj, prop, receiver) {
120
- const value = Reflect.get(obj, prop, receiver)
121
- const propKey = String(prop)
122
-
123
- // Ignore symbols and known React internal properties
124
- if (typeof prop === 'symbol' || propKey === '$$typeof' || propKey.startsWith('_')) {
125
- return value
126
- }
127
-
128
- const path = Array.isArray(target) ? `${basePath}[${propKey}]` : `${basePath}.${propKey}`
129
- const component = getComponent()
130
-
131
- // 1. Handle React internals or nulls (Log but don't wrap)
132
- if (value == null || isReactInternal(value)) {
133
- logRead(stores, path, component, value)
134
- return value
135
- }
136
-
137
- // 2. Handle Primitives & Functions (Wrap & Log)
138
- if (typeof value !== 'object' || typeof value === 'function') {
139
- const wrapped = wrapPrimitiveOrFunction(
140
- value as string | number | boolean | ((...args: unknown[]) => unknown),
141
- path,
142
- propKey,
143
- stores,
144
- getComponent,
145
- )
146
- logRead(stores, path, component, wrapped)
147
- return wrapped
148
- }
149
-
150
- // 3. Handle Objects/Arrays (Recurse Proxy & Log)
151
- const audited = createAuditedProps(value, stores, getComponent, path)
152
- logRead(stores, path, component, audited)
153
- return audited
154
- },
155
- ownKeys: (obj) => Reflect.ownKeys(obj),
156
- getOwnPropertyDescriptor: (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop),
157
- })
158
- }
159
-
160
- const getSpyMetadataByUniqueId = (id: string): PropSpyMeta | null => {
161
- return metadataMap.get(id) ?? null
162
- }
163
-
164
- return {
165
- createAuditedProps,
166
- getSpyMetadataByUniqueId,
167
- }
168
- }