assign-gingerly 0.0.80 → 0.0.81

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.
package/DX/paths.js CHANGED
@@ -30,6 +30,31 @@ const PATH_SYMBOL = Symbol('assign-gingerly-path');
30
30
  function isPathProxy(value) {
31
31
  return !!value && (typeof value === 'object' || typeof value === 'function') && PATH_SYMBOL in value;
32
32
  }
33
+ const COMMAND_TOKEN_SUFFIXES = {
34
+ Each: '?.@each',
35
+ EqNot: ' =!',
36
+ PlusEq: ' +=',
37
+ QMEq: ' ?=',
38
+ YEq: ' Y=',
39
+ MinusEq: ' -=',
40
+ Arrow: ' =>',
41
+ };
42
+ function serializePath(prefix) {
43
+ return prefix.length > 0 ? `?.${prefix}` : '?.';
44
+ }
45
+ function appendPathSegment(prefix, segment) {
46
+ return prefix ? `${prefix}?.${segment}` : segment;
47
+ }
48
+ function appendCommandSuffix(prefix, token) {
49
+ return `${prefix}${COMMAND_TOKEN_SUFFIXES[token]}`;
50
+ }
51
+ function getReservedToken(prop) {
52
+ if (prop === 'Path' || prop === 'path')
53
+ return prop;
54
+ if (prop in COMMAND_TOKEN_SUFFIXES)
55
+ return prop;
56
+ return undefined;
57
+ }
33
58
  /**
34
59
  * Create a proxy for id-ref paths (#[varName]).
35
60
  * After the initial #[varName], further property access chains with ?. from the resolved element.
@@ -40,13 +65,20 @@ function createIdRefProxy(idRef, options) {
40
65
  Object.defineProperty(handler, PATH_SYMBOL, { value: idRef });
41
66
  return new Proxy(handler, {
42
67
  get(_, prop) {
43
- if (prop === 'path' || prop === PATH_SYMBOL) {
68
+ if (prop === 'path' || prop === 'Path' || prop === PATH_SYMBOL) {
44
69
  return idRef;
45
70
  }
46
71
  if (typeof prop === 'symbol')
47
72
  return undefined;
73
+ const reservedToken = getReservedToken(prop);
74
+ if (reservedToken === 'Each') {
75
+ return createIdRefProxy(appendPathSegment(idRef, '@each'), options);
76
+ }
77
+ if (reservedToken && reservedToken !== 'Path' && reservedToken !== 'path') {
78
+ return createIdRefProxy(appendCommandSuffix(idRef, reservedToken), options);
79
+ }
48
80
  // Chain further path segments after the id ref
49
- const chained = `${idRef}?.${String(prop)}`;
81
+ const chained = appendPathSegment(idRef, String(prop));
50
82
  return createIdRefProxy(chained, options);
51
83
  },
52
84
  apply(_, __, args) {
@@ -84,12 +116,22 @@ function createPathProxy(prefix, options) {
84
116
  Object.defineProperty(handler, PATH_SYMBOL, { value: prefix.length > 0 ? `?.${prefix}` : '?.' });
85
117
  return new Proxy(handler, {
86
118
  get(_, prop) {
87
- if (prop === 'path' || prop === PATH_SYMBOL) {
88
- return prefix.length > 0 ? `?.${prefix}` : '?.';
119
+ if (prop === 'path' || prop === 'Path' || prop === PATH_SYMBOL) {
120
+ return serializePath(prefix);
89
121
  }
90
122
  // Ignore symbol access (Symbol.iterator, Symbol.toPrimitive, etc.)
91
123
  if (typeof prop === 'symbol')
92
124
  return undefined;
125
+ const reservedToken = getReservedToken(String(prop));
126
+ if (reservedToken === 'Path' || reservedToken === 'path') {
127
+ return serializePath(prefix);
128
+ }
129
+ if (reservedToken === 'Each') {
130
+ return createPathProxy(appendPathSegment(prefix, '@each'), options);
131
+ }
132
+ if (reservedToken) {
133
+ return createPathProxy(appendCommandSuffix(prefix, reservedToken), options);
134
+ }
93
135
  let segment = String(prop);
94
136
  // #-prefix: $['#firstName'] → '#[firstName]' (cached element ref)
95
137
  if (segment.startsWith('#')) {
@@ -107,7 +149,7 @@ function createPathProxy(prefix, options) {
107
149
  }
108
150
  }
109
151
  }
110
- const newPath = prefix ? `${prefix}?.${segment}` : segment;
152
+ const newPath = appendPathSegment(prefix, segment);
111
153
  return createPathProxy(newPath, options);
112
154
  },
113
155
  apply(_, __, args) {
@@ -126,7 +168,7 @@ function createPathProxy(prefix, options) {
126
168
  }
127
169
  else
128
170
  argStr = String(arg);
129
- const newPath = prefix ? `${prefix}?.${argStr}` : argStr;
171
+ const newPath = appendPathSegment(prefix, argStr);
130
172
  return createPathProxy(newPath, options);
131
173
  }
132
174
  // No args — method called with no arguments, return self
@@ -319,8 +361,10 @@ export function sp(strings, ...values) {
319
361
  * e.g., '?.address?.city' → 'city', '?.firstName' → 'firstName'
320
362
  */
321
363
  function extractPropName(pathStr) {
322
- const parts = pathStr.split('?.');
323
- return parts[parts.length - 1];
364
+ const withoutCommand = pathStr.replace(/(?: \+=| =!| \?=| Y=| -=| =>)$/, '');
365
+ const parts = withoutCommand.split('?.');
366
+ const last = parts[parts.length - 1];
367
+ return last === '@each' ? 'Each' : last;
324
368
  }
325
369
  /**
326
370
  * Tagged template literal that produces an array of {prop, val} objects + literal strings.
package/DX/paths.ts CHANGED
@@ -32,20 +32,63 @@ const PATH_SYMBOL = Symbol('assign-gingerly-path');
32
32
  function isPathProxy(value: unknown): value is { [PATH_SYMBOL]: string } {
33
33
  return !!value && (typeof value === 'object' || typeof value === 'function') && PATH_SYMBOL in value;
34
34
  }
35
+
36
+ const COMMAND_TOKEN_SUFFIXES = {
37
+ Each: '?.@each',
38
+ EqNot: ' =!',
39
+ PlusEq: ' +=',
40
+ QMEq: ' ?=',
41
+ YEq: ' Y=',
42
+ MinusEq: ' -=',
43
+ Arrow: ' =>',
44
+ } as const;
45
+
46
+ type CommandToken = keyof typeof COMMAND_TOKEN_SUFFIXES;
47
+
48
+ function serializePath(prefix: string): string {
49
+ return prefix.length > 0 ? `?.${prefix}` : '?.';
50
+ }
51
+
52
+ function appendPathSegment(prefix: string, segment: string): string {
53
+ return prefix ? `${prefix}?.${segment}` : segment;
54
+ }
55
+
56
+ function appendCommandSuffix(prefix: string, token: CommandToken): string {
57
+ return `${prefix}${COMMAND_TOKEN_SUFFIXES[token]}`;
58
+ }
59
+
60
+ function getReservedToken(prop: string): CommandToken | 'Path' | 'path' | undefined {
61
+ if (prop === 'Path' || prop === 'path') return prop;
62
+ if (prop in COMMAND_TOKEN_SUFFIXES) return prop as CommandToken;
63
+ return undefined;
64
+ }
35
65
 
36
66
  /**
37
- * Type that maps an object type to a proxy where every property access
38
- * returns either a deeper proxy (for object properties) or a terminal
39
- * with a `.path` string accessor — while providing full autocomplete.
40
- * Enhanced: also callable (for method call syntax).
41
- */
42
- export type PathProxy<T> = {
43
- [K in keyof T]-?: T[K] extends ((...args: any[]) => infer R)
44
- ? ((...args: any[]) => PathProxy<NonNullable<R>> & { readonly path: string }) & PathProxy<NonNullable<R>> & { readonly path: string }
45
- : T[K] extends (object | undefined | null)
46
- ? PathProxy<NonNullable<T[K]>> & { readonly path: string } & ((...args: any[]) => PathProxy<any> & { readonly path: string })
47
- : { readonly path: string } & ((...args: any[]) => PathProxy<any> & { readonly path: string });
48
- } & { readonly path: string } & ((...args: any[]) => PathProxy<any> & { readonly path: string });
67
+ * Type that maps an object type to a proxy where every property access
68
+ * returns either a deeper proxy (for object properties) or a terminal
69
+ * with a serialized path string accessor — while providing full autocomplete.
70
+ * Enhanced: also callable (for method call syntax) and includes reserved
71
+ * command markers such as `Each`, `EqNot`, and `PlusEq`.
72
+ */
73
+ export type PathProxyCore = {
74
+ readonly Path: string;
75
+ readonly path: string;
76
+ readonly Each: PathProxy<any>;
77
+ readonly EqNot: PathProxy<any>;
78
+ readonly PlusEq: PathProxy<any>;
79
+ readonly QMEq: PathProxy<any>;
80
+ readonly YEq: PathProxy<any>;
81
+ readonly MinusEq: PathProxy<any>;
82
+ readonly Arrow: PathProxy<any>;
83
+ };
84
+
85
+ export type PathProxy<T> = {
86
+ [K in keyof T]-?: T[K] extends ((...args: any[]) => infer R)
87
+ ? ((...args: any[]) => PathProxy<NonNullable<R>> & PathProxyCore) & PathProxy<NonNullable<R>> & PathProxyCore
88
+ : T[K] extends (object | undefined | null)
89
+ ? PathProxy<NonNullable<T[K]>> & PathProxyCore & ((...args: any[]) => PathProxy<any> & PathProxyCore)
90
+ : PathProxyCore & ((...args: any[]) => PathProxy<any> & PathProxyCore);
91
+ } & PathProxyCore & ((...args: any[]) => PathProxy<any> & PathProxyCore);
49
92
 
50
93
  /**
51
94
  * Options for paths proxy creation.
@@ -67,26 +110,34 @@ function createIdRefProxy(idRef: string, options?: PathsOptions): any {
67
110
  Object.defineProperty(handler, PATH_SYMBOL, { value: idRef });
68
111
  return new Proxy(handler, {
69
112
  get(_, prop: string | symbol) {
70
- if (prop === 'path' || prop === PATH_SYMBOL) {
113
+ if (prop === 'path' || prop === 'Path' || prop === PATH_SYMBOL) {
71
114
  return idRef;
72
115
  }
73
- if (typeof prop === 'symbol') return undefined;
74
-
75
- // Chain further path segments after the id ref
76
- const chained = `${idRef}?.${String(prop)}`;
77
- return createIdRefProxy(chained, options);
78
- },
79
- apply(_, __, args) {
80
- if (args.length > 0) {
116
+ if (typeof prop === 'symbol') return undefined;
117
+
118
+ const reservedToken = getReservedToken(prop);
119
+ if (reservedToken === 'Each') {
120
+ return createIdRefProxy(appendPathSegment(idRef, '@each'), options);
121
+ }
122
+ if (reservedToken && reservedToken !== 'Path' && reservedToken !== 'path') {
123
+ return createIdRefProxy(appendCommandSuffix(idRef, reservedToken), options);
124
+ }
125
+
126
+ // Chain further path segments after the id ref
127
+ const chained = appendPathSegment(idRef, String(prop));
128
+ return createIdRefProxy(chained, options);
129
+ },
130
+ apply(_, __, args) {
131
+ if (args.length > 0) {
81
132
  const arg = args[0];
82
- let argStr: string;
83
- if (arg === true) argStr = 'true';
84
- else if (arg === false) argStr = 'false';
85
- else if (isPathProxy(arg)) {
86
- const fullPath = arg[PATH_SYMBOL] as string;
87
- argStr = fullPath.startsWith('?.') ? fullPath.substring(2) : fullPath;
88
- }
89
- else argStr = String(arg);
133
+ let argStr: string;
134
+ if (arg === true) argStr = 'true';
135
+ else if (arg === false) argStr = 'false';
136
+ else if (isPathProxy(arg)) {
137
+ const fullPath = arg[PATH_SYMBOL] as string;
138
+ argStr = fullPath.startsWith('?.') ? fullPath.substring(2) : fullPath;
139
+ }
140
+ else argStr = String(arg);
90
141
 
91
142
  const chained = `${idRef}?.${argStr}`;
92
143
  return createIdRefProxy(chained, options);
@@ -112,52 +163,63 @@ function createPathProxy(prefix: string, options?: PathsOptions): any {
112
163
 
113
164
  return new Proxy(handler, {
114
165
  get(_, prop: string | symbol) {
115
- if (prop === 'path' || prop === PATH_SYMBOL) {
116
- return prefix.length > 0 ? `?.${prefix}` : '?.';
117
- }
118
- // Ignore symbol access (Symbol.iterator, Symbol.toPrimitive, etc.)
119
- if (typeof prop === 'symbol') return undefined;
120
-
121
- let segment = String(prop);
122
-
123
- // #-prefix: $['#firstName'] → '#[firstName]' (cached element ref)
124
- if (segment.startsWith('#')) {
125
- const varName = segment.substring(1);
126
- const idRef = `#[${varName}]`;
166
+ if (prop === 'path' || prop === 'Path' || prop === PATH_SYMBOL) {
167
+ return serializePath(prefix);
168
+ }
169
+ // Ignore symbol access (Symbol.iterator, Symbol.toPrimitive, etc.)
170
+ if (typeof prop === 'symbol') return undefined;
171
+
172
+ const reservedToken = getReservedToken(String(prop));
173
+ if (reservedToken === 'Path' || reservedToken === 'path') {
174
+ return serializePath(prefix);
175
+ }
176
+ if (reservedToken === 'Each') {
177
+ return createPathProxy(appendPathSegment(prefix, '@each'), options);
178
+ }
179
+ if (reservedToken) {
180
+ return createPathProxy(appendCommandSuffix(prefix, reservedToken), options);
181
+ }
182
+
183
+ let segment = String(prop);
184
+
185
+ // #-prefix: $['#firstName'] → '#[firstName]' (cached element ref)
186
+ if (segment.startsWith('#')) {
187
+ const varName = segment.substring(1);
188
+ const idRef = `#[${varName}]`;
127
189
  // Return a proxy that starts from this id ref (can chain further with ?.)
128
190
  return createIdRefProxy(idRef, options);
129
191
  }
130
192
 
131
193
  // Apply reverse alias: if prop matches an alias value, use the alias key
132
- if (aliasMap) {
133
- for (const [alias, target] of Object.entries(aliasMap)) {
134
- if (target === segment) { segment = alias; break; }
135
- }
136
- }
137
-
138
- const newPath = prefix ? `${prefix}?.${segment}` : segment;
139
- return createPathProxy(newPath, options);
140
- },
141
- apply(_, __, args) {
142
- // Method call syntax: $.querySelector('.username') → extends path with the argument
143
- if (args.length > 0) {
144
- const arg = args[0];
145
- let argStr: string;
146
- if (arg === true) argStr = 'true';
147
- else if (arg === false) argStr = 'false';
194
+ if (aliasMap) {
195
+ for (const [alias, target] of Object.entries(aliasMap)) {
196
+ if (target === segment) { segment = alias; break; }
197
+ }
198
+ }
199
+
200
+ const newPath = appendPathSegment(prefix, segment);
201
+ return createPathProxy(newPath, options);
202
+ },
203
+ apply(_, __, args) {
204
+ // Method call syntax: $.querySelector('.username') → extends path with the argument
205
+ if (args.length > 0) {
206
+ const arg = args[0];
207
+ let argStr: string;
208
+ if (arg === true) argStr = 'true';
209
+ else if (arg === false) argStr = 'false';
148
210
  else if (isPathProxy(arg)) {
149
211
  // Proxy arg — extract path without '?.' prefix
150
212
  const fullPath = arg[PATH_SYMBOL] as string;
151
213
  argStr = fullPath.startsWith('?.') ? fullPath.substring(2) : fullPath;
152
214
  }
153
215
  else argStr = String(arg);
154
-
155
- const newPath = prefix ? `${prefix}?.${argStr}` : argStr;
156
- return createPathProxy(newPath, options);
157
- }
158
- // No args — method called with no arguments, return self
159
- return createPathProxy(prefix, options);
160
- }
216
+
217
+ const newPath = appendPathSegment(prefix, argStr);
218
+ return createPathProxy(newPath, options);
219
+ }
220
+ // No args — method called with no arguments, return self
221
+ return createPathProxy(prefix, options);
222
+ }
161
223
  });
162
224
  }
163
225
 
@@ -203,14 +265,14 @@ export function set(lhs: any): { to: (rhs: any) => Record<string, any> } {
203
265
  const lhsStr = isPathProxy(lhs)
204
266
  ? lhs[PATH_SYMBOL]
205
267
  : String(lhs);
206
- return {
207
- to(rhs: any): Record<string, any> {
208
- const rhsStr = isPathProxy(rhs)
209
- ? rhs[PATH_SYMBOL]
210
- : rhs;
211
- return { [lhsStr]: rhsStr };
212
- }
213
- };
268
+ return {
269
+ to(rhs: any): Record<string, any> {
270
+ const rhsStr = isPathProxy(rhs)
271
+ ? rhs[PATH_SYMBOL]
272
+ : rhs;
273
+ return { [lhsStr]: rhsStr };
274
+ }
275
+ };
214
276
  }
215
277
 
216
278
  /**
@@ -234,16 +296,16 @@ export function set(lhs: any): { to: (rhs: any) => Record<string, any> } {
234
296
  export function smoothOver(value: any): any {
235
297
  if (isPathProxy(value)) {
236
298
  return value[PATH_SYMBOL];
237
- }
299
+ }
238
300
  if (Array.isArray(value)) {
239
301
  return value.map(smoothOver);
240
302
  }
241
303
  if (value && typeof value === 'object') {
242
304
  const proto = Object.getPrototypeOf(value);
243
305
  if (proto === Object.prototype || proto === null) {
244
- const result: Record<string, any> = {};
245
- for (const [k, v] of Object.entries(value)) {
246
- result[k] = smoothOver(v);
306
+ const result: Record<string, any> = {};
307
+ for (const [k, v] of Object.entries(value)) {
308
+ result[k] = smoothOver(v);
247
309
  }
248
310
  return result;
249
311
  }
@@ -328,23 +390,23 @@ export function forEachKeyIn<T>(
328
390
  * sp`${$.lastName}${[', ', $.middleName]}, ${$.firstName}`
329
391
  * // ['?.lastName', [', ', '?.middleName'], ', ', '?.firstName']
330
392
  */
331
- export function sp(strings: TemplateStringsArray, ...values: any[]): any[] {
393
+ export function sp(strings: TemplateStringsArray, ...values: any[]): any[] {
332
394
  const result: any[] = [];
333
395
  for (let i = 0; i < strings.length; i++) {
334
396
  if (strings[i]) result.push(strings[i]);
335
397
  if (i < values.length) {
336
- const v = values[i];
337
- if (isPathProxy(v)) {
338
- // Auto-extract path from proxy object
339
- result.push(v[PATH_SYMBOL]);
340
- } else if (Array.isArray(v)) {
341
- // Nested array — recursively extract paths from proxy elements
342
- result.push(v.map(el =>
343
- isPathProxy(el) ? el[PATH_SYMBOL] : el
344
- ));
345
- } else {
346
- result.push(v);
347
- }
398
+ const v = values[i];
399
+ if (isPathProxy(v)) {
400
+ // Auto-extract path from proxy object
401
+ result.push(v[PATH_SYMBOL]);
402
+ } else if (Array.isArray(v)) {
403
+ // Nested array — recursively extract paths from proxy elements
404
+ result.push(v.map(el =>
405
+ isPathProxy(el) ? el[PATH_SYMBOL] : el
406
+ ));
407
+ } else {
408
+ result.push(v);
409
+ }
348
410
  }
349
411
  }
350
412
  return result;
@@ -354,10 +416,12 @@ export function sp(strings: TemplateStringsArray, ...values: any[]): any[] {
354
416
  * Extract the last segment from a `?.`-prefixed path string.
355
417
  * e.g., '?.address?.city' → 'city', '?.firstName' → 'firstName'
356
418
  */
357
- function extractPropName(pathStr: string): string {
358
- const parts = pathStr.split('?.');
359
- return parts[parts.length - 1];
360
- }
419
+ function extractPropName(pathStr: string): string {
420
+ const withoutCommand = pathStr.replace(/(?: \+=| =!| \?=| Y=| -=| =>)$/, '');
421
+ const parts = withoutCommand.split('?.');
422
+ const last = parts[parts.length - 1];
423
+ return last === '@each' ? 'Each' : last;
424
+ }
361
425
 
362
426
  /**
363
427
  * Tagged template literal that produces an array of {prop, val} objects + literal strings.
@@ -389,27 +453,27 @@ export function md(strings: TemplateStringsArray, ...values: any[]): any[] {
389
453
  for (let i = 0; i < strings.length; i++) {
390
454
  if (strings[i]) result.push(strings[i]);
391
455
  if (i < values.length) {
392
- const v = values[i];
393
- if (isPathProxy(v)) {
394
- // Proxy object → {prop, val}
395
- const pathStr = v[PATH_SYMBOL] as string;
396
- result.push({ prop: extractPropName(pathStr), val: pathStr });
397
- } else if (Array.isArray(v)) {
398
- // Nested array — recursively convert proxy elements to {prop, val}
399
- result.push(v.map(el => {
400
- if (isPathProxy(el)) {
401
- const pathStr = el[PATH_SYMBOL] as string;
402
- return { prop: extractPropName(pathStr), val: pathStr };
403
- }
404
- return el;
405
- }));
406
- } else if (v && typeof v === 'object' && 'prop' in v) {
407
- // Developer override object — extract val from proxy if present
408
- const processed = { ...v };
409
- if (isPathProxy(processed.val)) {
410
- processed.val = processed.val[PATH_SYMBOL];
411
- }
412
- result.push(processed);
456
+ const v = values[i];
457
+ if (isPathProxy(v)) {
458
+ // Proxy object → {prop, val}
459
+ const pathStr = v[PATH_SYMBOL] as string;
460
+ result.push({ prop: extractPropName(pathStr), val: pathStr });
461
+ } else if (Array.isArray(v)) {
462
+ // Nested array — recursively convert proxy elements to {prop, val}
463
+ result.push(v.map(el => {
464
+ if (isPathProxy(el)) {
465
+ const pathStr = el[PATH_SYMBOL] as string;
466
+ return { prop: extractPropName(pathStr), val: pathStr };
467
+ }
468
+ return el;
469
+ }));
470
+ } else if (v && typeof v === 'object' && 'prop' in v) {
471
+ // Developer override object — extract val from proxy if present
472
+ const processed = { ...v };
473
+ if (isPathProxy(processed.val)) {
474
+ processed.val = processed.val[PATH_SYMBOL];
475
+ }
476
+ result.push(processed);
413
477
  } else {
414
478
  result.push(v);
415
479
  }
package/README.md CHANGED
@@ -4400,9 +4400,10 @@ export default {
4400
4400
  **How `paths` works:**
4401
4401
 
4402
4402
  - `paths<T>()` creates a deeply-proxied object typed as `T`
4403
- - Every property access returns a deeper proxy (e.g., `$.address.city`)
4404
- - `.path` extracts the `?.`-prefixed string: `$.address.city.path` → `'?.address?.city'`
4405
- - Inside `sp` template literals, `.path` is not needed proxy objects are auto-detected
4403
+ - Every property access returns a deeper proxy (e.g., `$.address.city`)
4404
+ - Capitalized reserved tokens like `.Each` and `.EqNot` normalize into command syntax
4405
+ - `.Path` extracts the `?.`-prefixed string: `$.address.city.Path` `'?.address?.city'`
4406
+ - Inside `sp` template literals, `.Path` is not needed — proxy objects are auto-detected
4406
4407
 
4407
4408
  **How `sp` works:**
4408
4409
 
@@ -4421,19 +4422,19 @@ const value = sp`${$.lastName}${[', ', $.middleName]}, ${$.firstName}`;
4421
4422
  // ['?.lastName', [', ', '?.middleName'], ', ', '?.firstName']
4422
4423
  ```
4423
4424
 
4424
- **Using `.path` outside of `sp`:**
4425
+ **Using `.Path` outside of `sp`:**
4425
4426
 
4426
4427
  When you need the path string in a non-`sp` context (object keys, plain arrays, other expressions):
4427
4428
 
4428
4429
  ```TypeScript
4429
4430
  const $ = paths<Person>();
4430
4431
 
4431
- $.lastName.path // '?.lastName'
4432
- $.address.city.path // '?.address?.city'
4432
+ $.lastName.Path // '?.lastName'
4433
+ $.address.city.Path // '?.address?.city'
4433
4434
 
4434
4435
  // As an object key:
4435
4436
  const pattern = {
4436
- [$.textContent.path]: '?.firstName' // '?.textContent': '?.firstName'
4437
+ [$.textContent.Path]: '?.firstName' // '?.textContent': '?.firstName'
4437
4438
  };
4438
4439
  ```
4439
4440
 
@@ -4473,7 +4474,7 @@ md`${$.firstName} ${{ prop: 'birthDate', val: $.birthDT, format: 'long' }}`
4473
4474
  | `sp` | `'?.firstName'` (path string) | `builtIns.join` |
4474
4475
  | `md` | `{ prop: 'firstName', val: '?.firstName' }` | `builtIns.microDataJoin` |
4475
4476
 
4476
- Both auto-detect path proxies (no `.path` needed inside template literals) and preserve nested arrays for optional segments.
4477
+ Both auto-detect path proxies (no `.Path` needed inside template literals) and preserve nested arrays for optional segments.
4477
4478
 
4478
4479
  ## Cached Element Resolution with `#[x]` and `pin`
4479
4480