@llui/compiler 0.3.1 → 0.3.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/dist/collect-deps.d.ts +12 -0
- package/dist/collect-deps.d.ts.map +1 -1
- package/dist/collect-deps.js +6 -1
- package/dist/collect-deps.js.map +1 -1
- package/dist/cross-file-walker.d.ts +10 -0
- package/dist/cross-file-walker.d.ts.map +1 -1
- package/dist/cross-file-walker.js +81 -24
- package/dist/cross-file-walker.js.map +1 -1
- package/dist/transform.d.ts.map +1 -1
- package/dist/transform.js +65 -42
- package/dist/transform.js.map +1 -1
- package/package.json +1 -1
package/dist/transform.js
CHANGED
|
@@ -976,12 +976,19 @@ const VIEW_BAG_FIELD_TO_PRIMITIVE = {
|
|
|
976
976
|
* Idempotent — returns `call` unchanged when:
|
|
977
977
|
* • the config arg is not an object literal
|
|
978
978
|
* • no `view:` property exists, or its value is not an arrow/function
|
|
979
|
-
* • the view's first parameter is not an ObjectBindingPattern
|
|
980
979
|
* • the config arg already has a `__view` property (re-run safety)
|
|
981
980
|
*
|
|
982
981
|
* Bag fields that aren't in `VIEW_BAG_FIELD_TO_PRIMITIVE` (e.g. unknown
|
|
983
|
-
* names from a user-typed View extension) are skipped
|
|
984
|
-
*
|
|
982
|
+
* names from a user-typed View extension) are skipped — the runtime
|
|
983
|
+
* cannot fabricate them, so accessing them at runtime is the user's
|
|
984
|
+
* problem (matches dev-mode behavior).
|
|
985
|
+
*
|
|
986
|
+
* Identifier-style view params (`view: (h) => ...` or `view: (send) => ...`)
|
|
987
|
+
* can't be statically narrowed to a known subset of primitives — `h` may
|
|
988
|
+
* be passed to helpers, destructured later, or read dynamically. For
|
|
989
|
+
* those we emit `__view: ($send) => createView($send)` so the runtime
|
|
990
|
+
* gets the full bag. The instance-level `_viewBag` cache on
|
|
991
|
+
* `getInstanceViewBag` means this is still one allocation per mount.
|
|
985
992
|
*/
|
|
986
993
|
function injectViewBag(call, needed, f) {
|
|
987
994
|
const configArg = call.arguments[0];
|
|
@@ -1008,51 +1015,67 @@ function injectViewBag(call, needed, f) {
|
|
|
1008
1015
|
}
|
|
1009
1016
|
if (!viewFn)
|
|
1010
1017
|
return call;
|
|
1011
|
-
// Inspect the first parameter — must be an ObjectBindingPattern.
|
|
1012
|
-
const firstParam = viewFn.parameters[0];
|
|
1013
|
-
if (!firstParam || !ts.isObjectBindingPattern(firstParam.name))
|
|
1014
|
-
return call;
|
|
1015
|
-
const entries = [];
|
|
1016
|
-
for (const elem of firstParam.name.elements) {
|
|
1017
|
-
const localName = ts.isIdentifier(elem.name) ? elem.name.text : null;
|
|
1018
|
-
const sourceName = elem.propertyName && ts.isIdentifier(elem.propertyName) ? elem.propertyName.text : localName;
|
|
1019
|
-
if (!localName || !sourceName)
|
|
1020
|
-
continue;
|
|
1021
|
-
if (sourceName === 'send') {
|
|
1022
|
-
entries.push({ localName, primitive: null });
|
|
1023
|
-
continue;
|
|
1024
|
-
}
|
|
1025
|
-
const primitive = VIEW_BAG_FIELD_TO_PRIMITIVE[sourceName];
|
|
1026
|
-
if (!primitive)
|
|
1027
|
-
continue; // unknown name — let the runtime fail at runtime if accessed
|
|
1028
|
-
entries.push({ localName, primitive });
|
|
1029
|
-
}
|
|
1030
|
-
if (entries.length === 0)
|
|
1031
|
-
return call;
|
|
1032
|
-
// Synthesize: __view: ($send) => ({ localA: $send, localB: text, localC: each, ... })
|
|
1033
|
-
// We use a fixed parameter name `$send` to avoid shadowing — the bag
|
|
1034
|
-
// entries that map to send use this identifier.
|
|
1035
1018
|
const sendParamName = f.createIdentifier('$send');
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1019
|
+
// Build the __view factory body. Two shapes:
|
|
1020
|
+
//
|
|
1021
|
+
// Destructured param — `view: ({ send, text, each }) => ...`
|
|
1022
|
+
// emit `__view: ($send) => ({ send: $send, text, each })`
|
|
1023
|
+
// (tree-shakes unused primitives — the Tier 1.2 size cut).
|
|
1024
|
+
//
|
|
1025
|
+
// Identifier / no param — `view: (h) => ...`, `view: () => ...`,
|
|
1026
|
+
// `view: (send) => ...`, etc.
|
|
1027
|
+
// emit `__view: ($send) => createView($send)`
|
|
1028
|
+
// The compiler can't see which fields `h` is accessed on (it
|
|
1029
|
+
// may be passed to a helper, destructured later, read by
|
|
1030
|
+
// name dynamically). Full bag, instance-cached.
|
|
1031
|
+
const firstParam = viewFn.parameters[0];
|
|
1032
|
+
const isDestructured = !!firstParam && ts.isObjectBindingPattern(firstParam.name);
|
|
1033
|
+
let factoryBody;
|
|
1034
|
+
if (isDestructured) {
|
|
1035
|
+
const entries = [];
|
|
1036
|
+
for (const elem of firstParam.name.elements) {
|
|
1037
|
+
const localName = ts.isIdentifier(elem.name) ? elem.name.text : null;
|
|
1038
|
+
const sourceName = elem.propertyName && ts.isIdentifier(elem.propertyName) ? elem.propertyName.text : localName;
|
|
1039
|
+
if (!localName || !sourceName)
|
|
1040
|
+
continue;
|
|
1041
|
+
if (sourceName === 'send') {
|
|
1042
|
+
entries.push({ localName, primitive: null });
|
|
1043
|
+
continue;
|
|
1044
|
+
}
|
|
1045
|
+
const primitive = VIEW_BAG_FIELD_TO_PRIMITIVE[sourceName];
|
|
1046
|
+
if (!primitive)
|
|
1047
|
+
continue; // unknown name — accessing it at runtime is the user's problem
|
|
1048
|
+
entries.push({ localName, primitive });
|
|
1047
1049
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1050
|
+
const bagProps = [];
|
|
1051
|
+
for (const e of entries) {
|
|
1052
|
+
if (e.primitive === null) {
|
|
1053
|
+
bagProps.push(e.localName === '$send'
|
|
1054
|
+
? f.createShorthandPropertyAssignment(sendParamName)
|
|
1055
|
+
: f.createPropertyAssignment(f.createIdentifier(e.localName), sendParamName));
|
|
1056
|
+
}
|
|
1057
|
+
else if (e.localName === e.primitive) {
|
|
1058
|
+
bagProps.push(f.createShorthandPropertyAssignment(f.createIdentifier(e.localName)));
|
|
1059
|
+
needed.add(e.primitive);
|
|
1060
|
+
}
|
|
1061
|
+
else {
|
|
1062
|
+
bagProps.push(f.createPropertyAssignment(f.createIdentifier(e.localName), f.createIdentifier(e.primitive)));
|
|
1063
|
+
needed.add(e.primitive);
|
|
1064
|
+
}
|
|
1051
1065
|
}
|
|
1066
|
+
factoryBody = f.createParenthesizedExpression(f.createObjectLiteralExpression(bagProps, false));
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
// Identifier-style or zero-arg view: emit `createView($send)` and
|
|
1070
|
+
// pull `createView` into the file imports via cleanupImports.
|
|
1071
|
+
needed.add('createView');
|
|
1072
|
+
factoryBody = f.createCallExpression(f.createIdentifier('createView'), undefined, [
|
|
1073
|
+
sendParamName,
|
|
1074
|
+
]);
|
|
1052
1075
|
}
|
|
1053
1076
|
const viewBagFactory = f.createArrowFunction(undefined, undefined, [
|
|
1054
1077
|
f.createParameterDeclaration(undefined, undefined, sendParamName, undefined, undefined, undefined),
|
|
1055
|
-
], undefined, f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
1078
|
+
], undefined, f.createToken(ts.SyntaxKind.EqualsGreaterThanToken), factoryBody);
|
|
1056
1079
|
const newConfig = f.createObjectLiteralExpression([...configArg.properties, f.createPropertyAssignment('__view', viewBagFactory)], true);
|
|
1057
1080
|
return f.createCallExpression(call.expression, call.typeArguments, [
|
|
1058
1081
|
newConfig,
|