assign-gingerly 0.0.63 → 0.0.65
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/README.md +59 -18
- package/assignFrom.js +21 -19
- package/assignFrom.ts +26 -24
- package/assignFromAsync.js +10 -7
- package/assignFromAsync.ts +13 -96
- package/assignGingerly.js +3 -17
- package/assignGingerly.ts +10 -18
- package/assignTentatively.ts +3 -4
- package/getValues.js +81 -25
- package/getValues.ts +85 -26
- package/handlers/arr.js +13 -0
- package/handlers/arr.ts +13 -0
- package/handlers/manageTemplateList.js +1 -1
- package/handlers/manageTemplateList.ts +1 -1
- package/handlers/nudge.js +23 -0
- package/handlers/nudge.ts +23 -0
- package/index.js +2 -0
- package/index.ts +2 -0
- package/inferencer/types/assign-gingerly/types.d.ts +269 -1
- package/inferencer/types/mount-observer/types.d.ts +10 -2
- package/inferencer/types/roundabout/types.d.ts +1 -1
- package/inferencer/types/three-peat/types.d.ts +18 -0
- package/object-extension.js +1 -1
- package/object-extension.ts +4 -3
- package/package.json +9 -1
- package/paths.ts +1 -1
- package/{withIdsCorrector.js → pinCorrector.js} +5 -5
- package/{withIdsCorrector.ts → pinCorrector.ts} +5 -5
- package/processHandlerCommands.js +4 -2
- package/processHandlerCommands.ts +4 -2
- package/resolveIdRef.js +8 -8
- package/resolveIdRef.ts +9 -9
- package/resolveValues.js +20 -88
- package/resolveValues.ts +17 -91
- package/types/assign-gingerly/types.d.ts +168 -0
package/assignGingerly.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeAliasOptions } from './getValues.js';
|
|
1
2
|
/**
|
|
2
3
|
* GUID for global instance map storage to ensure uniqueness across package versions
|
|
3
4
|
*/
|
|
@@ -561,29 +562,14 @@ export function assignGingerly(target, source, options, permissions) {
|
|
|
561
562
|
if (!target || typeof target !== 'object') {
|
|
562
563
|
return target;
|
|
563
564
|
}
|
|
564
|
-
//
|
|
565
|
-
const withMethodsSet = options
|
|
566
|
-
? options.withMethods instanceof Set
|
|
567
|
-
? options.withMethods
|
|
568
|
-
: new Set(options.withMethods)
|
|
569
|
-
: undefined;
|
|
565
|
+
//TODO
|
|
566
|
+
const { aliasMap, withMethods: withMethodsSet } = normalizeAliasOptions(options);
|
|
570
567
|
// Convert withAsyncMethods array to Set for O(1) lookup
|
|
571
568
|
const withAsyncMethodsSet = options?.withAsyncMethods
|
|
572
569
|
? options.withAsyncMethods instanceof Set
|
|
573
570
|
? options.withAsyncMethods
|
|
574
571
|
: new Set(options.withAsyncMethods)
|
|
575
572
|
: undefined;
|
|
576
|
-
// Convert aka object to Map for O(1) lookup and validate aliases
|
|
577
|
-
const aliasMap = new Map();
|
|
578
|
-
if (options?.aka) {
|
|
579
|
-
for (const [alias, target] of Object.entries(options.aka)) {
|
|
580
|
-
// Validate: disallow space and backtick in aliases
|
|
581
|
-
if (alias.includes(' ') || alias.includes('`')) {
|
|
582
|
-
throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
|
|
583
|
-
}
|
|
584
|
-
aliasMap.set(alias, target);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
573
|
const registry = options?.registry instanceof EnhancementRegistry
|
|
588
574
|
? options.registry
|
|
589
575
|
: options?.registry
|
package/assignGingerly.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { EnhancementConfig } from "./types/assign-gingerly/types";
|
|
4
4
|
import type { FeatureConfigsMap } from "./types/assign-gingerly/types";
|
|
5
5
|
import type { AssignPermissions } from "./isAllowedImportPath.js";
|
|
6
|
+
import { normalizeAliasOptions } from './getValues.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Constructor signature for ItemScope Manager classes
|
|
@@ -82,6 +83,13 @@ export interface IAssignGingerlyOptions {
|
|
|
82
83
|
* // Equivalent to: element.querySelector('my-element').classList.add('highlighted')
|
|
83
84
|
*/
|
|
84
85
|
aka?: Record<string, string>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Shorthand for binding method aliases from the source object.
|
|
89
|
+
* Each entry maps an alias to a method name, and is normalized into
|
|
90
|
+
* the existing withMethods + aka behavior.
|
|
91
|
+
*/
|
|
92
|
+
akaMethods?: Record<string, string>;
|
|
85
93
|
|
|
86
94
|
/**
|
|
87
95
|
* AbortSignal for cleaning up reactive subscriptions (@eachTime)
|
|
@@ -759,13 +767,9 @@ export function assignGingerly(
|
|
|
759
767
|
if (!target || typeof target !== 'object') {
|
|
760
768
|
return target;
|
|
761
769
|
}
|
|
770
|
+
//TODO
|
|
762
771
|
|
|
763
|
-
|
|
764
|
-
const withMethodsSet = options?.withMethods
|
|
765
|
-
? options.withMethods instanceof Set
|
|
766
|
-
? options.withMethods
|
|
767
|
-
: new Set(options.withMethods)
|
|
768
|
-
: undefined;
|
|
772
|
+
const { aliasMap, withMethods: withMethodsSet } = normalizeAliasOptions(options);
|
|
769
773
|
|
|
770
774
|
// Convert withAsyncMethods array to Set for O(1) lookup
|
|
771
775
|
const withAsyncMethodsSet = options?.withAsyncMethods
|
|
@@ -774,18 +778,6 @@ export function assignGingerly(
|
|
|
774
778
|
: new Set(options.withAsyncMethods)
|
|
775
779
|
: undefined;
|
|
776
780
|
|
|
777
|
-
// Convert aka object to Map for O(1) lookup and validate aliases
|
|
778
|
-
const aliasMap = new Map<string, string>();
|
|
779
|
-
if (options?.aka) {
|
|
780
|
-
for (const [alias, target] of Object.entries(options.aka)) {
|
|
781
|
-
// Validate: disallow space and backtick in aliases
|
|
782
|
-
if (alias.includes(' ') || alias.includes('`')) {
|
|
783
|
-
throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
|
|
784
|
-
}
|
|
785
|
-
aliasMap.set(alias, target);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
781
|
const registry = options?.registry instanceof EnhancementRegistry
|
|
790
782
|
? options.registry
|
|
791
783
|
: options?.registry
|
package/assignTentatively.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* assignTentatively — reversible assignment with change tracking.
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
4
|
+
import type { IAssignTentativelyOptions } from './types/assign-gingerly/types.js';
|
|
5
|
+
export type { IAssignTentativelyOptions };
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Helper function to check if a string key represents an += command
|
package/getValues.js
CHANGED
|
@@ -16,6 +16,39 @@
|
|
|
16
16
|
* count: 42
|
|
17
17
|
* }, source, { withMethods: ['querySelector'], aka: { q: 'querySelector' } });
|
|
18
18
|
*/
|
|
19
|
+
//TODO
|
|
20
|
+
export function normalizeAliasOptions(options) {
|
|
21
|
+
const aliasMap = new Map();
|
|
22
|
+
if (options?.aka) {
|
|
23
|
+
for (const [alias, target] of Object.entries(options.aka)) {
|
|
24
|
+
if (alias.includes(' ') || alias.includes('`')) {
|
|
25
|
+
throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
|
|
26
|
+
}
|
|
27
|
+
aliasMap.set(alias, target);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (options?.akaMethods) {
|
|
31
|
+
for (const [alias, target] of Object.entries(options.akaMethods)) {
|
|
32
|
+
if (alias.includes(' ') || alias.includes('`')) {
|
|
33
|
+
throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
|
|
34
|
+
}
|
|
35
|
+
aliasMap.set(alias, target);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const withMethods = options?.withMethods
|
|
39
|
+
? options.withMethods instanceof Set
|
|
40
|
+
? new Set(options.withMethods)
|
|
41
|
+
: new Set(options.withMethods)
|
|
42
|
+
: options?.akaMethods
|
|
43
|
+
? new Set()
|
|
44
|
+
: undefined;
|
|
45
|
+
if (options?.akaMethods) {
|
|
46
|
+
for (const target of Object.values(options.akaMethods)) {
|
|
47
|
+
withMethods?.add(target);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { aliasMap, withMethods };
|
|
51
|
+
}
|
|
19
52
|
/**
|
|
20
53
|
* Apply alias substitutions to a path string.
|
|
21
54
|
* Replaces complete tokens between `?.` delimiters with their aliased values.
|
|
@@ -27,6 +60,17 @@ function applyAliases(path, aliasMap) {
|
|
|
27
60
|
const substituted = parts.map(part => aliasMap.get(part) ?? part);
|
|
28
61
|
return substituted.join('?.');
|
|
29
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve a special root-reference token at the start of a string.
|
|
65
|
+
* '$0' refers to the first argument passed to assignFrom / resolveValues.
|
|
66
|
+
*/
|
|
67
|
+
function resolveRootReference(path, source, root) {
|
|
68
|
+
if (path === '$0')
|
|
69
|
+
return { source: root ?? source, path: '' };
|
|
70
|
+
if (path.startsWith('$0?.'))
|
|
71
|
+
return { source: root ?? source, path: path.substring(4) };
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
30
74
|
/**
|
|
31
75
|
* Path cache for parsed path strings.
|
|
32
76
|
* Avoids re-splitting the same path on repeated calls.
|
|
@@ -116,6 +160,18 @@ function getArray(arr, source, aliasMap, withMethods, protocols, options) {
|
|
|
116
160
|
const parts = parseCachedPath(aliased);
|
|
117
161
|
result.push(parts.length === 0 ? source : navigatePath(source, parts, withMethods));
|
|
118
162
|
}
|
|
163
|
+
else if (typeof item === 'string' && item.startsWith('$0')) {
|
|
164
|
+
const rootRef = resolveRootReference(item, source, options?.root);
|
|
165
|
+
if (rootRef === null) {
|
|
166
|
+
result.push(source);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const aliased = applyAliases(rootRef.path, aliasMap);
|
|
170
|
+
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
171
|
+
const parts = parseCachedPath(normalizedPath);
|
|
172
|
+
result.push(parts.length === 0 ? rootRef.source : navigatePath(rootRef.source, parts, withMethods));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
119
175
|
else if (typeof item === 'string' && protocols && hasProtocol(item)) {
|
|
120
176
|
result.push(getProtocolValue(item, protocols, options));
|
|
121
177
|
}
|
|
@@ -150,19 +206,7 @@ function getArray(arr, source, aliasMap, withMethods, protocols, options) {
|
|
|
150
206
|
* @returns New object with path strings replaced by resolved values
|
|
151
207
|
*/
|
|
152
208
|
export function getValues(pattern, source, options) {
|
|
153
|
-
|
|
154
|
-
const aliasMap = new Map();
|
|
155
|
-
if (options?.aka) {
|
|
156
|
-
for (const [alias, target] of Object.entries(options.aka)) {
|
|
157
|
-
aliasMap.set(alias, target);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// Build methods set
|
|
161
|
-
const withMethods = options?.withMethods
|
|
162
|
-
? options.withMethods instanceof Set
|
|
163
|
-
? options.withMethods
|
|
164
|
-
: new Set(options.withMethods)
|
|
165
|
-
: undefined;
|
|
209
|
+
const { aliasMap, withMethods } = normalizeAliasOptions(options);
|
|
166
210
|
const protocols = options?.protocols;
|
|
167
211
|
const result = {};
|
|
168
212
|
for (const [key, value] of Object.entries(pattern)) {
|
|
@@ -171,6 +215,18 @@ export function getValues(pattern, source, options) {
|
|
|
171
215
|
const parts = parseCachedPath(aliased);
|
|
172
216
|
result[key] = parts.length === 0 ? source : navigatePath(source, parts, withMethods);
|
|
173
217
|
}
|
|
218
|
+
else if (typeof value === 'string' && value.startsWith('$0')) {
|
|
219
|
+
const rootRef = resolveRootReference(value, source, options?.root);
|
|
220
|
+
if (rootRef === null) {
|
|
221
|
+
result[key] = source;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
const aliased = applyAliases(rootRef.path, aliasMap);
|
|
225
|
+
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
226
|
+
const parts = parseCachedPath(normalizedPath);
|
|
227
|
+
result[key] = parts.length === 0 ? rootRef.source : navigatePath(rootRef.source, parts, withMethods);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
174
230
|
else if (typeof value === 'string' && protocols && hasProtocol(value)) {
|
|
175
231
|
result[key] = getProtocolValue(value, protocols, options);
|
|
176
232
|
}
|
|
@@ -201,23 +257,23 @@ export function getValues(pattern, source, options) {
|
|
|
201
257
|
* @returns The resolved value, or undefined if any segment is nullish
|
|
202
258
|
*/
|
|
203
259
|
export function getValue(path, source, options) {
|
|
204
|
-
|
|
260
|
+
const rootRef = resolveRootReference(path, source, options?.root);
|
|
261
|
+
if (rootRef) {
|
|
262
|
+
path = rootRef.path;
|
|
263
|
+
source = rootRef.source;
|
|
264
|
+
}
|
|
265
|
+
else if (!path.startsWith('?.')) {
|
|
205
266
|
return path;
|
|
267
|
+
}
|
|
206
268
|
let aliased = path;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
for (const [alias, target] of Object.entries(options.aka)) {
|
|
210
|
-
aliasMap.set(alias, target);
|
|
211
|
-
}
|
|
269
|
+
const { aliasMap } = normalizeAliasOptions(options);
|
|
270
|
+
if (aliasMap.size > 0) {
|
|
212
271
|
aliased = applyAliases(path, aliasMap);
|
|
213
272
|
}
|
|
214
|
-
const
|
|
273
|
+
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
274
|
+
const parts = parseCachedPath(normalizedPath);
|
|
215
275
|
if (parts.length === 0)
|
|
216
276
|
return source;
|
|
217
|
-
const withMethods = options
|
|
218
|
-
? options.withMethods instanceof Set
|
|
219
|
-
? options.withMethods
|
|
220
|
-
: new Set(options.withMethods)
|
|
221
|
-
: undefined;
|
|
277
|
+
const { withMethods } = normalizeAliasOptions(options);
|
|
222
278
|
return navigatePath(source, parts, withMethods);
|
|
223
279
|
}
|
package/getValues.ts
CHANGED
|
@@ -18,6 +18,48 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import type { GetValuesOptions } from './types/assign-gingerly/types.js';
|
|
21
|
+
//TODO
|
|
22
|
+
export function normalizeAliasOptions(options?: {
|
|
23
|
+
aka?: Record<string, string>;
|
|
24
|
+
akaMethods?: Record<string, string>;
|
|
25
|
+
withMethods?: string[] | Set<string>;
|
|
26
|
+
}): { aliasMap: Map<string, string>; withMethods: Set<string> | undefined } {
|
|
27
|
+
const aliasMap = new Map<string, string>();
|
|
28
|
+
|
|
29
|
+
if (options?.aka) {
|
|
30
|
+
for (const [alias, target] of Object.entries(options.aka)) {
|
|
31
|
+
if (alias.includes(' ') || alias.includes('`')) {
|
|
32
|
+
throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
|
|
33
|
+
}
|
|
34
|
+
aliasMap.set(alias, target);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (options?.akaMethods) {
|
|
39
|
+
for (const [alias, target] of Object.entries(options.akaMethods)) {
|
|
40
|
+
if (alias.includes(' ') || alias.includes('`')) {
|
|
41
|
+
throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
|
|
42
|
+
}
|
|
43
|
+
aliasMap.set(alias, target);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const withMethods = options?.withMethods
|
|
48
|
+
? options.withMethods instanceof Set
|
|
49
|
+
? new Set(options.withMethods)
|
|
50
|
+
: new Set(options.withMethods)
|
|
51
|
+
: options?.akaMethods
|
|
52
|
+
? new Set<string>()
|
|
53
|
+
: undefined;
|
|
54
|
+
|
|
55
|
+
if (options?.akaMethods) {
|
|
56
|
+
for (const target of Object.values(options.akaMethods)) {
|
|
57
|
+
withMethods?.add(target);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { aliasMap, withMethods };
|
|
62
|
+
}
|
|
21
63
|
|
|
22
64
|
/**
|
|
23
65
|
* Apply alias substitutions to a path string.
|
|
@@ -30,6 +72,16 @@ function applyAliases(path: string, aliasMap: Map<string, string>): string {
|
|
|
30
72
|
return substituted.join('?.');
|
|
31
73
|
}
|
|
32
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Resolve a special root-reference token at the start of a string.
|
|
77
|
+
* '$0' refers to the first argument passed to assignFrom / resolveValues.
|
|
78
|
+
*/
|
|
79
|
+
function resolveRootReference(path: string, source: any, root: any): { source: any; path: string } | null {
|
|
80
|
+
if (path === '$0') return { source: root ?? source, path: '' };
|
|
81
|
+
if (path.startsWith('$0?.')) return { source: root ?? source, path: path.substring(4) };
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
33
85
|
/**
|
|
34
86
|
* Path cache for parsed path strings.
|
|
35
87
|
* Avoids re-splitting the same path on repeated calls.
|
|
@@ -142,6 +194,16 @@ function getArray(
|
|
|
142
194
|
const aliased = applyAliases(item, aliasMap);
|
|
143
195
|
const parts = parseCachedPath(aliased);
|
|
144
196
|
result.push(parts.length === 0 ? source : navigatePath(source, parts, withMethods));
|
|
197
|
+
} else if (typeof item === 'string' && item.startsWith('$0')) {
|
|
198
|
+
const rootRef = resolveRootReference(item, source, options?.root);
|
|
199
|
+
if (rootRef === null) {
|
|
200
|
+
result.push(source);
|
|
201
|
+
} else {
|
|
202
|
+
const aliased = applyAliases(rootRef.path, aliasMap);
|
|
203
|
+
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
204
|
+
const parts = parseCachedPath(normalizedPath);
|
|
205
|
+
result.push(parts.length === 0 ? rootRef.source : navigatePath(rootRef.source, parts, withMethods));
|
|
206
|
+
}
|
|
145
207
|
} else if (typeof item === 'string' && protocols && hasProtocol(item)) {
|
|
146
208
|
result.push(getProtocolValue(item, protocols, options));
|
|
147
209
|
} else if (Array.isArray(item)) {
|
|
@@ -177,20 +239,7 @@ export function getValues(
|
|
|
177
239
|
source: any,
|
|
178
240
|
options?: GetValuesOptions
|
|
179
241
|
): Record<string, any> {
|
|
180
|
-
|
|
181
|
-
const aliasMap = new Map<string, string>();
|
|
182
|
-
if (options?.aka) {
|
|
183
|
-
for (const [alias, target] of Object.entries(options.aka)) {
|
|
184
|
-
aliasMap.set(alias, target);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Build methods set
|
|
189
|
-
const withMethods = options?.withMethods
|
|
190
|
-
? options.withMethods instanceof Set
|
|
191
|
-
? options.withMethods
|
|
192
|
-
: new Set(options.withMethods)
|
|
193
|
-
: undefined;
|
|
242
|
+
const { aliasMap, withMethods } = normalizeAliasOptions(options);
|
|
194
243
|
|
|
195
244
|
const protocols = options?.protocols;
|
|
196
245
|
|
|
@@ -200,6 +249,16 @@ export function getValues(
|
|
|
200
249
|
const aliased = applyAliases(value, aliasMap);
|
|
201
250
|
const parts = parseCachedPath(aliased);
|
|
202
251
|
result[key] = parts.length === 0 ? source : navigatePath(source, parts, withMethods);
|
|
252
|
+
} else if (typeof value === 'string' && value.startsWith('$0')) {
|
|
253
|
+
const rootRef = resolveRootReference(value, source, options?.root);
|
|
254
|
+
if (rootRef === null) {
|
|
255
|
+
result[key] = source;
|
|
256
|
+
} else {
|
|
257
|
+
const aliased = applyAliases(rootRef.path, aliasMap);
|
|
258
|
+
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
259
|
+
const parts = parseCachedPath(normalizedPath);
|
|
260
|
+
result[key] = parts.length === 0 ? rootRef.source : navigatePath(rootRef.source, parts, withMethods);
|
|
261
|
+
}
|
|
203
262
|
} else if (typeof value === 'string' && protocols && hasProtocol(value)) {
|
|
204
263
|
result[key] = getProtocolValue(value, protocols, options);
|
|
205
264
|
} else if (Array.isArray(value)) {
|
|
@@ -231,25 +290,25 @@ export function getValue(
|
|
|
231
290
|
source: any,
|
|
232
291
|
options?: GetValuesOptions
|
|
233
292
|
): any {
|
|
234
|
-
|
|
293
|
+
const rootRef = resolveRootReference(path, source, options?.root);
|
|
294
|
+
if (rootRef) {
|
|
295
|
+
path = rootRef.path;
|
|
296
|
+
source = rootRef.source;
|
|
297
|
+
} else if (!path.startsWith('?.')) {
|
|
298
|
+
return path;
|
|
299
|
+
}
|
|
235
300
|
|
|
236
301
|
let aliased = path;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
for (const [alias, target] of Object.entries(options.aka)) {
|
|
240
|
-
aliasMap.set(alias, target);
|
|
241
|
-
}
|
|
302
|
+
const { aliasMap } = normalizeAliasOptions(options);
|
|
303
|
+
if (aliasMap.size > 0) {
|
|
242
304
|
aliased = applyAliases(path, aliasMap);
|
|
243
305
|
}
|
|
244
306
|
|
|
245
|
-
const
|
|
307
|
+
const normalizedPath = aliased.startsWith('?.') ? aliased : (aliased ? `?.${aliased}` : '?.');
|
|
308
|
+
const parts = parseCachedPath(normalizedPath);
|
|
246
309
|
if (parts.length === 0) return source;
|
|
247
310
|
|
|
248
|
-
const withMethods = options
|
|
249
|
-
? options.withMethods instanceof Set
|
|
250
|
-
? options.withMethods
|
|
251
|
-
: new Set(options.withMethods)
|
|
252
|
-
: undefined;
|
|
311
|
+
const { withMethods } = normalizeAliasOptions(options);
|
|
253
312
|
|
|
254
313
|
return navigatePath(source, parts, withMethods);
|
|
255
314
|
}
|
package/handlers/arr.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function to normalize a value to an array.
|
|
3
|
+
* - If undefined, returns empty array
|
|
4
|
+
* - If already an array, returns as-is
|
|
5
|
+
* - Otherwise, wraps the value in an array
|
|
6
|
+
*
|
|
7
|
+
* @param inp - Value to normalize to array
|
|
8
|
+
* @returns Array containing the value(s)
|
|
9
|
+
*/
|
|
10
|
+
export function arr(inp) {
|
|
11
|
+
return inp === undefined ? []
|
|
12
|
+
: Array.isArray(inp) ? inp : [inp];
|
|
13
|
+
}
|
package/handlers/arr.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function to normalize a value to an array.
|
|
3
|
+
* - If undefined, returns empty array
|
|
4
|
+
* - If already an array, returns as-is
|
|
5
|
+
* - Otherwise, wraps the value in an array
|
|
6
|
+
*
|
|
7
|
+
* @param inp - Value to normalize to array
|
|
8
|
+
* @returns Array containing the value(s)
|
|
9
|
+
*/
|
|
10
|
+
export function arr<T = any>(inp: T | T[] | undefined): T[] {
|
|
11
|
+
return inp === undefined ? []
|
|
12
|
+
: Array.isArray(inp) ? inp : [inp];
|
|
13
|
+
}
|
|
@@ -149,7 +149,7 @@ export class ManageTemplateListHandler {
|
|
|
149
149
|
// New item — clone template
|
|
150
150
|
let content;
|
|
151
151
|
if (instantiate instanceof HTMLTemplateElement) {
|
|
152
|
-
content = instantiate.content.cloneNode(true);
|
|
152
|
+
content = (instantiate.remoteContent || instantiate.content).cloneNode(true);
|
|
153
153
|
}
|
|
154
154
|
else if (instantiate instanceof DocumentFragment) {
|
|
155
155
|
content = instantiate.cloneNode(true);
|
|
@@ -182,7 +182,7 @@ export class ManageTemplateListHandler implements AssignFromHandler {
|
|
|
182
182
|
// New item — clone template
|
|
183
183
|
let content: DocumentFragment;
|
|
184
184
|
if (instantiate instanceof HTMLTemplateElement) {
|
|
185
|
-
content = instantiate.content.cloneNode(true) as DocumentFragment;
|
|
185
|
+
content = (instantiate.remoteContent ||instantiate.content).cloneNode(true) as DocumentFragment;
|
|
186
186
|
} else if (instantiate instanceof DocumentFragment) {
|
|
187
187
|
content = instantiate.cloneNode(true) as DocumentFragment;
|
|
188
188
|
} else {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { arr } from './arr.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decrement "disabled" counter, remove when reaches 0
|
|
4
|
+
* @param el
|
|
5
|
+
* Optional select the attribute or attributes to remove or decrement
|
|
6
|
+
* @param attr
|
|
7
|
+
*/
|
|
8
|
+
export function nudge(el, attr = 'disabled') {
|
|
9
|
+
const attrs = arr(attr);
|
|
10
|
+
for (const attr of attrs) {
|
|
11
|
+
const da = el.getAttribute(attr);
|
|
12
|
+
if (da !== null) {
|
|
13
|
+
if (da.length === 0 || da === "1") {
|
|
14
|
+
el.removeAttribute(attr);
|
|
15
|
+
if (attr === 'disabled')
|
|
16
|
+
el.disabled = false;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
el.setAttribute(attr, (parseInt(da) - 1).toString());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {arr} from './arr.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decrement "disabled" counter, remove when reaches 0
|
|
4
|
+
* @param el
|
|
5
|
+
* Optional select the attribute or attributes to remove or decrement
|
|
6
|
+
* @param attr
|
|
7
|
+
*/
|
|
8
|
+
export function nudge(el: Element, attr: string | Array<string> = 'disabled') { //TODO: Share with be-observant
|
|
9
|
+
const attrs = arr(attr);
|
|
10
|
+
for(const attr of attrs){
|
|
11
|
+
const da = el.getAttribute(attr);
|
|
12
|
+
if (da !== null) {
|
|
13
|
+
if (da.length === 0 || da === "1") {
|
|
14
|
+
el.removeAttribute(attr);
|
|
15
|
+
if(attr === 'disabled') (<any>el).disabled = false;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
el.setAttribute(attr, (parseInt(da) - 1).toString());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
package/index.js
CHANGED
|
@@ -14,4 +14,6 @@ export { assignFeatures, FeaturesRegistry, captureFeatureInitVals, PropertyBag,
|
|
|
14
14
|
export { installForwarding } from './installForwarding.js';
|
|
15
15
|
export { defineWithFeatures } from './defineWithFeatures.js';
|
|
16
16
|
export { resolveAndAssignFeatures } from './resolveAndAssignFeatures.js';
|
|
17
|
+
export { nudge } from './handlers/nudge.js';
|
|
18
|
+
export { arr } from './handlers/arr.js';
|
|
17
19
|
import './object-extension.js';
|
package/index.ts
CHANGED
|
@@ -14,5 +14,7 @@ export {assignFeatures, FeaturesRegistry, captureFeatureInitVals, PropertyBag, s
|
|
|
14
14
|
export {installForwarding} from './installForwarding.js';
|
|
15
15
|
export {defineWithFeatures} from './defineWithFeatures.js';
|
|
16
16
|
export {resolveAndAssignFeatures} from './resolveAndAssignFeatures.js';
|
|
17
|
+
export {nudge} from './handlers/nudge.js';
|
|
18
|
+
export {arr} from './handlers/arr.js';
|
|
17
19
|
export {} from './handlers/manageTemplateList.js';
|
|
18
20
|
import './object-extension.js';
|