@dooboostore/simple-web-component 1.0.42 → 1.0.43
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 +423 -68
- package/dist/cjs/decorators/addEventListener.js +10 -0
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +11 -2
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +9 -2
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +11 -2
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyProperty.js +10 -2
- package/dist/cjs/decorators/applyProperty.js.map +2 -2
- package/dist/cjs/decorators/applySlot.js +11 -2
- package/dist/cjs/decorators/applySlot.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +9 -2
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/emitCustomEvent.js +2 -0
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/publishSwcAppMessage.js +37 -23
- package/dist/cjs/decorators/publishSwcAppMessage.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +10 -0
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +11 -2
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +9 -2
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +11 -2
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyProperty.js +10 -2
- package/dist/esm/decorators/applyProperty.js.map +2 -2
- package/dist/esm/decorators/applySlot.js +11 -2
- package/dist/esm/decorators/applySlot.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +9 -2
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +2 -0
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/publishSwcAppMessage.js +37 -23
- package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +146 -71
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +3 -3
- package/dist/types/decorators/addEventListener.d.ts +5 -0
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +26 -0
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +6 -0
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +6 -0
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyProperty.d.ts +26 -0
- package/dist/types/decorators/applyProperty.d.ts.map +1 -1
- package/dist/types/decorators/applySlot.d.ts +6 -0
- package/dist/types/decorators/applySlot.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +6 -0
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +17 -0
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts +19 -0
- package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +146 -71
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +3 -3
- package/package.json +7 -9
- package/src/decorators/addEventListener.ts +7 -0
- package/src/decorators/applyAttribute.ts +58 -2
- package/src/decorators/applyClass.ts +24 -2
- package/src/decorators/applyNode.ts +26 -2
- package/src/decorators/applyProperty.ts +57 -2
- package/src/decorators/applySlot.ts +24 -10
- package/src/decorators/applyStyle.ts +24 -2
- package/src/decorators/emitCustomEvent.ts +19 -0
- package/src/decorators/publishSwcAppMessage.ts +71 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dooboostore/simple-web-component",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.43",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -67,11 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"author": "dooboostore <dooboostore@gmail.com> (https://github.com/dooboostore)",
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"reflect-metadata": "^0.2.2"
|
|
71
|
-
"@dooboostore/core": "1.0.32",
|
|
72
|
-
"@dooboostore/simple-boot": "1.0.56",
|
|
73
|
-
"@dooboostore/core-web": "1.0.12",
|
|
74
|
-
"@dooboostore/core-node": "1.0.12"
|
|
70
|
+
"reflect-metadata": "^0.2.2"
|
|
75
71
|
},
|
|
76
72
|
"devDependencies": {
|
|
77
73
|
"@babel/core": "^7.24.0",
|
|
@@ -95,7 +91,11 @@
|
|
|
95
91
|
"typescript": "^5.9.2",
|
|
96
92
|
"webpack": "^5.93.0",
|
|
97
93
|
"webpack-cli": "^5.1.4",
|
|
98
|
-
"webpack-dev-server": "^5.2.0"
|
|
94
|
+
"webpack-dev-server": "^5.2.0",
|
|
95
|
+
"@dooboostore/core": "1.0.32",
|
|
96
|
+
"@dooboostore/core-node": "1.0.12",
|
|
97
|
+
"@dooboostore/core-web": "1.0.12",
|
|
98
|
+
"@dooboostore/simple-boot": "1.0.56"
|
|
99
99
|
},
|
|
100
100
|
"scripts": {
|
|
101
101
|
"clean": "rm -rf dist",
|
|
@@ -112,8 +112,6 @@
|
|
|
112
112
|
"publish:npm": "pnpm run build && cp package.json package.json.back && pnpm pack && TARBALL_NAME=$(ls dooboostore-simple-web-component-*.tgz | head -n 1) && tar -xzf \"$TARBALL_NAME\" -C . --strip-components=1 package/package.json && rm \"$TARBALL_NAME\" && (pnpm publish --no-git-checks || true) && cp package.json.back package.json && rm -rf package.json.back ",
|
|
113
113
|
"ts:clean": "find . -name '*.js' -o -name '*.map' -o -name '*.d.ts' | xargs rm -f",
|
|
114
114
|
"typecheck": "pnpm exec tsc --noEmit",
|
|
115
|
-
"generate:is": "tsx generate-is.ts",
|
|
116
|
-
"generate:is:watch": "node --import tsx --watch --watch-path=./src/elements/SwcIf.ts --watch-path=./src/elements/SwcLoop.ts --watch-path=./src/elements/SwcChoose.ts --watch-path=./src/elements/SwcAsync.ts --watch-path=./src/elements/SwcAppMixin.ts --watch-path=./generate-is.ts generate-is.ts",
|
|
117
115
|
"test": "echo test",
|
|
118
116
|
"test:bundle": "pnpm --filter @dooboostore/simple-web-component-bundle-test dev"
|
|
119
117
|
}
|
|
@@ -59,6 +59,13 @@ export function addEventListenerDelegate(selector: string, type: string, options
|
|
|
59
59
|
/**
|
|
60
60
|
* @addEventListenerThis decorator - simplified version of @addEventListener for $this selector
|
|
61
61
|
*/
|
|
62
|
+
|
|
63
|
+
// --- Aliases: event... ---
|
|
64
|
+
export const event = addEventListener;
|
|
65
|
+
export const eventDelegateLightDom = addEventListenerDelegateLightDom;
|
|
66
|
+
export const eventDelegateShadowDom = addEventListenerDelegateShadowDom;
|
|
67
|
+
export const eventDelegateAllDom = addEventListenerDelegateAllDom;
|
|
68
|
+
export const eventDelegate = addEventListenerDelegate;
|
|
62
69
|
export function addEventListenerThis(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {
|
|
63
70
|
return addEventListener('$this', type, options);
|
|
64
71
|
}
|
|
@@ -12,6 +12,32 @@ export interface AttributeOptions extends SwcQueryOptions {
|
|
|
12
12
|
name?: string;
|
|
13
13
|
type?: typeof Number | typeof Boolean | typeof String;
|
|
14
14
|
filter?: (target: HTMLElement, value: any, meta: { currentThis: any, helper: HelperHostSet }) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Custom key to extract value from return object.
|
|
17
|
+
* If not provided, uses ATTRIBUTE_METADATA_KEY by default.
|
|
18
|
+
* Useful when multiple @setAttribute decorators are on the same method.
|
|
19
|
+
*
|
|
20
|
+
* Example:
|
|
21
|
+
* @setAttribute('selector1', { valueKey: 'attr1' })
|
|
22
|
+
* @setAttribute('selector2', { valueKey: 'attr2' })
|
|
23
|
+
* myMethod() {
|
|
24
|
+
* return {
|
|
25
|
+
* attr1: 'value1',
|
|
26
|
+
* attr2: 'value2'
|
|
27
|
+
* };
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* Or with symbols:
|
|
31
|
+
* @setAttribute('selector1', { valueKey: Symbol.for('attr1') })
|
|
32
|
+
* @setAttribute('selector2', { valueKey: Symbol.for('attr2') })
|
|
33
|
+
* myMethod() {
|
|
34
|
+
* return {
|
|
35
|
+
* [Symbol.for('attr1')]: 'value1',
|
|
36
|
+
* [Symbol.for('attr2')]: 'value2'
|
|
37
|
+
* };
|
|
38
|
+
* }
|
|
39
|
+
*/
|
|
40
|
+
valueKey?: symbol | string;
|
|
15
41
|
}
|
|
16
42
|
|
|
17
43
|
export interface AttributeMetadata {
|
|
@@ -210,13 +236,43 @@ export function applyAttribute(selector: string, targetAttributeNameOrOptions?:
|
|
|
210
236
|
ensureInit(this);
|
|
211
237
|
const res = (original as any).apply(this, args);
|
|
212
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Extract value for this decorator from method return value
|
|
241
|
+
*
|
|
242
|
+
* If return value is an object with this decorator's key,
|
|
243
|
+
* use that value. Otherwise use the entire return value.
|
|
244
|
+
*
|
|
245
|
+
* Uses valueKey from options if provided, otherwise uses ATTRIBUTE_METADATA_KEY.
|
|
246
|
+
*
|
|
247
|
+
* Example:
|
|
248
|
+
* @setAttribute('selector1', { valueKey: 'attr1' })
|
|
249
|
+
* @setAttribute('selector2', { valueKey: 'attr2' })
|
|
250
|
+
* myMethod() {
|
|
251
|
+
* return {
|
|
252
|
+
* attr1: 'attribute-value1',
|
|
253
|
+
* attr2: 'attribute-value2'
|
|
254
|
+
* };
|
|
255
|
+
* }
|
|
256
|
+
*
|
|
257
|
+
* First decorator will use 'attribute-value1', second will use 'attribute-value2'
|
|
258
|
+
*/
|
|
259
|
+
const extractValue = (v: any) => {
|
|
260
|
+
const keyToUse = finalOptions.valueKey ?? ATTRIBUTE_METADATA_KEY;
|
|
261
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
262
|
+
return v[keyToUse];
|
|
263
|
+
}
|
|
264
|
+
return v;
|
|
265
|
+
};
|
|
266
|
+
|
|
213
267
|
if (res instanceof Promise) {
|
|
214
268
|
return res.then((v: any) => {
|
|
215
|
-
|
|
269
|
+
const extracted = extractValue(v);
|
|
270
|
+
applyValueToTargets(this, extracted);
|
|
216
271
|
return v;
|
|
217
272
|
});
|
|
218
273
|
} else {
|
|
219
|
-
|
|
274
|
+
const extracted = extractValue(res);
|
|
275
|
+
applyValueToTargets(this, extracted);
|
|
220
276
|
return res;
|
|
221
277
|
}
|
|
222
278
|
};
|
|
@@ -9,6 +9,12 @@ export type ClassAction = 'set' | 'update' | 'add' | 'remove' | 'toggle';
|
|
|
9
9
|
|
|
10
10
|
export interface ClassApplyOptions extends SwcQueryOptions {
|
|
11
11
|
filter?: (target: HTMLElement, value: any, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Custom key to extract value from return object.
|
|
14
|
+
* If not provided, uses CLASS_METADATA_KEY by default.
|
|
15
|
+
* Useful when multiple @applyClass decorators are on the same method.
|
|
16
|
+
*/
|
|
17
|
+
valueKey?: symbol | string;
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
export interface ClassApplyMetadata {
|
|
@@ -44,6 +50,22 @@ function createClassDecorator(action: ClassAction) {
|
|
|
44
50
|
ensureInit(this);
|
|
45
51
|
const res = (original as any).apply(this, args);
|
|
46
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Extract value for this decorator from method return value
|
|
55
|
+
*
|
|
56
|
+
* If return value is an object with this decorator's key,
|
|
57
|
+
* use that value. Otherwise use the entire return value.
|
|
58
|
+
*
|
|
59
|
+
* Uses valueKey from options if provided, otherwise uses CLASS_METADATA_KEY.
|
|
60
|
+
*/
|
|
61
|
+
const extractValue = (v: any) => {
|
|
62
|
+
const keyToUse = finalOptions.valueKey ?? CLASS_METADATA_KEY;
|
|
63
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
64
|
+
return v[keyToUse];
|
|
65
|
+
}
|
|
66
|
+
return v;
|
|
67
|
+
};
|
|
68
|
+
|
|
47
69
|
const handleResult = (resolvedValue: any) => {
|
|
48
70
|
if (resolvedValue !== undefined) {
|
|
49
71
|
const win = (this as any).ownerDocument?.defaultView || window;
|
|
@@ -131,9 +153,9 @@ function createClassDecorator(action: ClassAction) {
|
|
|
131
153
|
};
|
|
132
154
|
|
|
133
155
|
if (res instanceof Promise) {
|
|
134
|
-
return res.then(handleResult);
|
|
156
|
+
return res.then((v: any) => handleResult(extractValue(v)));
|
|
135
157
|
} else {
|
|
136
|
-
return handleResult(res);
|
|
158
|
+
return handleResult(extractValue(res));
|
|
137
159
|
}
|
|
138
160
|
};
|
|
139
161
|
return descriptor;
|
|
@@ -27,6 +27,12 @@ export interface ApplyNodeOptions {
|
|
|
27
27
|
* Optional loading content to display while an async method is executing.
|
|
28
28
|
*/
|
|
29
29
|
fallback?: (helper: HelperHostSet) => any;
|
|
30
|
+
/**
|
|
31
|
+
* Custom key to extract value from return object.
|
|
32
|
+
* If not provided, uses APPLY_NODE_METADATA_KEY by default.
|
|
33
|
+
* Useful when multiple @applyNode decorators are on the same method.
|
|
34
|
+
*/
|
|
35
|
+
valueKey?: symbol | string;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
export interface ApplyNodeMetadata {
|
|
@@ -140,6 +146,22 @@ export function applyNode(selector: string, options: ApplyNodeOptions = {positio
|
|
|
140
146
|
const targetEl = getTarget();
|
|
141
147
|
const res = original.apply(this, args);
|
|
142
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Extract value for this decorator from method return value
|
|
151
|
+
*
|
|
152
|
+
* If return value is an object with this decorator's key,
|
|
153
|
+
* use that value. Otherwise use the entire return value.
|
|
154
|
+
*
|
|
155
|
+
* Uses valueKey from options if provided, otherwise uses APPLY_NODE_METADATA_KEY.
|
|
156
|
+
*/
|
|
157
|
+
const extractValue = (v: any) => {
|
|
158
|
+
const keyToUse = options.valueKey ?? APPLY_NODE_METADATA_KEY;
|
|
159
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
160
|
+
return v[keyToUse];
|
|
161
|
+
}
|
|
162
|
+
return v;
|
|
163
|
+
};
|
|
164
|
+
|
|
143
165
|
const runApply = (target: any, val: any) => {
|
|
144
166
|
const pos = options.position || 'beforeEnd';
|
|
145
167
|
// Delegate HTML/node processing to applyToDom which centralizes
|
|
@@ -163,12 +185,14 @@ export function applyNode(selector: string, options: ApplyNodeOptions = {positio
|
|
|
163
185
|
|
|
164
186
|
if (res instanceof Promise) {
|
|
165
187
|
return res.then(finalRes => {
|
|
188
|
+
const extracted = extractValue(finalRes);
|
|
166
189
|
fallbackNodes.forEach((it: any)=>it.remove());
|
|
167
|
-
if (
|
|
190
|
+
if (extracted !== undefined && targetEl) runApply(targetEl, extracted);
|
|
168
191
|
return finalRes;
|
|
169
192
|
});
|
|
170
193
|
} else {
|
|
171
|
-
|
|
194
|
+
const extracted = extractValue(res);
|
|
195
|
+
if (extracted !== undefined && targetEl) runApply(targetEl, extracted);
|
|
172
196
|
return res;
|
|
173
197
|
}
|
|
174
198
|
};
|
|
@@ -6,6 +6,32 @@ import { SwcQueryOptions, HelperHostSet } from '../types';
|
|
|
6
6
|
export interface PropertyOptions extends SwcQueryOptions {
|
|
7
7
|
name?: string | symbol;
|
|
8
8
|
filter?: (target: HTMLElement, value: any, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Custom key to extract value from return object.
|
|
11
|
+
* If not provided, uses PROPERTY_METADATA_KEY by default.
|
|
12
|
+
* Useful when multiple @setProperty decorators are on the same method.
|
|
13
|
+
*
|
|
14
|
+
* Example:
|
|
15
|
+
* @setProperty('selector1', { valueKey: 'prop1' })
|
|
16
|
+
* @setProperty('selector2', { valueKey: 'prop2' })
|
|
17
|
+
* myMethod() {
|
|
18
|
+
* return {
|
|
19
|
+
* prop1: 'value1',
|
|
20
|
+
* prop2: 'value2'
|
|
21
|
+
* };
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* Or with symbols:
|
|
25
|
+
* @setProperty('selector1', { valueKey: Symbol.for('prop1') })
|
|
26
|
+
* @setProperty('selector2', { valueKey: Symbol.for('prop2') })
|
|
27
|
+
* myMethod() {
|
|
28
|
+
* return {
|
|
29
|
+
* [Symbol.for('prop1')]: 'value1',
|
|
30
|
+
* [Symbol.for('prop2')]: 'value2'
|
|
31
|
+
* };
|
|
32
|
+
* }
|
|
33
|
+
*/
|
|
34
|
+
valueKey?: symbol | string;
|
|
9
35
|
}
|
|
10
36
|
|
|
11
37
|
export interface PropertyMetadata {
|
|
@@ -159,10 +185,39 @@ export function applyProperty(selector: string, targetPropertyKeyOrOptions?: str
|
|
|
159
185
|
ensureInit(this);
|
|
160
186
|
const res = (original as any).apply(this, args);
|
|
161
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Extract value for this decorator from method return value
|
|
190
|
+
*
|
|
191
|
+
* If return value is an object with this decorator's symbol key,
|
|
192
|
+
* use that value. Otherwise use the entire return value.
|
|
193
|
+
*
|
|
194
|
+
* Example:
|
|
195
|
+
* @setProperty('selector')
|
|
196
|
+
* myMethod() {
|
|
197
|
+
* return {
|
|
198
|
+
* [PROPERTY_METADATA_KEY]: 'property-value',
|
|
199
|
+
* [OTHER_DECORATOR_KEY]: 'other-value'
|
|
200
|
+
* };
|
|
201
|
+
* }
|
|
202
|
+
*
|
|
203
|
+
* This decorator will use 'property-value'
|
|
204
|
+
*/
|
|
205
|
+
const extractValue = (v: any) => {
|
|
206
|
+
if (v && typeof v === 'object' && PROPERTY_METADATA_KEY in v) {
|
|
207
|
+
return v[PROPERTY_METADATA_KEY];
|
|
208
|
+
}
|
|
209
|
+
return v;
|
|
210
|
+
};
|
|
211
|
+
|
|
162
212
|
if (res instanceof Promise) {
|
|
163
|
-
return res.then((v: any) => {
|
|
213
|
+
return res.then((v: any) => {
|
|
214
|
+
const extracted = extractValue(v);
|
|
215
|
+
applyValueToTargets(this, extracted);
|
|
216
|
+
return v;
|
|
217
|
+
});
|
|
164
218
|
} else {
|
|
165
|
-
|
|
219
|
+
const extracted = extractValue(res);
|
|
220
|
+
applyValueToTargets(this, extracted);
|
|
166
221
|
return res;
|
|
167
222
|
}
|
|
168
223
|
};
|
|
@@ -17,16 +17,12 @@ export type ApplySlotPosition = 'prepend' | 'prependHtml' | 'prependText' | 'app
|
|
|
17
17
|
export interface ApplySlotOptions {
|
|
18
18
|
position: ApplySlotPosition;
|
|
19
19
|
fallback?: (helper: HelperHostSet) => string | Node;
|
|
20
|
-
// root?: SwcRootType;
|
|
21
20
|
/**
|
|
22
|
-
*
|
|
23
|
-
* If
|
|
21
|
+
* Custom key to extract value from return object.
|
|
22
|
+
* If not provided, uses APPLY_SLOT_METADATA_KEY by default.
|
|
23
|
+
* Useful when multiple @applySlot decorators are on the same method.
|
|
24
24
|
*/
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Optional loading content to display while an async method is executing.
|
|
28
|
-
*/
|
|
29
|
-
// loading?: (helper: HelperHostSet) => any;
|
|
25
|
+
valueKey?: symbol | string;
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
export interface ApplySlotMetadata {
|
|
@@ -144,15 +140,33 @@ export function applySlot(targetId: string, opt: OptionalType<ApplySlotOptions,
|
|
|
144
140
|
applyToDom(swcId, targetId, options.position, nodes);
|
|
145
141
|
}
|
|
146
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Extract value for this decorator from method return value
|
|
145
|
+
*
|
|
146
|
+
* If return value is an object with this decorator's key,
|
|
147
|
+
* use that value. Otherwise use the entire return value.
|
|
148
|
+
*
|
|
149
|
+
* Uses valueKey from options if provided, otherwise uses APPLY_SLOT_METADATA_KEY.
|
|
150
|
+
*/
|
|
151
|
+
const extractValue = (v: any) => {
|
|
152
|
+
const keyToUse = options.valueKey ?? APPLY_SLOT_METADATA_KEY;
|
|
153
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
154
|
+
return v[keyToUse];
|
|
155
|
+
}
|
|
156
|
+
return v;
|
|
157
|
+
};
|
|
158
|
+
|
|
147
159
|
let res = original.apply(this, args);
|
|
148
160
|
if (res instanceof Promise) {
|
|
149
161
|
return res.then(asyncRes => {
|
|
150
|
-
const
|
|
162
|
+
const extracted = extractValue(asyncRes);
|
|
163
|
+
const nodes = resToNodes(extracted)
|
|
151
164
|
fallbackNodes.forEach((it: any) => it.remove());
|
|
152
165
|
applyToDom(swcId, targetId, options.position, nodes);
|
|
153
166
|
})
|
|
154
167
|
} else {
|
|
155
|
-
const
|
|
168
|
+
const extracted = extractValue(res);
|
|
169
|
+
const nodes: Node[] = resToNodes(extracted);
|
|
156
170
|
applyToDom(swcId, targetId, options.position, nodes);
|
|
157
171
|
}
|
|
158
172
|
};
|
|
@@ -7,6 +7,12 @@ export type StyleAction = 'set' | 'update' | 'remove';
|
|
|
7
7
|
|
|
8
8
|
export interface StyleApplyOptions extends SwcQueryOptions {
|
|
9
9
|
filter?: (target: HTMLElement, value: any, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Custom key to extract value from return object.
|
|
12
|
+
* If not provided, uses STYLE_METADATA_KEY by default.
|
|
13
|
+
* Useful when multiple @applyStyle decorators are on the same method.
|
|
14
|
+
*/
|
|
15
|
+
valueKey?: symbol | string;
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
export interface StyleApplyMetadata {
|
|
@@ -34,6 +40,22 @@ function createStyleDecorator(action: StyleAction) {
|
|
|
34
40
|
ensureInit(this);
|
|
35
41
|
const res = (original as any).apply(this, args);
|
|
36
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Extract value for this decorator from method return value
|
|
45
|
+
*
|
|
46
|
+
* If return value is an object with this decorator's key,
|
|
47
|
+
* use that value. Otherwise use the entire return value.
|
|
48
|
+
*
|
|
49
|
+
* Uses valueKey from options if provided, otherwise uses STYLE_METADATA_KEY.
|
|
50
|
+
*/
|
|
51
|
+
const extractValue = (v: any) => {
|
|
52
|
+
const keyToUse = options.valueKey ?? STYLE_METADATA_KEY;
|
|
53
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
54
|
+
return v[keyToUse];
|
|
55
|
+
}
|
|
56
|
+
return v;
|
|
57
|
+
};
|
|
58
|
+
|
|
37
59
|
const handleResult = (resolvedValue: any) => {
|
|
38
60
|
if (resolvedValue !== undefined) {
|
|
39
61
|
const win = (this as any).ownerDocument?.defaultView || window;
|
|
@@ -105,9 +127,9 @@ function createStyleDecorator(action: StyleAction) {
|
|
|
105
127
|
};
|
|
106
128
|
|
|
107
129
|
if (res instanceof Promise) {
|
|
108
|
-
return res.then(handleResult);
|
|
130
|
+
return res.then((v: any) => handleResult(extractValue(v)));
|
|
109
131
|
} else {
|
|
110
|
-
return handleResult(res);
|
|
132
|
+
return handleResult(extractValue(res));
|
|
111
133
|
}
|
|
112
134
|
};
|
|
113
135
|
return descriptor;
|
|
@@ -8,6 +8,22 @@ export interface EmitCustomEventBaseOptions {
|
|
|
8
8
|
composed?: boolean;
|
|
9
9
|
cancelable?: boolean;
|
|
10
10
|
filter?: (target: EventTarget, detail: any, meta: { currentThis: any, helper: HelperHostSet }) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Custom key to extract value from return object.
|
|
13
|
+
* If not provided, uses EMIT_CUSTOM_EVENT_METADATA_KEY by default.
|
|
14
|
+
* Useful when multiple @emitCustomEvent decorators are on the same method.
|
|
15
|
+
*
|
|
16
|
+
* Example:
|
|
17
|
+
* @emitCustomEvent('$appHost', 'event1', { valueKey: 'detail1' })
|
|
18
|
+
* @emitCustomEvent('$appHost', 'event2', { valueKey: 'detail2' })
|
|
19
|
+
* myMethod() {
|
|
20
|
+
* return {
|
|
21
|
+
* detail1: { type: 'event1', data: 'value1' },
|
|
22
|
+
* detail2: { type: 'event2', data: 'value2' }
|
|
23
|
+
* };
|
|
24
|
+
* }
|
|
25
|
+
*/
|
|
26
|
+
valueKey?: symbol | string;
|
|
11
27
|
}
|
|
12
28
|
|
|
13
29
|
type Options = (EmitCustomEventBaseOptions & SwcQueryOptions) | (EmitCustomEventBaseOptions & SwcQueryOptions & { attributeName?: string });
|
|
@@ -122,6 +138,9 @@ export const getEmitCustomEventMetadataList = (target: any): EmitCustomEventMeta
|
|
|
122
138
|
return ReflectUtils.getMetadata(EMIT_CUSTOM_EVENT_METADATA_KEY, constructor);
|
|
123
139
|
};
|
|
124
140
|
|
|
141
|
+
// --- Aliases: emit... ---
|
|
142
|
+
export const emit = emitCustomEvent;
|
|
143
|
+
|
|
125
144
|
/**
|
|
126
145
|
* @emitCustomEventThis decorator - simplified version of @emitCustomEvent for $this selector
|
|
127
146
|
*/
|
|
@@ -10,9 +10,25 @@ export interface PublishSwcAppMessageMetadata {
|
|
|
10
10
|
|
|
11
11
|
export interface PublishSwcAppMessageOptions {
|
|
12
12
|
messageType?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom key to extract value from return object.
|
|
15
|
+
* If not provided, uses PUBLISH_SWC_APP_MESSAGE_METADATA_KEY by default.
|
|
16
|
+
* Useful when multiple @publishSwcAppMessage decorators are on the same method.
|
|
17
|
+
*
|
|
18
|
+
* Example:
|
|
19
|
+
* @publishSwcAppMessage('event1', { valueKey: 'detail1' })
|
|
20
|
+
* @publishSwcAppMessage('event2', { valueKey: 'detail2' })
|
|
21
|
+
* myMethod() {
|
|
22
|
+
* return {
|
|
23
|
+
* detail1: { type: 'event1', data: 'value1' },
|
|
24
|
+
* detail2: { type: 'event2', data: 'value2' }
|
|
25
|
+
* };
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
valueKey?: symbol | string;
|
|
13
29
|
}
|
|
14
30
|
|
|
15
|
-
function createPublishSwcAppMessage(messageType?: string): MethodDecorator {
|
|
31
|
+
function createPublishSwcAppMessage(messageType?: string, options?: PublishSwcAppMessageOptions): MethodDecorator {
|
|
16
32
|
return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
|
|
17
33
|
const constructor = target.constructor;
|
|
18
34
|
let list = ReflectUtils.getOwnMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, constructor) as PublishSwcAppMessageMetadata[];
|
|
@@ -31,32 +47,47 @@ function createPublishSwcAppMessage(messageType?: string): MethodDecorator {
|
|
|
31
47
|
descriptor.value = function (...args: any[]) {
|
|
32
48
|
// 원본 메서드 실행
|
|
33
49
|
const result = originalMethod.apply(this, args);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Extract value for this decorator from method return value
|
|
53
|
+
*
|
|
54
|
+
* If return value is an object with this decorator's key,
|
|
55
|
+
* use that value. Otherwise use the entire return value.
|
|
56
|
+
*
|
|
57
|
+
* Uses valueKey from options if provided, otherwise uses PUBLISH_SWC_APP_MESSAGE_METADATA_KEY.
|
|
58
|
+
*/
|
|
59
|
+
const extractValue = (v: any) => {
|
|
60
|
+
const keyToUse = options?.valueKey ?? PUBLISH_SWC_APP_MESSAGE_METADATA_KEY;
|
|
61
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
62
|
+
return v[keyToUse];
|
|
63
|
+
}
|
|
64
|
+
return v;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const publishMessage = (data: any) => {
|
|
68
|
+
// appHost 찾아서 메시지 발행
|
|
69
|
+
const appHost = SwcUtils.getAppHost(this as HTMLElement);
|
|
70
|
+
if (appHost) {
|
|
71
|
+
appHost.publishMessage({
|
|
72
|
+
publisher: this,
|
|
73
|
+
data,
|
|
74
|
+
type: messageType
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
};
|
|
34
78
|
|
|
35
79
|
// Promise 체크
|
|
36
80
|
if (result instanceof Promise) {
|
|
37
81
|
result.then((data) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (appHost) {
|
|
41
|
-
appHost.publishMessage({
|
|
42
|
-
publisher: this,
|
|
43
|
-
data,
|
|
44
|
-
type: messageType
|
|
45
|
-
});
|
|
46
|
-
}
|
|
82
|
+
const extracted = extractValue(data);
|
|
83
|
+
publishMessage(extracted);
|
|
47
84
|
}).catch((err) => {
|
|
48
85
|
console.warn('publishSwcAppMessage async error:', err);
|
|
49
86
|
});
|
|
50
87
|
} else {
|
|
51
88
|
// 동기 호출 - 바로 메시지 발행
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
appHost.publishMessage({
|
|
55
|
-
publisher: this,
|
|
56
|
-
data: result,
|
|
57
|
-
type: messageType
|
|
58
|
-
});
|
|
59
|
-
}
|
|
89
|
+
const extracted = extractValue(result);
|
|
90
|
+
publishMessage(extracted);
|
|
60
91
|
}
|
|
61
92
|
|
|
62
93
|
return result;
|
|
@@ -71,27 +102,40 @@ export function publishSwcAppMessage(target: Object, propertyKey: string | symbo
|
|
|
71
102
|
// 오버로드 시그니처 - 함수 호출 (괄호 있음)
|
|
72
103
|
export function publishSwcAppMessage(): MethodDecorator;
|
|
73
104
|
export function publishSwcAppMessage(messageType: string): MethodDecorator;
|
|
105
|
+
export function publishSwcAppMessage(messageType: string, options: PublishSwcAppMessageOptions): MethodDecorator;
|
|
106
|
+
export function publishSwcAppMessage(options: PublishSwcAppMessageOptions): MethodDecorator;
|
|
74
107
|
|
|
75
|
-
export function publishSwcAppMessage(
|
|
108
|
+
export function publishSwcAppMessage(targetOrMessageTypeOrOptions?: any, propertyKeyOrOptions?: string | symbol | PublishSwcAppMessageOptions, descriptor?: PropertyDescriptor): any {
|
|
76
109
|
// 직접 데코레이터로 사용된 경우 (괄호 없음): @publishSwcAppMessage
|
|
77
|
-
if (
|
|
78
|
-
|
|
110
|
+
if (targetOrMessageTypeOrOptions && typeof targetOrMessageTypeOrOptions === 'object' &&
|
|
111
|
+
propertyKeyOrOptions && (typeof propertyKeyOrOptions === 'string' || typeof propertyKeyOrOptions === 'symbol') &&
|
|
79
112
|
descriptor) {
|
|
80
|
-
const target =
|
|
81
|
-
return createPublishSwcAppMessage()(target,
|
|
113
|
+
const target = targetOrMessageTypeOrOptions;
|
|
114
|
+
return createPublishSwcAppMessage()(target, propertyKeyOrOptions, descriptor);
|
|
82
115
|
}
|
|
83
116
|
|
|
84
|
-
// 함수로 호출된 경우 (괄호 있음): @publishSwcAppMessage() / @publishSwcAppMessage('messageType')
|
|
117
|
+
// 함수로 호출된 경우 (괄호 있음): @publishSwcAppMessage() / @publishSwcAppMessage('messageType') / @publishSwcAppMessage({...})
|
|
85
118
|
let messageType: string | undefined;
|
|
119
|
+
let options: PublishSwcAppMessageOptions | undefined;
|
|
86
120
|
|
|
87
|
-
if (typeof
|
|
121
|
+
if (typeof targetOrMessageTypeOrOptions === 'string') {
|
|
88
122
|
// 메시지 타입 전달: @publishSwcAppMessage('messageType')
|
|
89
|
-
messageType =
|
|
123
|
+
messageType = targetOrMessageTypeOrOptions;
|
|
124
|
+
if (typeof propertyKeyOrOptions === 'object' && propertyKeyOrOptions !== null) {
|
|
125
|
+
options = propertyKeyOrOptions as PublishSwcAppMessageOptions;
|
|
126
|
+
}
|
|
127
|
+
} else if (typeof targetOrMessageTypeOrOptions === 'object' && targetOrMessageTypeOrOptions !== null) {
|
|
128
|
+
// 옵션 객체 전달: @publishSwcAppMessage({...})
|
|
129
|
+
options = targetOrMessageTypeOrOptions as PublishSwcAppMessageOptions;
|
|
130
|
+
messageType = options.messageType;
|
|
90
131
|
}
|
|
91
132
|
|
|
92
|
-
return createPublishSwcAppMessage(messageType);
|
|
133
|
+
return createPublishSwcAppMessage(messageType, options);
|
|
93
134
|
}
|
|
94
135
|
|
|
136
|
+
// --- Aliases: publish... ---
|
|
137
|
+
export const publish = publishSwcAppMessage;
|
|
138
|
+
|
|
95
139
|
// Helper function to retrieve publish message metadata
|
|
96
140
|
export const getPublishSwcAppMessageMetadata = (target: any): PublishSwcAppMessageMetadata[] | undefined => {
|
|
97
141
|
const constructor = target instanceof Function ? target : target.constructor;
|