assign-gingerly 0.0.1 → 0.0.2
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 +17 -4
- package/index.d.ts +1 -1
- package/index.js +42 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -84,14 +84,14 @@ class YourEnhancement extends ElementEnhancement(EventTarget){
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
class BaseRegistry{
|
|
87
|
-
|
|
87
|
+
push(IBaseRegistryItem | IBaseRegistryItem[]){
|
|
88
88
|
...
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
//Here's where the dependency injection mapping takes place
|
|
93
93
|
const baseRegistry = new BaseRegistry;
|
|
94
|
-
baseRegistry.
|
|
94
|
+
baseRegistry.push([
|
|
95
95
|
{
|
|
96
96
|
map: {
|
|
97
97
|
[isHappy]: 'isHappy'
|
|
@@ -120,12 +120,25 @@ const asyncResult = await assignGingerly({}, {
|
|
|
120
120
|
asyncResult.set[isMellow] = false;
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
The assignGingerly searches the registry for any items that has a mapping with a matching symbol of isHappy and isMellow, and if found, sees it already has an instance of the spawn class associated with the first passed in parameter. If no such instance is found, it instantiates one, associates the instance with the first parameter, then sets the property value.
|
|
123
|
+
The assignGingerly searches the registry for any items that has a mapping with a matching symbol of isHappy and isMellow, and if found, sees if it already has an instance of the spawn class associated with the first passed in parameter. If no such instance is found, it instantiates one, associates the instance with the first parameter, then sets the property value.
|
|
124
124
|
|
|
125
125
|
It also adds a lazy property to the first passed in parameter, "set", which returns a proxy, and that proxy watches for symbol references passed in a value, and sets the value from that spawned instance. Again, if the spawned instance is not found, it respawns it.
|
|
126
126
|
|
|
127
127
|
The suggestion to use Symbol.for with a guid, as opposed to just Symbol(), is based on some negative experiences I've had with multiple versions of the same library being referenced, but is not required. Regular symbols could also be used when that risk can be avoided.
|
|
128
128
|
|
|
129
|
-
Note the first time we mention async. This is only necessary if you wish to work directly with the merged object. This allows for lazy loading of the spawning class, which can be useful for large applications that don't need to download all the classes at once. If you are just "depositing" values into the object, no need to await for anything. Also, the assignGingerly should first do all the class instantiations that are already loaded (where the class constructor is specified in spawn), and then does all the lazy loaded ones.
|
|
129
|
+
Note that the example above is the first time we mention async. This is only necessary if you wish to work directly with the merged object. This allows for lazy loading of the spawning class, which can be useful for large applications that don't need to download all the classes at once. If you are just "depositing" values into the object, no need to await for anything. Also, the assignGingerly should first do all the class instantiations that are already loaded (where the class constructor is specified in spawn), and then does all the lazy loaded ones.
|
|
130
|
+
|
|
131
|
+
## Support for JSON assignment with Symbol.for symbols
|
|
132
|
+
|
|
133
|
+
```JavaScript
|
|
134
|
+
const asyncResult = await assignGingerly({}, {
|
|
135
|
+
"[Symbol.for('TFWsx0YH5E6eSfhE7zfLxA')]": true,
|
|
136
|
+
"[Symbol.for('BqnnTPWRHkWdVGWcGQoAiw')]": true,
|
|
137
|
+
'?.style.height': '40px',
|
|
138
|
+
'?.enhancements?.mellowYellow?.madAboutFourteen': true
|
|
139
|
+
}, {
|
|
140
|
+
registry: BaseRegistry
|
|
141
|
+
});
|
|
142
|
+
```
|
|
130
143
|
|
|
131
144
|
|
package/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export interface IAssignGingerlyOptions {
|
|
|
18
18
|
*/
|
|
19
19
|
export declare class BaseRegistry {
|
|
20
20
|
private items;
|
|
21
|
-
|
|
21
|
+
push(items: IBaseRegistryItem | IBaseRegistryItem[]): void;
|
|
22
22
|
getItems(): IBaseRegistryItem[];
|
|
23
23
|
findBySymbol(symbol: symbol | string): IBaseRegistryItem | undefined;
|
|
24
24
|
}
|
package/index.js
CHANGED
|
@@ -7,7 +7,7 @@ const instanceMap = new WeakMap();
|
|
|
7
7
|
*/
|
|
8
8
|
export class BaseRegistry {
|
|
9
9
|
items = [];
|
|
10
|
-
|
|
10
|
+
push(items) {
|
|
11
11
|
if (Array.isArray(items)) {
|
|
12
12
|
this.items.push(...items);
|
|
13
13
|
}
|
|
@@ -30,6 +30,22 @@ export class BaseRegistry {
|
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Helper function to check if a string key represents a Symbol.for expression
|
|
35
|
+
*/
|
|
36
|
+
function isSymbolForKey(key) {
|
|
37
|
+
return key.startsWith('[Symbol.for(') && key.endsWith(')]');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Helper function to extract the symbol key from a Symbol.for string
|
|
41
|
+
*/
|
|
42
|
+
function parseSymbolForKey(key) {
|
|
43
|
+
const match = key.match(/^\[Symbol\.for\(['"](.+)['"]\)\]$/);
|
|
44
|
+
if (match && match[1]) {
|
|
45
|
+
return Symbol.for(match[1]);
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
33
49
|
/**
|
|
34
50
|
* Helper function to parse a path string with ?. notation
|
|
35
51
|
*/
|
|
@@ -72,9 +88,30 @@ export async function assignGingerly(target, source, options) {
|
|
|
72
88
|
: undefined;
|
|
73
89
|
// Track promises for async spawning
|
|
74
90
|
const asyncSpawns = [];
|
|
75
|
-
//
|
|
91
|
+
// Convert Symbol.for string keys to actual symbols
|
|
92
|
+
const processedSource = {};
|
|
76
93
|
for (const key of Object.keys(source)) {
|
|
77
|
-
|
|
94
|
+
if (isSymbolForKey(key)) {
|
|
95
|
+
const symbol = parseSymbolForKey(key);
|
|
96
|
+
if (symbol) {
|
|
97
|
+
processedSource[symbol] = source[key];
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Invalid Symbol.for format - treat as regular string key
|
|
101
|
+
processedSource[key] = source[key];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
processedSource[key] = source[key];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Copy over actual symbol keys
|
|
109
|
+
for (const sym of Object.getOwnPropertySymbols(source)) {
|
|
110
|
+
processedSource[sym] = source[sym];
|
|
111
|
+
}
|
|
112
|
+
// First pass: handle all non-symbol keys and sync operations
|
|
113
|
+
for (const key of Object.keys(processedSource)) {
|
|
114
|
+
const value = processedSource[key];
|
|
78
115
|
if (isNestedPath(key)) {
|
|
79
116
|
const pathParts = parsePath(key);
|
|
80
117
|
const lastKey = pathParts[pathParts.length - 1];
|
|
@@ -104,9 +141,9 @@ export async function assignGingerly(target, source, options) {
|
|
|
104
141
|
}
|
|
105
142
|
}
|
|
106
143
|
// Second pass: handle symbol keys for dependency injection
|
|
107
|
-
const symbols = Object.getOwnPropertySymbols(
|
|
144
|
+
const symbols = Object.getOwnPropertySymbols(processedSource);
|
|
108
145
|
for (const sym of symbols) {
|
|
109
|
-
const value =
|
|
146
|
+
const value = processedSource[sym];
|
|
110
147
|
if (registry) {
|
|
111
148
|
const registryItem = registry.findBySymbol(sym);
|
|
112
149
|
if (registryItem) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "assign-gingerly",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
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": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"update": "ncu -u && npm install"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@playwright/test": "^1.
|
|
37
|
-
"spa-ssi": "0.0.
|
|
38
|
-
"@types/node": "^
|
|
36
|
+
"@playwright/test": "^1.58.0",
|
|
37
|
+
"spa-ssi": "0.0.26",
|
|
38
|
+
"@types/node": "^25.0.10",
|
|
39
39
|
"typescript": "^5.9.3"
|
|
40
40
|
}
|
|
41
41
|
}
|