@torpor/view 1.0.3 → 1.1.1
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/{fromWebSocket-DeB35Q4w.d.cts → AsyncOptions-BtMe2PAd.d.cts} +21 -2
- package/dist/AsyncOptions-BtMe2PAd.d.cts.map +1 -0
- package/dist/{fromWebSocket-B52kN3-W.d.mts → AsyncOptions-ClS1_ERX.d.mts} +21 -2
- package/dist/AsyncOptions-ClS1_ERX.d.mts.map +1 -0
- package/dist/{Effect-BTKurOpr.d.mts → Effect-DazmAdyC.d.mts} +3 -3
- package/dist/{Effect-BTKurOpr.d.mts.map → Effect-DazmAdyC.d.mts.map} +1 -1
- package/dist/{Effect-COl3aRJV.d.cts → Effect-Dewn7MLc.d.cts} +3 -3
- package/dist/{Effect-COl3aRJV.d.cts.map → Effect-Dewn7MLc.d.cts.map} +1 -1
- package/dist/compile.cjs +139 -33
- package/dist/compile.mjs +139 -33
- package/dist/compile.mjs.map +1 -1
- package/dist/dev.d.cts +1 -1
- package/dist/dev.d.mts +1 -1
- package/dist/index.cjs +60 -8
- package/dist/index.d.cts +23 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +23 -6
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +60 -8
- package/dist/index.mjs.map +1 -1
- package/dist/ssr.cjs +292 -4
- package/dist/ssr.d.cts +108 -9
- package/dist/ssr.d.cts.map +1 -1
- package/dist/ssr.d.mts +108 -9
- package/dist/ssr.d.mts.map +1 -1
- package/dist/ssr.mjs +291 -5
- package/dist/ssr.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/fromWebSocket-B52kN3-W.d.mts.map +0 -1
- package/dist/fromWebSocket-DeB35Q4w.d.cts.map +0 -1
package/dist/compile.mjs
CHANGED
|
@@ -2200,12 +2200,15 @@ function headElementSelector(node) {
|
|
|
2200
2200
|
function buildElementAttributes$1(node, varName, status, b) {
|
|
2201
2201
|
let fragment = status.fragmentStack.at(-1)?.fragment;
|
|
2202
2202
|
if (!fragment) throw new Error("No fragment on stack");
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2203
|
+
const combinedHandlers = combinedEventHandlers(node, status);
|
|
2204
|
+
const consumedHandlers = new Set(Array.from(combinedHandlers.values(), (c) => c.index));
|
|
2205
|
+
for (let [index, { name, value, reactive, fullyReactive, span }] of node.attributes.entries()) if (name === "self" && node.tagName === "@element") {} else if (name === "&ref") {} else if (value != null && fullyReactive) {
|
|
2206
|
+
if (name === "&group") buildBindGroupAttribute(node, varName, value, status, b, combinedHandlers.get(index));
|
|
2207
|
+
else if (name === "&value" || name === "&checked") buildBindAttribute(node, varName, name, value, status, b, combinedHandlers.get(index));
|
|
2206
2208
|
else if (name === "onmount") buildMount("elMount", `return (${trimEnd(value.trim(), ";")})(${varName});`, status, b);
|
|
2207
|
-
else if (name.startsWith("on"))
|
|
2208
|
-
|
|
2209
|
+
else if (name.startsWith("on")) {
|
|
2210
|
+
if (!consumedHandlers.has(index)) buildEventAttribute(varName, name, value, span, status, b);
|
|
2211
|
+
} else if (name.startsWith("transition")) buildTransitionAttribute(node, varName, name, value, status, b);
|
|
2209
2212
|
else if (name === "class") {
|
|
2210
2213
|
status.imports.add("t_class");
|
|
2211
2214
|
const params = [value];
|
|
@@ -2243,21 +2246,20 @@ function buildElementAttributes$1(node, varName, status, b) {
|
|
|
2243
2246
|
}
|
|
2244
2247
|
}
|
|
2245
2248
|
}
|
|
2246
|
-
function buildBindGroupAttribute(node, varName, value, status, b) {
|
|
2249
|
+
function buildBindGroupAttribute(node, varName, value, status, b, combined) {
|
|
2247
2250
|
value = replaceForVarNames(value, status);
|
|
2248
2251
|
let eventName = "change";
|
|
2249
2252
|
let inputValue = node.attributes.find((a) => a.name === "value")?.value;
|
|
2250
2253
|
let set = `${value} == ${inputValue}`;
|
|
2251
2254
|
let propName = "checked";
|
|
2252
2255
|
buildRun("setBinding", `${`${varName}.${propName} = ${set}`};`, status, b);
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
if (e.target.${propName}) ${value} = ${inputValue};
|
|
2256
|
-
});`);
|
|
2256
|
+
emitBindEvent(varName, eventName, `(e) => {
|
|
2257
|
+
if (e.target.${propName}) ${value} = ${inputValue};
|
|
2258
|
+
}`, `if (e.target.${propName}) ${value} = ${inputValue};`, combined, status, b);
|
|
2257
2259
|
}
|
|
2258
|
-
function buildBindAttribute(node, varName, name, value, status, b) {
|
|
2260
|
+
function buildBindAttribute(node, varName, name, value, status, b, combined) {
|
|
2259
2261
|
value = replaceForVarNames(value, status);
|
|
2260
|
-
let eventName =
|
|
2262
|
+
let eventName = bindEventName(node, name);
|
|
2261
2263
|
let defaultValue = "\"\"";
|
|
2262
2264
|
let inputValue = "e.target.value";
|
|
2263
2265
|
if (node.tagName === "input") {
|
|
@@ -2270,25 +2272,83 @@ function buildBindAttribute(node, varName, name, value, status, b) {
|
|
|
2270
2272
|
case "checkbox":
|
|
2271
2273
|
defaultValue = "false";
|
|
2272
2274
|
inputValue = "e.target.checked";
|
|
2273
|
-
break;
|
|
2274
|
-
case "radio":
|
|
2275
|
-
eventName = "change";
|
|
2276
|
-
inputValue = "e.target.value";
|
|
2277
2275
|
}
|
|
2278
2276
|
} else if (node.tagName === "select") {
|
|
2279
|
-
eventName = "change";
|
|
2280
2277
|
if (node.attributes.find((a) => a.name === "multiple")) {
|
|
2281
2278
|
buildRun("setBinding", `Array.from(${varName}.options).forEach((opt) => opt.selected = Array.isArray(${value}) && ${value}.includes(opt.value));`, status, b);
|
|
2282
|
-
|
|
2283
|
-
b.append(`t_event(${varName}, "change", (e) => ${value} = Array.from(e.target.selectedOptions).map((opt) => opt.value));`);
|
|
2279
|
+
emitBindEvent(varName, eventName, `(e) => ${value} = Array.from(e.target.selectedOptions).map((opt) => opt.value)`, `${value} = Array.from(e.target.selectedOptions).map((opt) => opt.value);`, combined, status, b);
|
|
2284
2280
|
return;
|
|
2285
2281
|
}
|
|
2286
2282
|
}
|
|
2287
2283
|
let set = `${value} || ${defaultValue}`;
|
|
2288
2284
|
const propName = name.substring(1);
|
|
2289
2285
|
buildRun("setBinding", `${propName === "value" ? `${varName}.${propName} = String(${set})` : `${varName}.${propName} = ${set}`};`, status, b);
|
|
2286
|
+
emitBindEvent(varName, eventName, `(e) => ${value} = ${inputValue}`, `${value} = ${inputValue};`, combined, status, b);
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Gets the name of the event that a &-binding attribute uses to write the
|
|
2290
|
+
* element's state back to the bound value
|
|
2291
|
+
*/
|
|
2292
|
+
function bindEventName(node, name) {
|
|
2293
|
+
if (name === "&group") return "change";
|
|
2294
|
+
if (node.tagName === "select") return "change";
|
|
2295
|
+
if (node.tagName === "input") {
|
|
2296
|
+
let typeAttribute = node.attributes.find((a) => a.name === "type");
|
|
2297
|
+
if (typeAttribute?.value && trimQuotes(typeAttribute.value) === "radio") return "change";
|
|
2298
|
+
}
|
|
2299
|
+
return "input";
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* Pairs &-binding attributes (&value, &checked, &group) with user `on<event>`
|
|
2303
|
+
* handler attributes listening to the same event. Both would emit their own
|
|
2304
|
+
* t_event call for the element, but the second registration would clobber
|
|
2305
|
+
* the first -- typically the binding's state write -- so the pair is emitted
|
|
2306
|
+
* as one t_event that calls the binding write and the user handler in source
|
|
2307
|
+
* order. Returns a map from binding attribute index to the combined handler.
|
|
2308
|
+
*/
|
|
2309
|
+
function combinedEventHandlers(node, status) {
|
|
2310
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
2311
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
2312
|
+
for (let [index, { name, value, fullyReactive }] of node.attributes.entries()) {
|
|
2313
|
+
if (value == null || !fullyReactive) continue;
|
|
2314
|
+
if (name === "&value" || name === "&checked" || name === "&group") bindings.set(bindEventName(node, name), index);
|
|
2315
|
+
else if (name.startsWith("on")) handlers.set(name.substring(2), index);
|
|
2316
|
+
}
|
|
2317
|
+
const combined = /* @__PURE__ */ new Map();
|
|
2318
|
+
for (let [eventName, bindingIndex] of bindings) {
|
|
2319
|
+
const handlerIndex = handlers.get(eventName);
|
|
2320
|
+
if (handlerIndex === void 0) continue;
|
|
2321
|
+
const handler = node.attributes[handlerIndex];
|
|
2322
|
+
combined.set(bindingIndex, {
|
|
2323
|
+
index: handlerIndex,
|
|
2324
|
+
value: replaceForVarNames(handler.value, status),
|
|
2325
|
+
span: handler.span,
|
|
2326
|
+
first: handlerIndex < bindingIndex
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
2329
|
+
return combined;
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Emits the t_event call for a &-binding, optionally combined with a user
|
|
2333
|
+
* `on<event>` handler for the same event (which is called after -- or, when
|
|
2334
|
+
* it appeared first in source, before -- the binding write)
|
|
2335
|
+
*/
|
|
2336
|
+
function emitBindEvent(varName, eventName, listener, body, combined, status, b) {
|
|
2290
2337
|
status.imports.add("t_event");
|
|
2291
|
-
|
|
2338
|
+
if (!combined) {
|
|
2339
|
+
b.append(`t_event(${varName}, "${eventName}", ${listener});`);
|
|
2340
|
+
return;
|
|
2341
|
+
}
|
|
2342
|
+
b.append(`t_event(${varName}, "${eventName}", (e) => {`);
|
|
2343
|
+
const handlerCall = `((${combined.value}) as ((e: any) => any) | undefined)?.(e);`;
|
|
2344
|
+
if (combined.first) {
|
|
2345
|
+
addMappedText("", handlerCall, "", combined.span, status, b);
|
|
2346
|
+
b.append(body);
|
|
2347
|
+
} else {
|
|
2348
|
+
b.append(body);
|
|
2349
|
+
addMappedText("", handlerCall, "", combined.span, status, b);
|
|
2350
|
+
}
|
|
2351
|
+
b.append("});");
|
|
2292
2352
|
}
|
|
2293
2353
|
function buildEventAttribute(varName, name, value, span, status, b) {
|
|
2294
2354
|
value = replaceForVarNames(value, status);
|
|
@@ -2799,7 +2859,7 @@ function buildServerComponentNode(node, status, b) {
|
|
|
2799
2859
|
const nameAttribute = slot.attributes.find((a) => a.name === "name");
|
|
2800
2860
|
const slotName = nameAttribute?.value ? trimQuotes(nameAttribute.value) : "_";
|
|
2801
2861
|
const slotParams = [slot.hasSlotProps ? "$slot: Record<PropertyKey, any>" : "_$slot?: Record<PropertyKey, any>", "// @ts-ignore\n// eslint-disable-next-line no-unused-vars\n$context?: Record<PropertyKey, any>"];
|
|
2802
|
-
b.append(`${slot.hasSlotProps ? "// @ts-ignore\n" : ""}${slotsName}["${slotName}"] = (\n${slotParams.join(",\n")}\n) => {`);
|
|
2862
|
+
b.append(`${slot.hasSlotProps ? "// @ts-ignore\n" : ""}${slotsName}["${slotName}"] = async (\n${slotParams.join(",\n")}\n) => {`);
|
|
2803
2863
|
b.append(`let t_body = "";`);
|
|
2804
2864
|
for (let child of slot.children) buildServerNode(child, status, b);
|
|
2805
2865
|
if (status.output) {
|
|
@@ -2818,7 +2878,7 @@ function buildServerComponentNode(node, status, b) {
|
|
|
2818
2878
|
let renderParams = `${propsName}, $context`;
|
|
2819
2879
|
if (slotsName !== "undefined") renderParams += `, ${slotsName}`;
|
|
2820
2880
|
const componentResult = nextVarName("comp", status);
|
|
2821
|
-
b.append(`const ${componentResult} = ${componentName}(${renderParams});`);
|
|
2881
|
+
b.append(`const ${componentResult} = await ${componentName}(${renderParams});`);
|
|
2822
2882
|
b.append(`${status.inHead ? "t_head" : "t_body"} += ${componentResult}.body;`);
|
|
2823
2883
|
b.append(`t_head += ${componentResult}.head;`);
|
|
2824
2884
|
status.output += HYDRATION_END_COMMENT;
|
|
@@ -2826,16 +2886,37 @@ function buildServerComponentNode(node, status, b) {
|
|
|
2826
2886
|
}
|
|
2827
2887
|
//#endregion
|
|
2828
2888
|
//#region src/compile/build/server/buildServerAwaitNode.ts
|
|
2889
|
+
/**
|
|
2890
|
+
* Builds an `@await` boundary for the server (ASYNC.md → "Server rendering").
|
|
2891
|
+
*
|
|
2892
|
+
* Rather than inlining the `with` branch (the old shape), the boundary is
|
|
2893
|
+
* handed to the `t_await_server` runtime helper: content and `with` branches
|
|
2894
|
+
* become closures, and the helper decides at render time whether resolved
|
|
2895
|
+
* content can ship (all `source: "server"` reads settled) or the `with`
|
|
2896
|
+
* branch + client fetch is the honest output. The runtime emits the
|
|
2897
|
+
* hydration markers and anchor itself, including the `<!--t-await:...-->`
|
|
2898
|
+
* values payload for resolved boundaries.
|
|
2899
|
+
*/
|
|
2829
2900
|
function buildServerAwaitNode(node, status, b) {
|
|
2830
|
-
status.output += HYDRATION_START_COMMENT;
|
|
2831
2901
|
flushOutput(status, b);
|
|
2832
|
-
|
|
2833
|
-
status.
|
|
2834
|
-
|
|
2835
|
-
}
|
|
2836
|
-
|
|
2837
|
-
|
|
2902
|
+
status.imports.add("t_await_server");
|
|
2903
|
+
const id = status.awaitCount++;
|
|
2904
|
+
const resultName = nextVarName("await", status);
|
|
2905
|
+
b.append(`const ${resultName} = await t_await_server("${id}", async () => {`);
|
|
2906
|
+
b.append(`let t_body = "";`);
|
|
2907
|
+
b.append(`let t_head = "";`);
|
|
2908
|
+
for (let branch of node.children) if (isControlNode(branch) && branch.operation === "@await") for (let child of branch.children) buildServerNode(child, status, b);
|
|
2909
|
+
flushOutput(status, b);
|
|
2910
|
+
b.append(`return { body: t_body, head: t_head };`);
|
|
2911
|
+
b.append(`}, async () => {`);
|
|
2912
|
+
b.append(`let t_body = "";`);
|
|
2913
|
+
b.append(`let t_head = "";`);
|
|
2914
|
+
for (let branch of node.children) if (isControlNode(branch) && branch.operation === "@with") for (let child of branch.children) buildServerNode(child, status, b);
|
|
2838
2915
|
flushOutput(status, b);
|
|
2916
|
+
b.append(`return { body: t_body, head: t_head };`);
|
|
2917
|
+
b.append(`});`);
|
|
2918
|
+
b.append(`${status.inHead ? "t_head" : "t_body"} += ${resultName}.body;`);
|
|
2919
|
+
b.append(`t_head += ${resultName}.head;`);
|
|
2839
2920
|
}
|
|
2840
2921
|
//#endregion
|
|
2841
2922
|
//#region src/compile/build/server/buildServerForNode.ts
|
|
@@ -3090,7 +3171,7 @@ function buildServerSlotNode(node, status, b) {
|
|
|
3090
3171
|
else b.append(`${propsName}["${name}"] = true;`);
|
|
3091
3172
|
}
|
|
3092
3173
|
b.append(`if ($slots && $slots["${slotName}"]) {`);
|
|
3093
|
-
b.append(`${status.inHead ? "t_head" : "t_body"} += $slots["${slotName}"](${slotHasProps ? propsName : "undefined"}, $context);`);
|
|
3174
|
+
b.append(`${status.inHead ? "t_head" : "t_body"} += await $slots["${slotName}"](${slotHasProps ? propsName : "undefined"}, $context);`);
|
|
3094
3175
|
const fill = node.children.find((c) => isSpecialNode(c) && (c.tagName === "fill" || c.tagName === "filldef"));
|
|
3095
3176
|
if (fill && isSpecialNode(fill) && fill.children.length) {
|
|
3096
3177
|
b.append(`} else {`);
|
|
@@ -3193,6 +3274,8 @@ const importsMap = {
|
|
|
3193
3274
|
$unwrap: "import { $unwrap } from \"${folder}\";",
|
|
3194
3275
|
$peek: "import { $peek } from \"${folder}\";",
|
|
3195
3276
|
$batch: "import { $batch } from \"${folder}\";",
|
|
3277
|
+
t_server_flush: "import { t_server_flush } from \"${folder}\";",
|
|
3278
|
+
t_await_server: "import { t_await_server } from \"${folder}\";",
|
|
3196
3279
|
t_fmt: "import { t_fmt } from \"${folder}\";",
|
|
3197
3280
|
t_attr: "import { t_attr } from \"${folder}\";",
|
|
3198
3281
|
t_class: "import { t_class } from \"${folder}\";",
|
|
@@ -3235,18 +3318,24 @@ function buildServerTemplate(template, imports, b, options) {
|
|
|
3235
3318
|
if (/\$unwrap\b/.test(scriptCode)) imports.add("$unwrap");
|
|
3236
3319
|
if (/\$peek\b/.test(scriptCode)) imports.add("$peek");
|
|
3237
3320
|
if (/\$batch\b/.test(scriptCode)) imports.add("$batch");
|
|
3321
|
+
const asyncChunks = /* @__PURE__ */ new Set();
|
|
3322
|
+
for (let [i, chunk] of template.script.entries()) if (chunk.script === "/* @params */" && i > 0) asyncChunks.add(i - 1);
|
|
3238
3323
|
let currentIndex = 0;
|
|
3239
3324
|
let current = template.components[0];
|
|
3240
|
-
for (let chunk of template.script) if (chunk.script === "/* @params */") {
|
|
3325
|
+
for (let [chunkIndex, chunk] of template.script.entries()) if (chunk.script === "/* @params */") {
|
|
3241
3326
|
let params = [
|
|
3242
3327
|
current.params ?? `${current.props?.length ? "$props: Record<PropertyKey, any>" : "_$props?: Record<PropertyKey, any>"}`,
|
|
3243
3328
|
`${current.contextProps?.length || current.markup && markupRendersComponent(current.markup) || current.error && markupRendersComponent(current.error) ? "$context" : "_$context"}?: Record<PropertyKey, any>`,
|
|
3244
3329
|
`${current.slotProps?.length ? "$slots" : "_$slots"}?: Record<string, ServerSlotRender>`
|
|
3245
3330
|
];
|
|
3246
3331
|
b.append(params.join(",\n") + ",");
|
|
3247
|
-
} else if (chunk.script === ") /* @return_type */ {") b.append("): { body: string; head: string } {");
|
|
3332
|
+
} else if (chunk.script === ") /* @return_type */ {") b.append("): Promise<{ body: string; head: string }> {");
|
|
3248
3333
|
else if (chunk.script === "/* @start */") {
|
|
3249
3334
|
if (current.contextProps?.length) b.append(`$context = Object.assign({}, $context);`);
|
|
3335
|
+
if (containsAwaitGroup(current.markup) || containsAwaitGroup(current.error) || containsAwaitGroup(current.head)) {
|
|
3336
|
+
imports.add("t_server_flush");
|
|
3337
|
+
b.append(`return t_server_flush(async () => {`);
|
|
3338
|
+
}
|
|
3250
3339
|
b.append(`let t_body = "";`);
|
|
3251
3340
|
b.append(`let t_head = "";`);
|
|
3252
3341
|
} else if (chunk.script === "/* @render */") {
|
|
@@ -3257,6 +3346,7 @@ function buildServerTemplate(template, imports, b, options) {
|
|
|
3257
3346
|
styleHash: current.style?.hash || "",
|
|
3258
3347
|
varNames: {},
|
|
3259
3348
|
preserveWhitespace: false,
|
|
3349
|
+
awaitCount: 0,
|
|
3260
3350
|
options
|
|
3261
3351
|
};
|
|
3262
3352
|
b.append("");
|
|
@@ -3280,6 +3370,7 @@ function buildServerTemplate(template, imports, b, options) {
|
|
|
3280
3370
|
styleHash: current.style?.hash || "",
|
|
3281
3371
|
varNames: {},
|
|
3282
3372
|
preserveWhitespace: false,
|
|
3373
|
+
awaitCount: 0,
|
|
3283
3374
|
options
|
|
3284
3375
|
};
|
|
3285
3376
|
b.append(`} catch (${current.errorVar}) {`);
|
|
@@ -3302,6 +3393,7 @@ function buildServerTemplate(template, imports, b, options) {
|
|
|
3302
3393
|
varNames: {},
|
|
3303
3394
|
preserveWhitespace: false,
|
|
3304
3395
|
inHead: true,
|
|
3396
|
+
awaitCount: 0,
|
|
3305
3397
|
options
|
|
3306
3398
|
};
|
|
3307
3399
|
b.append("");
|
|
@@ -3318,9 +3410,23 @@ function buildServerTemplate(template, imports, b, options) {
|
|
|
3318
3410
|
}
|
|
3319
3411
|
} else if (chunk.script === "/* @end */") {
|
|
3320
3412
|
b.append(`return { body: t_body, head: t_head };`);
|
|
3413
|
+
if (containsAwaitGroup(current.markup) || containsAwaitGroup(current.error) || containsAwaitGroup(current.head)) b.append(`});`);
|
|
3321
3414
|
currentIndex += 1;
|
|
3322
3415
|
current = template.components[currentIndex];
|
|
3323
|
-
} else b.append(chunk.script);
|
|
3416
|
+
} else if (asyncChunks.has(chunkIndex)) b.append(chunk.script.replace(/(?<!async\s)function\s+([A-Za-z_$][\w$]*)((?:<(?:[^<>]|<[^<>]*>)*>)?)\s*\($/, "async function $1$2("));
|
|
3417
|
+
else b.append(chunk.script);
|
|
3418
|
+
}
|
|
3419
|
+
/**
|
|
3420
|
+
* Whether a markup tree contains an `@await` boundary, so the component's
|
|
3421
|
+
* render must be wrapped in a flush.
|
|
3422
|
+
*/
|
|
3423
|
+
function containsAwaitGroup(node) {
|
|
3424
|
+
if (node === void 0 || node === null) return false;
|
|
3425
|
+
if (isControlNode(node) && node.operation === "@await group") return true;
|
|
3426
|
+
if (node.type !== "text" && node.type !== "comment") {
|
|
3427
|
+
for (let child of node.children) if (containsAwaitGroup(child)) return true;
|
|
3428
|
+
}
|
|
3429
|
+
return false;
|
|
3324
3430
|
}
|
|
3325
3431
|
//#endregion
|
|
3326
3432
|
//#region src/compile/utils/trimWhitespace.ts
|