@wsxjs/wsx-core 0.0.13 → 0.0.14
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/dist/index.js +90 -10
- package/dist/index.mjs +90 -10
- package/package.json +1 -1
- package/src/reactive-decorator.ts +109 -214
package/dist/index.js
CHANGED
|
@@ -1208,14 +1208,45 @@ function deriveTagName(className, prefix) {
|
|
|
1208
1208
|
// src/reactive-decorator.ts
|
|
1209
1209
|
function state(targetOrContext, propertyKey) {
|
|
1210
1210
|
let propertyName;
|
|
1211
|
-
|
|
1211
|
+
const propertyKeyIsObject = typeof propertyKey === "object" && propertyKey !== null;
|
|
1212
|
+
const targetIsObject = typeof targetOrContext === "object" && targetOrContext !== null;
|
|
1213
|
+
const hasStage3Indicators = targetIsObject && ("kind" in targetOrContext || "addInitializer" in targetOrContext || "access" in targetOrContext);
|
|
1214
|
+
const hasName = hasStage3Indicators && "name" in targetOrContext;
|
|
1215
|
+
const isStage3Decorator = propertyKeyIsObject || hasName || hasStage3Indicators && (propertyKey === void 0 || propertyKey === null) || targetIsObject && "addInitializer" in targetOrContext;
|
|
1216
|
+
if (isStage3Decorator) {
|
|
1212
1217
|
const context = targetOrContext;
|
|
1213
|
-
|
|
1218
|
+
if (context.name) {
|
|
1219
|
+
propertyName = typeof context.name === "string" ? context.name : context.name.toString();
|
|
1220
|
+
} else if (propertyKeyIsObject) {
|
|
1221
|
+
if ("name" in propertyKey) {
|
|
1222
|
+
const keyObj = propertyKey;
|
|
1223
|
+
propertyName = keyObj.name ? typeof keyObj.name === "string" ? keyObj.name : keyObj.name.toString() : "unknown";
|
|
1224
|
+
} else if ("key" in propertyKey) {
|
|
1225
|
+
const keyObj = propertyKey;
|
|
1226
|
+
propertyName = keyObj.key ? typeof keyObj.key === "string" ? keyObj.key : keyObj.key.toString() : "unknown";
|
|
1227
|
+
} else {
|
|
1228
|
+
const keyStr = String(propertyKey);
|
|
1229
|
+
if (keyStr !== "[object Object]") {
|
|
1230
|
+
propertyName = keyStr;
|
|
1231
|
+
} else {
|
|
1232
|
+
propertyName = "unknown";
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
} else {
|
|
1236
|
+
propertyName = "unknown";
|
|
1237
|
+
}
|
|
1214
1238
|
} else {
|
|
1215
1239
|
if (typeof propertyKey === "string" || typeof propertyKey === "symbol") {
|
|
1216
1240
|
propertyName = typeof propertyKey === "string" ? propertyKey : propertyKey.toString();
|
|
1241
|
+
} else if (propertyKey != null) {
|
|
1242
|
+
const propertyKeyStr = String(propertyKey);
|
|
1243
|
+
if (propertyKeyStr === "[object Object]") {
|
|
1244
|
+
propertyName = "unknown";
|
|
1245
|
+
} else {
|
|
1246
|
+
propertyName = propertyKeyStr;
|
|
1247
|
+
}
|
|
1217
1248
|
} else {
|
|
1218
|
-
propertyName =
|
|
1249
|
+
propertyName = "unknown";
|
|
1219
1250
|
}
|
|
1220
1251
|
}
|
|
1221
1252
|
console.warn(
|
|
@@ -1233,15 +1264,34 @@ To fix this and enable compile-time processing, please:
|
|
|
1233
1264
|
|
|
1234
1265
|
See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
1235
1266
|
);
|
|
1236
|
-
if (
|
|
1237
|
-
|
|
1238
|
-
if (
|
|
1267
|
+
if (isStage3Decorator) {
|
|
1268
|
+
let context;
|
|
1269
|
+
if (hasStage3Indicators) {
|
|
1270
|
+
context = targetOrContext;
|
|
1271
|
+
} else if (propertyKeyIsObject) {
|
|
1272
|
+
const keyObj = propertyKey;
|
|
1273
|
+
const targetObj = targetOrContext;
|
|
1274
|
+
const nameValue = targetObj.name || keyObj.name || keyObj.key || "unknown";
|
|
1275
|
+
context = {
|
|
1276
|
+
kind: targetObj.kind || "field",
|
|
1277
|
+
name: nameValue,
|
|
1278
|
+
addInitializer: targetObj.addInitializer || keyObj.addInitializer,
|
|
1279
|
+
access: targetObj.access || keyObj.access
|
|
1280
|
+
};
|
|
1281
|
+
} else {
|
|
1282
|
+
context = targetOrContext;
|
|
1283
|
+
}
|
|
1284
|
+
if (context.kind && context.kind !== "field") {
|
|
1239
1285
|
const nameStr = typeof context.name === "string" ? context.name : context.name.toString();
|
|
1240
1286
|
throw new Error(
|
|
1241
1287
|
`@state decorator can only be used on class fields, not ${context.kind}. Property: "${nameStr}"`
|
|
1242
1288
|
);
|
|
1243
1289
|
}
|
|
1244
|
-
if (context.addInitializer) {
|
|
1290
|
+
if (!context.addInitializer) {
|
|
1291
|
+
console.warn(
|
|
1292
|
+
`[WSX] @state decorator: addInitializer not available for property "${propertyName}". The property will not be reactive. This usually means the decorator system is not properly configured.`
|
|
1293
|
+
);
|
|
1294
|
+
} else {
|
|
1245
1295
|
context.addInitializer(function() {
|
|
1246
1296
|
if (!this || typeof this.reactive !== "function" || typeof this.useState !== "function") {
|
|
1247
1297
|
throw new Error(
|
|
@@ -1294,13 +1344,39 @@ The @state decorator can only be used in classes that extend WebComponent or Lig
|
|
|
1294
1344
|
let normalizedPropertyKey;
|
|
1295
1345
|
if (typeof propertyKey === "string" || typeof propertyKey === "symbol") {
|
|
1296
1346
|
normalizedPropertyKey = propertyKey;
|
|
1297
|
-
} else {
|
|
1347
|
+
} else if (propertyKey != null) {
|
|
1298
1348
|
const propertyKeyStr = String(propertyKey);
|
|
1299
1349
|
if (propertyKeyStr === "[object Object]") {
|
|
1350
|
+
if (typeof targetOrContext === "object" && targetOrContext !== null && ("kind" in targetOrContext || "addInitializer" in targetOrContext)) {
|
|
1351
|
+
console.warn(
|
|
1352
|
+
`[WSX] @state decorator: Detected potential Stage 3 decorator format but with unexpected propertyKey. This might be a compatibility issue. The decorator will attempt to work in runtime fallback mode.`
|
|
1353
|
+
);
|
|
1354
|
+
const context = targetOrContext;
|
|
1355
|
+
if (context.name) {
|
|
1356
|
+
const name = typeof context.name === "string" ? context.name : context.name.toString();
|
|
1357
|
+
throw new Error(
|
|
1358
|
+
`@state decorator: Detected Stage 3 decorator format but with invalid propertyKey. Property name: "${name}".
|
|
1359
|
+
|
|
1360
|
+
This usually means the decorator is being called in an unexpected format. Please ensure you have configured the Babel plugin correctly.
|
|
1361
|
+
|
|
1362
|
+
To fix this, please:
|
|
1363
|
+
1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin
|
|
1364
|
+
2. Configure it in vite.config.ts:
|
|
1365
|
+
import { wsx } from '@wsxjs/wsx-vite-plugin';
|
|
1366
|
+
export default defineConfig({ plugins: [wsx()] });
|
|
1367
|
+
3. Configure TypeScript (recommended: use @wsxjs/wsx-tsconfig):
|
|
1368
|
+
npm install --save-dev @wsxjs/wsx-tsconfig
|
|
1369
|
+
Then in tsconfig.json: { "extends": "@wsxjs/wsx-tsconfig/tsconfig.base.json" }
|
|
1370
|
+
Or manually: { "compilerOptions": { "experimentalDecorators": true, "useDefineForClassFields": false } }
|
|
1371
|
+
|
|
1372
|
+
See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1300
1376
|
throw new Error(
|
|
1301
|
-
`@state decorator: Invalid propertyKey detected.
|
|
1377
|
+
`@state decorator: Invalid propertyKey detected (received object instead of string/symbol).
|
|
1302
1378
|
|
|
1303
|
-
The @state decorator MUST be processed by Babel plugin at compile time. It appears the Babel plugin is not configured in your build setup.
|
|
1379
|
+
The @state decorator MUST be processed by Babel plugin at compile time. It appears the Babel plugin is not configured in your build setup.
|
|
1304
1380
|
|
|
1305
1381
|
To fix this, please:
|
|
1306
1382
|
1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin
|
|
@@ -1316,6 +1392,10 @@ See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
|
1316
1392
|
);
|
|
1317
1393
|
}
|
|
1318
1394
|
normalizedPropertyKey = propertyKeyStr;
|
|
1395
|
+
} else {
|
|
1396
|
+
throw new Error(
|
|
1397
|
+
`@state decorator: propertyKey is missing. This usually means the decorator is not being called correctly. Please ensure you're using @state on a class field, not a method or other construct.`
|
|
1398
|
+
);
|
|
1319
1399
|
}
|
|
1320
1400
|
if (target == null) {
|
|
1321
1401
|
const propertyKeyStr = typeof normalizedPropertyKey === "string" ? normalizedPropertyKey : normalizedPropertyKey.toString();
|
package/dist/index.mjs
CHANGED
|
@@ -975,14 +975,45 @@ function deriveTagName(className, prefix) {
|
|
|
975
975
|
// src/reactive-decorator.ts
|
|
976
976
|
function state(targetOrContext, propertyKey) {
|
|
977
977
|
let propertyName;
|
|
978
|
-
|
|
978
|
+
const propertyKeyIsObject = typeof propertyKey === "object" && propertyKey !== null;
|
|
979
|
+
const targetIsObject = typeof targetOrContext === "object" && targetOrContext !== null;
|
|
980
|
+
const hasStage3Indicators = targetIsObject && ("kind" in targetOrContext || "addInitializer" in targetOrContext || "access" in targetOrContext);
|
|
981
|
+
const hasName = hasStage3Indicators && "name" in targetOrContext;
|
|
982
|
+
const isStage3Decorator = propertyKeyIsObject || hasName || hasStage3Indicators && (propertyKey === void 0 || propertyKey === null) || targetIsObject && "addInitializer" in targetOrContext;
|
|
983
|
+
if (isStage3Decorator) {
|
|
979
984
|
const context = targetOrContext;
|
|
980
|
-
|
|
985
|
+
if (context.name) {
|
|
986
|
+
propertyName = typeof context.name === "string" ? context.name : context.name.toString();
|
|
987
|
+
} else if (propertyKeyIsObject) {
|
|
988
|
+
if ("name" in propertyKey) {
|
|
989
|
+
const keyObj = propertyKey;
|
|
990
|
+
propertyName = keyObj.name ? typeof keyObj.name === "string" ? keyObj.name : keyObj.name.toString() : "unknown";
|
|
991
|
+
} else if ("key" in propertyKey) {
|
|
992
|
+
const keyObj = propertyKey;
|
|
993
|
+
propertyName = keyObj.key ? typeof keyObj.key === "string" ? keyObj.key : keyObj.key.toString() : "unknown";
|
|
994
|
+
} else {
|
|
995
|
+
const keyStr = String(propertyKey);
|
|
996
|
+
if (keyStr !== "[object Object]") {
|
|
997
|
+
propertyName = keyStr;
|
|
998
|
+
} else {
|
|
999
|
+
propertyName = "unknown";
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
} else {
|
|
1003
|
+
propertyName = "unknown";
|
|
1004
|
+
}
|
|
981
1005
|
} else {
|
|
982
1006
|
if (typeof propertyKey === "string" || typeof propertyKey === "symbol") {
|
|
983
1007
|
propertyName = typeof propertyKey === "string" ? propertyKey : propertyKey.toString();
|
|
1008
|
+
} else if (propertyKey != null) {
|
|
1009
|
+
const propertyKeyStr = String(propertyKey);
|
|
1010
|
+
if (propertyKeyStr === "[object Object]") {
|
|
1011
|
+
propertyName = "unknown";
|
|
1012
|
+
} else {
|
|
1013
|
+
propertyName = propertyKeyStr;
|
|
1014
|
+
}
|
|
984
1015
|
} else {
|
|
985
|
-
propertyName =
|
|
1016
|
+
propertyName = "unknown";
|
|
986
1017
|
}
|
|
987
1018
|
}
|
|
988
1019
|
console.warn(
|
|
@@ -1000,15 +1031,34 @@ To fix this and enable compile-time processing, please:
|
|
|
1000
1031
|
|
|
1001
1032
|
See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
1002
1033
|
);
|
|
1003
|
-
if (
|
|
1004
|
-
|
|
1005
|
-
if (
|
|
1034
|
+
if (isStage3Decorator) {
|
|
1035
|
+
let context;
|
|
1036
|
+
if (hasStage3Indicators) {
|
|
1037
|
+
context = targetOrContext;
|
|
1038
|
+
} else if (propertyKeyIsObject) {
|
|
1039
|
+
const keyObj = propertyKey;
|
|
1040
|
+
const targetObj = targetOrContext;
|
|
1041
|
+
const nameValue = targetObj.name || keyObj.name || keyObj.key || "unknown";
|
|
1042
|
+
context = {
|
|
1043
|
+
kind: targetObj.kind || "field",
|
|
1044
|
+
name: nameValue,
|
|
1045
|
+
addInitializer: targetObj.addInitializer || keyObj.addInitializer,
|
|
1046
|
+
access: targetObj.access || keyObj.access
|
|
1047
|
+
};
|
|
1048
|
+
} else {
|
|
1049
|
+
context = targetOrContext;
|
|
1050
|
+
}
|
|
1051
|
+
if (context.kind && context.kind !== "field") {
|
|
1006
1052
|
const nameStr = typeof context.name === "string" ? context.name : context.name.toString();
|
|
1007
1053
|
throw new Error(
|
|
1008
1054
|
`@state decorator can only be used on class fields, not ${context.kind}. Property: "${nameStr}"`
|
|
1009
1055
|
);
|
|
1010
1056
|
}
|
|
1011
|
-
if (context.addInitializer) {
|
|
1057
|
+
if (!context.addInitializer) {
|
|
1058
|
+
console.warn(
|
|
1059
|
+
`[WSX] @state decorator: addInitializer not available for property "${propertyName}". The property will not be reactive. This usually means the decorator system is not properly configured.`
|
|
1060
|
+
);
|
|
1061
|
+
} else {
|
|
1012
1062
|
context.addInitializer(function() {
|
|
1013
1063
|
if (!this || typeof this.reactive !== "function" || typeof this.useState !== "function") {
|
|
1014
1064
|
throw new Error(
|
|
@@ -1061,13 +1111,39 @@ The @state decorator can only be used in classes that extend WebComponent or Lig
|
|
|
1061
1111
|
let normalizedPropertyKey;
|
|
1062
1112
|
if (typeof propertyKey === "string" || typeof propertyKey === "symbol") {
|
|
1063
1113
|
normalizedPropertyKey = propertyKey;
|
|
1064
|
-
} else {
|
|
1114
|
+
} else if (propertyKey != null) {
|
|
1065
1115
|
const propertyKeyStr = String(propertyKey);
|
|
1066
1116
|
if (propertyKeyStr === "[object Object]") {
|
|
1117
|
+
if (typeof targetOrContext === "object" && targetOrContext !== null && ("kind" in targetOrContext || "addInitializer" in targetOrContext)) {
|
|
1118
|
+
console.warn(
|
|
1119
|
+
`[WSX] @state decorator: Detected potential Stage 3 decorator format but with unexpected propertyKey. This might be a compatibility issue. The decorator will attempt to work in runtime fallback mode.`
|
|
1120
|
+
);
|
|
1121
|
+
const context = targetOrContext;
|
|
1122
|
+
if (context.name) {
|
|
1123
|
+
const name = typeof context.name === "string" ? context.name : context.name.toString();
|
|
1124
|
+
throw new Error(
|
|
1125
|
+
`@state decorator: Detected Stage 3 decorator format but with invalid propertyKey. Property name: "${name}".
|
|
1126
|
+
|
|
1127
|
+
This usually means the decorator is being called in an unexpected format. Please ensure you have configured the Babel plugin correctly.
|
|
1128
|
+
|
|
1129
|
+
To fix this, please:
|
|
1130
|
+
1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin
|
|
1131
|
+
2. Configure it in vite.config.ts:
|
|
1132
|
+
import { wsx } from '@wsxjs/wsx-vite-plugin';
|
|
1133
|
+
export default defineConfig({ plugins: [wsx()] });
|
|
1134
|
+
3. Configure TypeScript (recommended: use @wsxjs/wsx-tsconfig):
|
|
1135
|
+
npm install --save-dev @wsxjs/wsx-tsconfig
|
|
1136
|
+
Then in tsconfig.json: { "extends": "@wsxjs/wsx-tsconfig/tsconfig.base.json" }
|
|
1137
|
+
Or manually: { "compilerOptions": { "experimentalDecorators": true, "useDefineForClassFields": false } }
|
|
1138
|
+
|
|
1139
|
+
See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
1140
|
+
);
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1067
1143
|
throw new Error(
|
|
1068
|
-
`@state decorator: Invalid propertyKey detected.
|
|
1144
|
+
`@state decorator: Invalid propertyKey detected (received object instead of string/symbol).
|
|
1069
1145
|
|
|
1070
|
-
The @state decorator MUST be processed by Babel plugin at compile time. It appears the Babel plugin is not configured in your build setup.
|
|
1146
|
+
The @state decorator MUST be processed by Babel plugin at compile time. It appears the Babel plugin is not configured in your build setup.
|
|
1071
1147
|
|
|
1072
1148
|
To fix this, please:
|
|
1073
1149
|
1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin
|
|
@@ -1083,6 +1159,10 @@ See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
|
1083
1159
|
);
|
|
1084
1160
|
}
|
|
1085
1161
|
normalizedPropertyKey = propertyKeyStr;
|
|
1162
|
+
} else {
|
|
1163
|
+
throw new Error(
|
|
1164
|
+
`@state decorator: propertyKey is missing. This usually means the decorator is not being called correctly. Please ensure you're using @state on a class field, not a method or other construct.`
|
|
1165
|
+
);
|
|
1086
1166
|
}
|
|
1087
1167
|
if (target == null) {
|
|
1088
1168
|
const propertyKeyStr = typeof normalizedPropertyKey === "string" ? normalizedPropertyKey : normalizedPropertyKey.toString();
|
package/package.json
CHANGED
|
@@ -48,241 +48,136 @@ interface DecoratorContext {
|
|
|
48
48
|
addInitializer?(initializer: () => void): void;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Helper function to create error message for missing Babel plugin
|
|
53
|
+
*/
|
|
54
|
+
function createBabelPluginError(propertyName: string): string {
|
|
55
|
+
return (
|
|
56
|
+
`@state decorator on property "${propertyName}" MUST be processed by Babel plugin at compile time. ` +
|
|
57
|
+
`It appears the Babel plugin is not configured in your build setup. ` +
|
|
58
|
+
`\n\n` +
|
|
59
|
+
`The @state decorator cannot work without the Babel plugin. ` +
|
|
60
|
+
`\n\n` +
|
|
61
|
+
`To fix this, please:` +
|
|
62
|
+
`\n1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin` +
|
|
63
|
+
`\n2. Configure it in vite.config.ts:` +
|
|
64
|
+
`\n import { wsx } from '@wsxjs/wsx-vite-plugin';` +
|
|
65
|
+
`\n export default defineConfig({ plugins: [wsx()] });` +
|
|
66
|
+
`\n3. Configure TypeScript (recommended: use @wsxjs/wsx-tsconfig):` +
|
|
67
|
+
`\n npm install --save-dev @wsxjs/wsx-tsconfig` +
|
|
68
|
+
`\n Then in tsconfig.json: { "extends": "@wsxjs/wsx-tsconfig/tsconfig.base.json" }` +
|
|
69
|
+
`\n Or manually: { "compilerOptions": { "experimentalDecorators": true, "useDefineForClassFields": false } }` +
|
|
70
|
+
`\n\n` +
|
|
71
|
+
`See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
51
75
|
export function state(
|
|
52
76
|
targetOrContext: unknown | DecoratorContext,
|
|
53
77
|
propertyKey?: string | symbol | unknown
|
|
54
|
-
|
|
78
|
+
// Compatibility with Babel plugin which is required for this decorator to work properly
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
|
+
): any {
|
|
55
81
|
/**
|
|
56
|
-
* @state decorator
|
|
57
|
-
* 1. Compile-time processing by Babel plugin (preferred) - decorator is removed at compile time
|
|
58
|
-
* 2. Runtime fallback when Babel plugin is not configured - decorator executes at runtime
|
|
59
|
-
*
|
|
82
|
+
* @state decorator MUST be processed by Babel plugin at compile time.
|
|
60
83
|
* If this function is executed at runtime, it means Babel plugin did not process it.
|
|
61
|
-
* We
|
|
84
|
+
* We MUST throw an error - no fallback is allowed.
|
|
62
85
|
*/
|
|
63
86
|
|
|
64
|
-
// Determine property name for
|
|
65
|
-
let propertyName: string;
|
|
66
|
-
if (
|
|
67
|
-
typeof targetOrContext === "object" &&
|
|
68
|
-
targetOrContext !== null &&
|
|
69
|
-
"kind" in targetOrContext &&
|
|
70
|
-
"name" in targetOrContext
|
|
71
|
-
) {
|
|
72
|
-
// Stage 3 decorator format
|
|
73
|
-
const context = targetOrContext as DecoratorContext;
|
|
74
|
-
propertyName = typeof context.name === "string" ? context.name : context.name.toString();
|
|
75
|
-
} else {
|
|
76
|
-
// Legacy decorator format
|
|
77
|
-
if (typeof propertyKey === "string" || typeof propertyKey === "symbol") {
|
|
78
|
-
propertyName = typeof propertyKey === "string" ? propertyKey : propertyKey.toString();
|
|
79
|
-
} else {
|
|
80
|
-
propertyName = String(propertyKey);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Show warning immediately when decorator is executed at runtime
|
|
85
|
-
// This means Babel plugin did not process it
|
|
86
|
-
console.warn(
|
|
87
|
-
`[WSX] @state decorator is using runtime fallback. ` +
|
|
88
|
-
`Property "${propertyName}" will work but with reduced performance. ` +
|
|
89
|
-
`\n\n` +
|
|
90
|
-
`To fix this and enable compile-time processing, please:` +
|
|
91
|
-
`\n1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin` +
|
|
92
|
-
`\n2. Configure it in vite.config.ts:` +
|
|
93
|
-
`\n import { wsx } from '@wsxjs/wsx-vite-plugin';` +
|
|
94
|
-
`\n export default defineConfig({ plugins: [wsx()] });` +
|
|
95
|
-
`\n3. Configure TypeScript (recommended: use @wsxjs/wsx-tsconfig):` +
|
|
96
|
-
`\n npm install --save-dev @wsxjs/wsx-tsconfig` +
|
|
97
|
-
`\n Then in tsconfig.json: { "extends": "@wsxjs/wsx-tsconfig/tsconfig.base.json" }` +
|
|
98
|
-
`\n Or manually: { "compilerOptions": { "experimentalDecorators": true, "useDefineForClassFields": false } }` +
|
|
99
|
-
`\n\n` +
|
|
100
|
-
`See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
101
|
-
);
|
|
87
|
+
// Determine property name for error message
|
|
88
|
+
let propertyName: string = "unknown";
|
|
102
89
|
|
|
103
90
|
// Check if this is a Stage 3 decorator (context object)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
context
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
91
|
+
const propertyKeyIsObject = typeof propertyKey === "object" && propertyKey !== null;
|
|
92
|
+
const targetIsObject = typeof targetOrContext === "object" && targetOrContext !== null;
|
|
93
|
+
|
|
94
|
+
const hasStage3Indicators =
|
|
95
|
+
targetIsObject &&
|
|
96
|
+
("kind" in targetOrContext ||
|
|
97
|
+
"addInitializer" in targetOrContext ||
|
|
98
|
+
"access" in targetOrContext);
|
|
99
|
+
|
|
100
|
+
const hasName = hasStage3Indicators && "name" in targetOrContext;
|
|
101
|
+
|
|
102
|
+
const isStage3Decorator =
|
|
103
|
+
propertyKeyIsObject ||
|
|
104
|
+
hasName ||
|
|
105
|
+
(hasStage3Indicators && (propertyKey === undefined || propertyKey === null)) ||
|
|
106
|
+
(targetIsObject && "addInitializer" in targetOrContext);
|
|
107
|
+
|
|
108
|
+
if (isStage3Decorator) {
|
|
109
|
+
// Stage 3 decorator format - determine property name safely
|
|
110
|
+
if (hasStage3Indicators && targetOrContext && typeof targetOrContext === "object") {
|
|
111
|
+
const context = targetOrContext as DecoratorContext;
|
|
112
|
+
if (context.name) {
|
|
113
|
+
propertyName =
|
|
114
|
+
typeof context.name === "string" ? context.name : context.name.toString();
|
|
115
|
+
}
|
|
116
|
+
} else if (propertyKeyIsObject) {
|
|
117
|
+
// If propertyKey is an object, try to extract name from it
|
|
118
|
+
const keyObj = propertyKey as Record<string, unknown>;
|
|
119
|
+
const targetObj = targetOrContext as Record<string, unknown> | null;
|
|
120
|
+
|
|
121
|
+
// Try to get name from multiple sources
|
|
122
|
+
const nameValue =
|
|
123
|
+
(targetObj?.name as string | symbol | undefined) ||
|
|
124
|
+
(keyObj.name as string | symbol | undefined) ||
|
|
125
|
+
(keyObj.key as string | symbol | undefined);
|
|
126
|
+
|
|
127
|
+
if (nameValue) {
|
|
128
|
+
propertyName = typeof nameValue === "string" ? nameValue : nameValue.toString();
|
|
129
|
+
} else {
|
|
130
|
+
const keyStr = String(propertyKey);
|
|
131
|
+
if (keyStr !== "[object Object]") {
|
|
132
|
+
propertyName = keyStr;
|
|
138
133
|
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
139
136
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
} else {
|
|
151
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
152
|
-
initialValue = (this as any)[propertyName];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Determine if it's an object/array
|
|
156
|
-
const isObject =
|
|
157
|
-
initialValue !== null &&
|
|
158
|
-
initialValue !== undefined &&
|
|
159
|
-
(typeof initialValue === "object" || Array.isArray(initialValue));
|
|
160
|
-
|
|
161
|
-
if (isObject) {
|
|
162
|
-
// For objects/arrays: use reactive()
|
|
163
|
-
let reactiveValue = this.reactive(initialValue);
|
|
164
|
-
Object.defineProperty(this, propertyName, {
|
|
165
|
-
get: () => reactiveValue,
|
|
166
|
-
set: (newValue: unknown) => {
|
|
167
|
-
// Auto-wrap new values in reactive if they're objects/arrays
|
|
168
|
-
if (
|
|
169
|
-
newValue !== null &&
|
|
170
|
-
newValue !== undefined &&
|
|
171
|
-
(typeof newValue === "object" || Array.isArray(newValue))
|
|
172
|
-
) {
|
|
173
|
-
// Create new reactive value
|
|
174
|
-
reactiveValue = this.reactive(newValue);
|
|
175
|
-
this.scheduleRerender();
|
|
176
|
-
} else {
|
|
177
|
-
// For primitives, just assign (but this shouldn't happen for object properties)
|
|
178
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
179
|
-
reactiveValue = newValue as any;
|
|
180
|
-
this.scheduleRerender();
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
enumerable: true,
|
|
184
|
-
configurable: true,
|
|
185
|
-
});
|
|
186
|
-
} else {
|
|
187
|
-
// For primitives: use useState
|
|
188
|
-
const [getState, setState] = this.useState(propertyName, initialValue);
|
|
189
|
-
Object.defineProperty(this, propertyName, {
|
|
190
|
-
get: getState,
|
|
191
|
-
set: setState,
|
|
192
|
-
enumerable: true,
|
|
193
|
-
configurable: true,
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
});
|
|
137
|
+
// Only support field decorators (if kind is specified)
|
|
138
|
+
if (targetIsObject && "kind" in targetOrContext) {
|
|
139
|
+
const context = targetOrContext as DecoratorContext;
|
|
140
|
+
if (context.kind && context.kind !== "field") {
|
|
141
|
+
const nameStr =
|
|
142
|
+
typeof context.name === "string" ? context.name : context.name.toString();
|
|
143
|
+
throw new Error(
|
|
144
|
+
`@state decorator can only be used on class fields, not ${context.kind}. Property: "${nameStr}"`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
197
147
|
}
|
|
198
148
|
|
|
199
|
-
//
|
|
200
|
-
|
|
149
|
+
// If we reach here, the decorator is being executed at runtime
|
|
150
|
+
// This means Babel plugin did not process it - throw error immediately
|
|
151
|
+
throw new Error(createBabelPluginError(propertyName));
|
|
201
152
|
}
|
|
202
153
|
|
|
203
154
|
// Legacy decorator format (experimentalDecorators: true)
|
|
204
155
|
// This should ideally be removed by Babel plugin
|
|
205
|
-
const target = targetOrContext;
|
|
206
|
-
let normalizedPropertyKey: string | symbol;
|
|
207
156
|
if (typeof propertyKey === "string" || typeof propertyKey === "symbol") {
|
|
208
|
-
|
|
209
|
-
} else {
|
|
157
|
+
propertyName = typeof propertyKey === "string" ? propertyKey : propertyKey.toString();
|
|
158
|
+
} else if (propertyKey != null) {
|
|
210
159
|
const propertyKeyStr = String(propertyKey);
|
|
211
160
|
if (propertyKeyStr === "[object Object]") {
|
|
212
|
-
// Invalid propertyKey -
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
`\n\n` +
|
|
229
|
-
`See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
230
|
-
);
|
|
161
|
+
// Invalid propertyKey - this might happen if decorator is called in unexpected format
|
|
162
|
+
// Check if targetOrContext might actually be a Stage 3 context that we missed
|
|
163
|
+
if (
|
|
164
|
+
typeof targetOrContext === "object" &&
|
|
165
|
+
targetOrContext !== null &&
|
|
166
|
+
("kind" in targetOrContext || "addInitializer" in targetOrContext)
|
|
167
|
+
) {
|
|
168
|
+
// This looks like it might be a Stage 3 decorator that we didn't detect properly
|
|
169
|
+
const context = targetOrContext as Partial<DecoratorContext>;
|
|
170
|
+
if (context.name) {
|
|
171
|
+
propertyName =
|
|
172
|
+
typeof context.name === "string" ? context.name : context.name.toString();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
propertyName = propertyKeyStr;
|
|
231
177
|
}
|
|
232
|
-
normalizedPropertyKey = propertyKeyStr;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Basic validation: ensure target is valid
|
|
236
|
-
if (target == null) {
|
|
237
|
-
const propertyKeyStr =
|
|
238
|
-
typeof normalizedPropertyKey === "string"
|
|
239
|
-
? normalizedPropertyKey
|
|
240
|
-
: normalizedPropertyKey.toString();
|
|
241
|
-
throw new Error(
|
|
242
|
-
`@state decorator: Cannot access property "${propertyKeyStr}". ` +
|
|
243
|
-
`Target is ${target === null ? "null" : "undefined"}.` +
|
|
244
|
-
`\n\n` +
|
|
245
|
-
`The @state decorator MUST be processed by Babel plugin at compile time. ` +
|
|
246
|
-
`It appears the Babel plugin is not configured in your build setup.` +
|
|
247
|
-
`\n\n` +
|
|
248
|
-
`To fix this, please:` +
|
|
249
|
-
`\n1. Install @wsxjs/wsx-vite-plugin: npm install @wsxjs/wsx-vite-plugin` +
|
|
250
|
-
`\n2. Configure it in vite.config.ts:` +
|
|
251
|
-
`\n import { wsx } from '@wsxjs/wsx-vite-plugin';` +
|
|
252
|
-
`\n export default defineConfig({ plugins: [wsx()] });` +
|
|
253
|
-
`\n3. Configure TypeScript (recommended: use @wsxjs/wsx-tsconfig):` +
|
|
254
|
-
`\n npm install --save-dev @wsxjs/wsx-tsconfig` +
|
|
255
|
-
`\n Then in tsconfig.json: { "extends": "@wsxjs/wsx-tsconfig/tsconfig.base.json" }` +
|
|
256
|
-
`\n Or manually: { "compilerOptions": { "experimentalDecorators": true, "useDefineForClassFields": false } }` +
|
|
257
|
-
`\n\n` +
|
|
258
|
-
`See: https://github.com/wsxjs/wsxjs#setup for more details.`
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (typeof target !== "object") {
|
|
263
|
-
const propertyKeyStr =
|
|
264
|
-
typeof normalizedPropertyKey === "string"
|
|
265
|
-
? normalizedPropertyKey
|
|
266
|
-
: normalizedPropertyKey.toString();
|
|
267
|
-
throw new Error(
|
|
268
|
-
`@state decorator: Cannot be used on "${propertyKeyStr}". ` +
|
|
269
|
-
`@state is for properties only, not methods.`
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Validate that property has an initial value
|
|
274
|
-
const descriptor = Object.getOwnPropertyDescriptor(target, normalizedPropertyKey);
|
|
275
|
-
if (descriptor?.get) {
|
|
276
|
-
const propertyKeyStr =
|
|
277
|
-
typeof normalizedPropertyKey === "string"
|
|
278
|
-
? normalizedPropertyKey
|
|
279
|
-
: normalizedPropertyKey.toString();
|
|
280
|
-
throw new Error(
|
|
281
|
-
`@state decorator cannot be used with getter properties. Property: "${propertyKeyStr}"`
|
|
282
|
-
);
|
|
283
178
|
}
|
|
284
179
|
|
|
285
|
-
//
|
|
286
|
-
// Babel plugin
|
|
287
|
-
|
|
180
|
+
// If we reach here, the decorator is being executed at runtime
|
|
181
|
+
// This means Babel plugin did not process it - throw error immediately
|
|
182
|
+
throw new Error(createBabelPluginError(propertyName));
|
|
288
183
|
}
|