assign-gingerly 0.0.52 → 0.0.54

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/assignFrom.js CHANGED
@@ -21,19 +21,237 @@
21
21
  */
22
22
  import { resolveValues } from './resolveValues.js';
23
23
  import assignGingerly from './assignGingerly.js';
24
+ /**
25
+ * Check if a key ends with the handler operator ' =>'.
26
+ */
27
+ function isHandlerCommand(key) {
28
+ return key.endsWith(' =>');
29
+ }
30
+ /**
31
+ * Supported substitution variables and their option keys.
32
+ */
33
+ const SUBSTITUTION_VARS = [
34
+ { placeholder: '${x}', optionKey: 'where_x_in' },
35
+ { placeholder: '${y}', optionKey: 'where_y_in' },
36
+ { placeholder: '${z}', optionKey: 'where_z_in' },
37
+ ];
38
+ /**
39
+ * Recursively substitute a placeholder in all string values of an object.
40
+ * Returns a new object (shallow clone at each level) with substitutions applied.
41
+ */
42
+ function substituteInValue(value, placeholder, replacement) {
43
+ if (typeof value === 'string') {
44
+ return value.includes(placeholder) ? value.replaceAll(placeholder, replacement) : value;
45
+ }
46
+ if (Array.isArray(value)) {
47
+ return value.map(item => substituteInValue(item, placeholder, replacement));
48
+ }
49
+ if (value && typeof value === 'object') {
50
+ const proto = Object.getPrototypeOf(value);
51
+ if (proto === Object.prototype || proto === null) {
52
+ const result = {};
53
+ for (const [k, v] of Object.entries(value)) {
54
+ result[k] = substituteInValue(v, placeholder, replacement);
55
+ }
56
+ return result;
57
+ }
58
+ }
59
+ return value;
60
+ }
61
+ /**
62
+ * Check if a pattern entry (key + value) contains a given placeholder.
63
+ */
64
+ function entryContainsPlaceholder(key, value, placeholder) {
65
+ if (key.includes(placeholder))
66
+ return true;
67
+ return valueContainsPlaceholder(value, placeholder);
68
+ }
69
+ /**
70
+ * Check if a value (string, object, or array) contains a placeholder.
71
+ */
72
+ function valueContainsPlaceholder(value, placeholder) {
73
+ if (typeof value === 'string')
74
+ return value.includes(placeholder);
75
+ if (Array.isArray(value))
76
+ return value.some(item => valueContainsPlaceholder(item, placeholder));
77
+ if (value && typeof value === 'object') {
78
+ const proto = Object.getPrototypeOf(value);
79
+ if (proto === Object.prototype || proto === null) {
80
+ return Object.values(value).some(v => valueContainsPlaceholder(v, placeholder));
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+ /**
86
+ * Expand looped substitution variables in a pattern.
87
+ * Applies cartesian expansion: x values are expanded first, then y, then z.
88
+ * Each variable multiplies the entries — result count = x.length × y.length × z.length.
89
+ *
90
+ * Returns the expanded pattern (or the original if no substitutions apply).
91
+ */
92
+ function expandSubstitutions(pattern, options) {
93
+ let entries = Object.entries(pattern);
94
+ for (const { placeholder, optionKey } of SUBSTITUTION_VARS) {
95
+ const values = options[optionKey];
96
+ if (!values || values.length === 0)
97
+ continue;
98
+ const expanded = [];
99
+ for (const [key, value] of entries) {
100
+ if (entryContainsPlaceholder(key, value, placeholder)) {
101
+ // Expand this entry for each value in the variable array
102
+ for (const replacement of values) {
103
+ const newKey = key.includes(placeholder)
104
+ ? key.replaceAll(placeholder, replacement)
105
+ : key;
106
+ const newValue = substituteInValue(value, placeholder, replacement);
107
+ expanded.push([newKey, newValue]);
108
+ }
109
+ }
110
+ else {
111
+ // No placeholder in this entry — pass through
112
+ expanded.push([key, value]);
113
+ }
114
+ }
115
+ entries = expanded;
116
+ }
117
+ return mergeHandlerDuplicates(entries);
118
+ }
119
+ /**
120
+ * Convert entries to an object, merging duplicate handler (` =>`) keys into arrays.
121
+ * For normal (non-handler) keys, later entries overwrite earlier ones (standard object behavior).
122
+ * For handler keys, duplicate entries are combined into an array (Multiple Handlers pattern).
123
+ */
124
+ function mergeHandlerDuplicates(entries) {
125
+ const result = {};
126
+ for (const [key, value] of entries) {
127
+ if (key.endsWith(' =>') && key in result) {
128
+ // Duplicate handler key — merge into array
129
+ const existing = result[key];
130
+ if (Array.isArray(existing)) {
131
+ existing.push(value);
132
+ }
133
+ else {
134
+ result[key] = [existing, value];
135
+ }
136
+ }
137
+ else {
138
+ result[key] = value;
139
+ }
140
+ }
141
+ return result;
142
+ }
24
143
  export async function assignFrom(target, pattern, options) {
25
- const resolved = await resolveValues(pattern, options.from, {
26
- withMethods: options.withMethods,
27
- aka: options.aka,
28
- protocols: options.protocols
29
- });
30
- // Handle "..." spread key — merge resolved value into parent
31
- if ('...' in resolved) {
32
- const spreadValue = resolved['...'];
144
+ // First: expand looped substitution variables (${x}, ${y}, ${z})
145
+ const expandedPattern = expandSubstitutions(pattern, options);
146
+ // Separate handler commands ( =>), #[x] keys, and normal keys
147
+ const handlerKeys = [];
148
+ const normalPattern = {};
149
+ const idRefNormalKeys = [];
150
+ const idRefHandlerKeys = [];
151
+ for (const key of Object.keys(expandedPattern)) {
152
+ if (isHandlerCommand(key)) {
153
+ if (key.startsWith('#[')) {
154
+ idRefHandlerKeys.push(key);
155
+ }
156
+ else {
157
+ handlerKeys.push(key);
158
+ }
159
+ }
160
+ else if (key.startsWith('#[')) {
161
+ idRefNormalKeys.push(key);
162
+ }
163
+ else {
164
+ normalPattern[key] = expandedPattern[key];
165
+ }
166
+ }
167
+ // Process normal keys via resolveValues + assignGingerly
168
+ if (Object.keys(normalPattern).length > 0) {
169
+ const resolved = await resolveValues(normalPattern, options.from, {
170
+ withMethods: options.withMethods,
171
+ aka: options.aka,
172
+ protocols: options.protocols
173
+ });
174
+ // Recursively handle "..." spread keys at all nesting levels
175
+ handleSpreads(resolved);
176
+ assignGingerly(target, resolved, options);
177
+ }
178
+ // Process #[x] normal keys — resolve element, then apply remaining path + value
179
+ if (idRefNormalKeys.length > 0 && options.withIds) {
180
+ const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
181
+ for (const key of idRefNormalKeys) {
182
+ const parsed = parseIdRef(key);
183
+ if (!parsed) continue;
184
+ const el = resolveIdVariable(parsed.varName, target, options.withIds);
185
+ if (!el) continue;
186
+ const value = expandedPattern[key];
187
+ if (parsed.remainingPath) {
188
+ // Resolve the RHS value
189
+ const resolvedValue = await resolveValues(
190
+ { __v: value }, options.from,
191
+ { withMethods: options.withMethods, aka: options.aka, protocols: options.protocols }
192
+ );
193
+ // Apply remaining path on the resolved element
194
+ assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
195
+ }
196
+ else {
197
+ // No remaining path — resolve and assign directly to the element
198
+ const resolvedValue = await resolveValues(
199
+ typeof value === 'object' && value !== null ? value : { __v: value },
200
+ options.from,
201
+ { withMethods: options.withMethods, aka: options.aka, protocols: options.protocols }
202
+ );
203
+ if (!('__v' in resolvedValue)) {
204
+ assignGingerly(el, resolvedValue, options);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ // Process handler commands ( =>) — dynamically imported only when needed
210
+ if (handlerKeys.length > 0) {
211
+ const { processHandlerCommands } = await import('./processHandlerCommands.js');
212
+ await processHandlerCommands(target, handlerKeys, expandedPattern, options);
213
+ }
214
+ // Process #[x] handler keys — resolve element, then pass to handler processing
215
+ if (idRefHandlerKeys.length > 0 && options.withIds) {
216
+ const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
217
+ const { processHandlerCommands } = await import('./processHandlerCommands.js');
218
+ for (const key of idRefHandlerKeys) {
219
+ const parsed = parseIdRef(key);
220
+ if (!parsed) continue;
221
+ const el = resolveIdVariable(parsed.varName, target, options.withIds);
222
+ if (!el) continue;
223
+ // Build a synthetic key for processHandlerCommands
224
+ const syntheticKey = parsed.remainingPath
225
+ ? `${parsed.remainingPath} =>`
226
+ : ' =>';
227
+ const syntheticPattern = {
228
+ [syntheticKey]: expandedPattern[key]
229
+ };
230
+ await processHandlerCommands(el, [syntheticKey], syntheticPattern, options);
231
+ }
232
+ }
233
+ return target;
234
+ }
235
+ /**
236
+ * Recursively walk an object and handle "..." spread keys.
237
+ * When a "..." key is found, its value (which should be an object after protocol resolution)
238
+ * is spread into the parent, replacing the "..." entry.
239
+ */
240
+ function handleSpreads(obj) {
241
+ for (const [key, value] of Object.entries(obj)) {
242
+ if (key !== '...' && typeof value === 'object' && value !== null && !Array.isArray(value)) {
243
+ const proto = Object.getPrototypeOf(value);
244
+ if (proto === Object.prototype || proto === null) {
245
+ obj[key] = handleSpreads(value);
246
+ }
247
+ }
248
+ }
249
+ if ('...' in obj) {
250
+ const spreadValue = obj['...'];
251
+ delete obj['...'];
33
252
  if (spreadValue && typeof spreadValue === 'object') {
34
- Object.assign(resolved, spreadValue);
253
+ Object.assign(obj, spreadValue);
35
254
  }
36
- delete resolved['...'];
37
255
  }
38
- return assignGingerly(target, resolved, options);
256
+ return obj;
39
257
  }
package/assignFrom.ts CHANGED
@@ -25,6 +25,181 @@ import assignGingerly, { IAssignGingerlyOptions } from './assignGingerly.js';
25
25
  export interface AssignFromOptions extends IAssignGingerlyOptions, ResolveValuesOptions {
26
26
  /** Source object to resolve RHS path strings against */
27
27
  from: any;
28
+
29
+ /** Loop variable bindings — expand pattern entries containing ${x} */
30
+ where_x_in?: string[];
31
+ /** Loop variable bindings — expand pattern entries containing ${y} */
32
+ where_y_in?: string[];
33
+ /** Loop variable bindings — expand pattern entries containing ${z} */
34
+ where_z_in?: string[];
35
+
36
+ /**
37
+ * Cached element references by variable name.
38
+ * Used with `#[varName]` syntax in LHS keys for fast repeated element access.
39
+ *
40
+ * - String value: existing element ID (uses getElementById)
41
+ * - Object value: { qry: 'selector' } — finds element via querySelector on target, auto-assigns an ID
42
+ *
43
+ * Elements are cached via WeakRef with getElementById fallback on cache miss.
44
+ */
45
+ withIds?: Record<string, string | { qry: string }>;
46
+
47
+ /**
48
+ * Handler implementations scoped to this call.
49
+ * Key: the `do` name referenced in handler configs.
50
+ * Value: a class constructor, or an import path to dynamically load one.
51
+ *
52
+ * Import paths must be local (relative, absolute, or bare specifier — no cross-domain URLs).
53
+ * The module's default export is checked first; otherwise the first exported class
54
+ * with an `assign` method on its prototype is used.
55
+ *
56
+ * Built-in handlers (builtIns.*) auto-load without needing to be listed here.
57
+ *
58
+ * @example
59
+ * handlers: {
60
+ * 'my-list': MyListHandler, // class constructor
61
+ * 'my-chart': './handlers/chart.js', // dynamic import path
62
+ * 'vendor-widget': 'some-package/handler.js', // bare specifier (import map)
63
+ * }
64
+ */
65
+ handlers?: Record<string, AssignFromHandlerConstructor | string>;
66
+ }
67
+
68
+ /**
69
+ * Interface for assignFrom handler classes.
70
+ * Handlers are invoked when a LHS key ends with ' =>'.
71
+ */
72
+ export interface AssignFromHandler {
73
+ assign(lhsTarget: any, resolvedParams: Record<string, any>, options: AssignFromOptions): Promise<void> | void;
74
+ }
75
+
76
+ export interface AssignFromHandlerConstructor {
77
+ new (config: any): AssignFromHandler;
78
+ }
79
+
80
+ /**
81
+ * Check if a key ends with the handler operator ' =>'.
82
+ */
83
+ function isHandlerCommand(key: string): boolean {
84
+ return key.endsWith(' =>');
85
+ }
86
+
87
+ /**
88
+ * Supported substitution variables and their option keys.
89
+ */
90
+ const SUBSTITUTION_VARS = [
91
+ { placeholder: '${x}', optionKey: 'where_x_in' },
92
+ { placeholder: '${y}', optionKey: 'where_y_in' },
93
+ { placeholder: '${z}', optionKey: 'where_z_in' },
94
+ ] as const;
95
+
96
+ /**
97
+ * Recursively substitute a placeholder in all string values of an object.
98
+ * Returns a new object (shallow clone at each level) with substitutions applied.
99
+ */
100
+ function substituteInValue(value: any, placeholder: string, replacement: string): any {
101
+ if (typeof value === 'string') {
102
+ return value.includes(placeholder) ? value.replaceAll(placeholder, replacement) : value;
103
+ }
104
+ if (Array.isArray(value)) {
105
+ return value.map(item => substituteInValue(item, placeholder, replacement));
106
+ }
107
+ if (value && typeof value === 'object') {
108
+ const proto = Object.getPrototypeOf(value);
109
+ if (proto === Object.prototype || proto === null) {
110
+ const result: Record<string, any> = {};
111
+ for (const [k, v] of Object.entries(value)) {
112
+ result[k] = substituteInValue(v, placeholder, replacement);
113
+ }
114
+ return result;
115
+ }
116
+ }
117
+ return value;
118
+ }
119
+
120
+ /**
121
+ * Check if a pattern entry (key + value) contains a given placeholder.
122
+ */
123
+ function entryContainsPlaceholder(key: string, value: any, placeholder: string): boolean {
124
+ if (key.includes(placeholder)) return true;
125
+ return valueContainsPlaceholder(value, placeholder);
126
+ }
127
+
128
+ /**
129
+ * Check if a value (string, object, or array) contains a placeholder.
130
+ */
131
+ function valueContainsPlaceholder(value: any, placeholder: string): boolean {
132
+ if (typeof value === 'string') return value.includes(placeholder);
133
+ if (Array.isArray(value)) return value.some(item => valueContainsPlaceholder(item, placeholder));
134
+ if (value && typeof value === 'object') {
135
+ const proto = Object.getPrototypeOf(value);
136
+ if (proto === Object.prototype || proto === null) {
137
+ return Object.values(value).some(v => valueContainsPlaceholder(v, placeholder));
138
+ }
139
+ }
140
+ return false;
141
+ }
142
+
143
+ /**
144
+ * Expand looped substitution variables in a pattern.
145
+ * Applies cartesian expansion: x values are expanded first, then y, then z.
146
+ * Each variable multiplies the entries — result count = x.length × y.length × z.length.
147
+ *
148
+ * Returns the expanded pattern (or the original if no substitutions apply).
149
+ */
150
+ function expandSubstitutions(
151
+ pattern: Record<string, any>,
152
+ options: AssignFromOptions
153
+ ): Record<string, any> {
154
+ let entries = Object.entries(pattern);
155
+
156
+ for (const { placeholder, optionKey } of SUBSTITUTION_VARS) {
157
+ const values = options[optionKey as keyof AssignFromOptions] as string[] | undefined;
158
+ if (!values || values.length === 0) continue;
159
+
160
+ const expanded: [string, any][] = [];
161
+ for (const [key, value] of entries) {
162
+ if (entryContainsPlaceholder(key, value, placeholder)) {
163
+ // Expand this entry for each value in the variable array
164
+ for (const replacement of values) {
165
+ const newKey = key.includes(placeholder)
166
+ ? key.replaceAll(placeholder, replacement)
167
+ : key;
168
+ const newValue = substituteInValue(value, placeholder, replacement);
169
+ expanded.push([newKey, newValue]);
170
+ }
171
+ } else {
172
+ // No placeholder in this entry — pass through
173
+ expanded.push([key, value]);
174
+ }
175
+ }
176
+ entries = expanded;
177
+ }
178
+
179
+ return mergeHandlerDuplicates(entries);
180
+ }
181
+
182
+ /**
183
+ * Convert entries to an object, merging duplicate handler (` =>`) keys into arrays.
184
+ * For normal (non-handler) keys, later entries overwrite earlier ones (standard object behavior).
185
+ * For handler keys, duplicate entries are combined into an array (Multiple Handlers pattern).
186
+ */
187
+ function mergeHandlerDuplicates(entries: [string, any][]): Record<string, any> {
188
+ const result: Record<string, any> = {};
189
+ for (const [key, value] of entries) {
190
+ if (key.endsWith(' =>') && key in result) {
191
+ // Duplicate handler key — merge into array
192
+ const existing = result[key];
193
+ if (Array.isArray(existing)) {
194
+ existing.push(value);
195
+ } else {
196
+ result[key] = [existing, value];
197
+ }
198
+ } else {
199
+ result[key] = value;
200
+ }
201
+ }
202
+ return result;
28
203
  }
29
204
 
30
205
  export async function assignFrom(
@@ -32,20 +207,133 @@ export async function assignFrom(
32
207
  pattern: Record<string, any>,
33
208
  options: AssignFromOptions
34
209
  ): Promise<any> {
35
- const resolved = await resolveValues(pattern, options.from, {
36
- withMethods: options.withMethods,
37
- aka: options.aka,
38
- protocols: options.protocols
39
- });
40
-
41
- // Handle "..." spread key — merge resolved value into parent
42
- if ('...' in resolved) {
43
- const spreadValue = resolved['...'];
44
- if (spreadValue && typeof spreadValue === 'object') {
45
- Object.assign(resolved, spreadValue);
210
+ // First: expand looped substitution variables (${x}, ${y}, ${z})
211
+ const expandedPattern = expandSubstitutions(pattern, options);
212
+
213
+ // Separate handler commands ( =>), #[x] keys, and normal keys
214
+ const handlerKeys: string[] = [];
215
+ const normalPattern: Record<string, any> = {};
216
+ const idRefNormalKeys: string[] = [];
217
+ const idRefHandlerKeys: string[] = [];
218
+
219
+ for (const key of Object.keys(expandedPattern)) {
220
+ if (isHandlerCommand(key)) {
221
+ if (key.startsWith('#[')) {
222
+ idRefHandlerKeys.push(key);
223
+ } else {
224
+ handlerKeys.push(key);
225
+ }
226
+ } else if (key.startsWith('#[')) {
227
+ idRefNormalKeys.push(key);
228
+ } else {
229
+ normalPattern[key] = expandedPattern[key];
46
230
  }
47
- delete resolved['...'];
48
231
  }
49
232
 
50
- return assignGingerly(target, resolved, options);
233
+ // Process normal keys via resolveValues + assignGingerly
234
+ if (Object.keys(normalPattern).length > 0) {
235
+ const resolved = await resolveValues(normalPattern, options.from, {
236
+ withMethods: options.withMethods,
237
+ aka: options.aka,
238
+ protocols: options.protocols
239
+ });
240
+
241
+ // Recursively handle "..." spread keys at all nesting levels
242
+ handleSpreads(resolved);
243
+
244
+ assignGingerly(target, resolved, options);
245
+ }
246
+
247
+ // Process #[x] normal keys — resolve element, then apply remaining path + value
248
+ if (idRefNormalKeys.length > 0 && options.withIds) {
249
+ const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
250
+ for (const key of idRefNormalKeys) {
251
+ const parsed = parseIdRef(key);
252
+ if (!parsed) continue;
253
+
254
+ const el = resolveIdVariable(parsed.varName, target, options.withIds);
255
+ if (!el) continue;
256
+
257
+ const value = expandedPattern[key];
258
+ if (parsed.remainingPath) {
259
+ // Resolve the RHS value
260
+ const resolvedValue = await resolveValues(
261
+ { __v: value }, options.from,
262
+ { withMethods: options.withMethods, aka: options.aka, protocols: options.protocols }
263
+ );
264
+ // Apply remaining path on the resolved element
265
+ assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
266
+ } else {
267
+ // No remaining path — resolve and assign directly to the element
268
+ const resolvedValue = await resolveValues(
269
+ typeof value === 'object' && value !== null ? value : { __v: value },
270
+ options.from,
271
+ { withMethods: options.withMethods, aka: options.aka, protocols: options.protocols }
272
+ );
273
+ if ('__v' in resolvedValue) {
274
+ // Single value — can't assign to element root without a path
275
+ } else {
276
+ assignGingerly(el, resolvedValue, options);
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ // Process handler commands ( =>) — dynamically imported only when needed
283
+ if (handlerKeys.length > 0) {
284
+ const { processHandlerCommands } = await import('./processHandlerCommands.js');
285
+ await processHandlerCommands(target, handlerKeys, expandedPattern, options);
286
+ }
287
+
288
+ // Process #[x] handler keys — resolve element, then pass to handler processing
289
+ if (idRefHandlerKeys.length > 0 && options.withIds) {
290
+ const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
291
+ const { processHandlerCommands } = await import('./processHandlerCommands.js');
292
+
293
+ for (const key of idRefHandlerKeys) {
294
+ const parsed = parseIdRef(key);
295
+ if (!parsed) continue;
296
+
297
+ const el = resolveIdVariable(parsed.varName, target, options.withIds);
298
+ if (!el) continue;
299
+
300
+ // Build a synthetic key for processHandlerCommands:
301
+ // The resolved element becomes the target, remaining path is the LHS
302
+ const syntheticKey = parsed.remainingPath
303
+ ? `${parsed.remainingPath} =>`
304
+ : ' =>';
305
+
306
+ const syntheticPattern: Record<string, any> = {
307
+ [syntheticKey]: expandedPattern[key]
308
+ };
309
+
310
+ await processHandlerCommands(el, [syntheticKey], syntheticPattern, options);
311
+ }
312
+ }
313
+
314
+ return target;
315
+ }
316
+
317
+ /**
318
+ * Recursively walk an object and handle "..." spread keys.
319
+ * When a "..." key is found, its value (which should be an object after protocol resolution)
320
+ * is spread into the parent, replacing the "..." entry.
321
+ */
322
+ function handleSpreads(obj: Record<string, any>): Record<string, any> {
323
+ for (const [key, value] of Object.entries(obj)) {
324
+ if (key !== '...' && typeof value === 'object' && value !== null && !Array.isArray(value)) {
325
+ const proto = Object.getPrototypeOf(value);
326
+ if (proto === Object.prototype || proto === null) {
327
+ obj[key] = handleSpreads(value);
328
+ }
329
+ }
330
+ }
331
+ if ('...' in obj) {
332
+ const spreadValue = obj['...'];
333
+ delete obj['...'];
334
+ if (spreadValue && typeof spreadValue === 'object') {
335
+ Object.assign(obj, spreadValue);
336
+ }
337
+ }
338
+ return obj;
51
339
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assign-gingerly",
3
- "version": "0.0.52",
3
+ "version": "0.0.54",
4
4
  "description": "This package provides a utility function for carefully merging one object into another.",
5
5
  "homepage": "https://github.com/bahrus/assign-gingerly#readme",
6
6
  "bugs": {
@@ -60,6 +60,14 @@
60
60
  "default": "./resolveValues.js",
61
61
  "types": "./resolveValues.ts"
62
62
  },
63
+ "./resolveIdRef.js": {
64
+ "default": "./resolveIdRef.js",
65
+ "types": "./resolveIdRef.ts"
66
+ },
67
+ "./transitionHelper.js": {
68
+ "default": "./transitionHelper.js",
69
+ "types": "./transitionHelper.ts"
70
+ },
63
71
  "./installForwarding.js": {
64
72
  "default": "./installForwarding.js",
65
73
  "types": "./installForwarding.ts"
@@ -72,6 +80,26 @@
72
80
  "default": "./resolveAndAssignFeatures.js",
73
81
  "types": "./resolveAndAssignFeatures.ts"
74
82
  },
83
+ "./handlers/lazyLoad.js": {
84
+ "default": "./handlers/lazyLoad.js",
85
+ "types": "./handlers/lazyLoad.ts"
86
+ },
87
+ "./handlers/lazyLoadSwitch.js": {
88
+ "default": "./handlers/lazyLoadSwitch.js",
89
+ "types": "./handlers/lazyLoadSwitch.ts"
90
+ },
91
+ "./handlers/join.js": {
92
+ "default": "./handlers/join.js",
93
+ "types": "./handlers/join.ts"
94
+ },
95
+ "./handlers/microDataJoin.js": {
96
+ "default": "./handlers/microDataJoin.js",
97
+ "types": "./handlers/microDataJoin.ts"
98
+ },
99
+ "./paths.js": {
100
+ "default": "./paths.js",
101
+ "types": "./paths.ts"
102
+ },
75
103
  "./assignFrom.js": {
76
104
  "default": "./assignFrom.js",
77
105
  "types": "./assignFrom.ts"
@@ -95,9 +123,9 @@
95
123
  "chrome": "npx playwright cr http://localhost:8000"
96
124
  },
97
125
  "devDependencies": {
98
- "@playwright/test": "1.60.0",
126
+ "@playwright/test": "1.61.1",
99
127
  "spa-ssi": "0.0.27",
100
- "@types/node": "25.9.3",
128
+ "@types/node": "26.1.0",
101
129
  "typescript": "6.0.3"
102
130
  }
103
131
  }