@lucidkiln/core 1.1.0 → 1.2.0
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/CHANGELOG.md +5 -0
- package/dist/{ast-1akLiy-A.d.ts → ast-DDhHuwaY.d.ts} +15 -22
- package/dist/ast-DDhHuwaY.d.ts.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{environment-DkfrPazl.d.ts → environment-DBvRrOn0.d.ts} +15 -8
- package/dist/environment-DBvRrOn0.d.ts.map +1 -0
- package/dist/{format-CLCViAPn.js → format-Di6-GUtH.js} +4 -4
- package/dist/{format-CLCViAPn.js.map → format-Di6-GUtH.js.map} +1 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +50 -147
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/{parser-BU5dThuk.js → parser-isboTef0.js} +59 -99
- package/dist/parser-isboTef0.js.map +1 -0
- package/dist/{source-BHcxowQp.js → source-BbikGqIb.js} +25 -97
- package/dist/source-BbikGqIb.js.map +1 -0
- package/dist/syntax.d.ts +1 -1
- package/dist/syntax.js +1 -1
- package/package.json +1 -1
- package/dist/ast-1akLiy-A.d.ts.map +0 -1
- package/dist/environment-DkfrPazl.d.ts.map +0 -1
- package/dist/parser-BU5dThuk.js.map +0 -1
- package/dist/source-BHcxowQp.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { a as ESCAPE_STRATEGIES, i as DEFAULT_SLOT, r as scanParts, t as parse } from "./parser-
|
|
1
|
+
import { $ as compare, $t as escapeUrl, A as consume, At as additionsIn, B as loadTemplate, Bt as fillScope, C as getAttr, Ct as contentSets, D as after, Dt as passesFrom, E as addSlotFlags, Et as passesAhead, F as fail, Ft as RenderState, G as renderTemplate, Gt as sectionCopy, H as locating, Ht as childScope, I as hold, It as Run, J as unhold, Jt as suggest, K as silence, Kt as sectionScope, L as holdData, Lt as blockScope, M as embed, Mt as closeOutlets, N as embedKeyed, Nt as recordAddition, O as all, Ot as runAhead, P as embedScope, Pt as takeOutput, Q as MISSING, Qt as escapeHtml, R as importsFor, Rt as emptyOut, S as toTime, St as atFront, T as readableNames, Tt as mayRunAhead, U as markCaller, Ut as lookup$1, V as locate, Vt as startCapture, W as passData, Wt as ownerOf, X as write, Xt as isSafe, Y as withCaller, Yt as Markup, Z as FORMATTERS, Zt as safe, _ as markupText, _t as unwrap, a as operatorFunction, an as KilnSyntaxError, at as isHashLike, b as toPieces, bt as expose, c as checkDepth, ct as mapKeys, d as functionArgument, dt as templateFunctions, en as escapeWith, et as describeType, f as insertedPiece, ft as toNumber, g as mapContents, gt as typeName, h as listOf$1, ht as truthy, i as contains, in as KilnRenderError, it as isEmpty, j as consumeAt, jt as checkLate, k as checkLength, kt as runSequence, l as entriesOf, lt as matchesType, m as isHtmlStrategy, mt as toStringArgument, n as builtinFunctions, nn as resolveTemplateName, nt as equals, o as rangeOperator, on as createDiagnostic, ot as isPlainObject, p as integerArgument, pt as toStr, q as step, qt as variableNames, r as builtinTests, rn as KilnIssue, rt as hashKeys, s as Kept, sn as issue, st as literalOptions, t as Source, tn as TEMPLATE_EXTENSION, tt as describeValue, u as fromPieces, ut as setOwn, v as readProperty, vt as valueLabel, w as getMethod, wt as isRoot, x as toPlainData, xt as lookup, y as scanHtml, yt as BLOCKED_NAMES, z as isPromise, zt as endCapture } from "./source-BbikGqIb.js";
|
|
2
|
+
import { a as ESCAPE_STRATEGIES, i as DEFAULT_SLOT, r as scanParts, t as parse } from "./parser-isboTef0.js";
|
|
3
3
|
//#region src/analyzer.ts
|
|
4
4
|
const MAX_DEPTH$1 = 1e3;
|
|
5
5
|
/** The statement lists nested inside a statement. */
|
|
@@ -2097,18 +2097,14 @@ const printParts = (list) => {
|
|
|
2097
2097
|
const parts = [];
|
|
2098
2098
|
for (const part of list) {
|
|
2099
2099
|
const last = parts.at(-1);
|
|
2100
|
-
if (part.text !== null && last && last.text !== null) {
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
end: part.span.end
|
|
2109
|
-
}
|
|
2110
|
-
};
|
|
2111
|
-
} else parts.push(part);
|
|
2100
|
+
if (part.text !== null && last && last.text !== null) parts[parts.length - 1] = {
|
|
2101
|
+
text: last.text + part.text,
|
|
2102
|
+
span: {
|
|
2103
|
+
start: last.span.start,
|
|
2104
|
+
end: part.span.end
|
|
2105
|
+
}
|
|
2106
|
+
};
|
|
2107
|
+
else parts.push(part);
|
|
2112
2108
|
}
|
|
2113
2109
|
const first = parts[0];
|
|
2114
2110
|
const span = {
|
|
@@ -2117,18 +2113,12 @@ const printParts = (list) => {
|
|
|
2117
2113
|
};
|
|
2118
2114
|
if (parts.length === 1 && first.text !== null) {
|
|
2119
2115
|
const text = first.text;
|
|
2120
|
-
if (!first.lines) return (run, _scope, out) => {
|
|
2121
|
-
write(run, out, text, span);
|
|
2122
|
-
};
|
|
2123
|
-
const entry = indentedText(text, first.lines);
|
|
2124
2116
|
return (run, _scope, out) => {
|
|
2125
|
-
|
|
2126
|
-
write(run, out, indent === "" ? text : indentText(entry, indent, out.inline), span);
|
|
2117
|
+
write(run, out, text, span);
|
|
2127
2118
|
};
|
|
2128
2119
|
}
|
|
2129
2120
|
const count = parts.length;
|
|
2130
2121
|
const texts = [];
|
|
2131
|
-
const indented = [];
|
|
2132
2122
|
const reads = [];
|
|
2133
2123
|
const evs = [];
|
|
2134
2124
|
const emits = [];
|
|
@@ -2146,7 +2136,6 @@ const printParts = (list) => {
|
|
|
2146
2136
|
const root = compiled?.variable ?? path?.root.variable ?? null;
|
|
2147
2137
|
const choice = compiled?.choice ? emitChoice(compiled.choice, emit) : null;
|
|
2148
2138
|
texts.push(part.text);
|
|
2149
|
-
indented.push(part.text !== null && part.lines ? indentedText(part.text, part.lines) : null);
|
|
2150
2139
|
reads.push(root !== null ? "path" : choice ? "choice" : "other");
|
|
2151
2140
|
evs.push(compiled?.ev ?? null);
|
|
2152
2141
|
emits.push(emit);
|
|
@@ -2158,13 +2147,11 @@ const printParts = (list) => {
|
|
|
2158
2147
|
spans.push(part.span);
|
|
2159
2148
|
}
|
|
2160
2149
|
return (run, scope, out) => {
|
|
2161
|
-
const indent = out.indent;
|
|
2162
2150
|
let text = "";
|
|
2163
2151
|
for (let i = 0; i < count; i++) {
|
|
2164
2152
|
const part = texts[i];
|
|
2165
2153
|
if (part !== null) {
|
|
2166
|
-
|
|
2167
|
-
text += indent === "" || !entry ? part : entry.indent === indent && !out.inline ? entry.indented : indentText(entry, indent, text === "" && out.inline);
|
|
2154
|
+
text += part;
|
|
2168
2155
|
continue;
|
|
2169
2156
|
}
|
|
2170
2157
|
const at = spans[i];
|
|
@@ -2648,7 +2635,6 @@ var Compiler = class {
|
|
|
2648
2635
|
if (parts.length === 0) partsStart = i;
|
|
2649
2636
|
parts.push({
|
|
2650
2637
|
text: statement.value,
|
|
2651
|
-
lines: statement.lines,
|
|
2652
2638
|
span: statement.span
|
|
2653
2639
|
});
|
|
2654
2640
|
continue;
|
|
@@ -2780,15 +2766,13 @@ var Compiler = class {
|
|
|
2780
2766
|
const env = this.#env;
|
|
2781
2767
|
/**
|
|
2782
2768
|
* Runs passes `index` to `end`. When a pass waits, the passes after it run as `passesFrom` runs them: ahead of
|
|
2783
|
-
* it when they may. `ahead` is whether they may, found the first time a pass waits
|
|
2784
|
-
* output's indentation when the loop started.
|
|
2769
|
+
* it when they may. `ahead` is whether they may, found the first time a pass waits.
|
|
2785
2770
|
*/
|
|
2786
|
-
const iterate = (run, scope, out, values, keys, index, end, reused,
|
|
2771
|
+
const iterate = (run, scope, out, values, keys, index, end, reused, ahead) => {
|
|
2787
2772
|
const length = values.length;
|
|
2788
2773
|
for (let i = index; i < end; i++) {
|
|
2789
2774
|
step(run, span);
|
|
2790
2775
|
const inner = reused ?? childScope(scope);
|
|
2791
|
-
const inline = out.inline;
|
|
2792
2776
|
inner[valueName] = values[i] ?? null;
|
|
2793
2777
|
if (keyName !== null) inner[keyName] = keys ? keys[i] ?? null : i;
|
|
2794
2778
|
if (usesLoop) inner.loop = {
|
|
@@ -2811,14 +2795,14 @@ var Compiler = class {
|
|
|
2811
2795
|
};
|
|
2812
2796
|
}
|
|
2813
2797
|
const may = ahead ??= passesAhead(run, scope, effects.sets, effects.elsewhere);
|
|
2814
|
-
return passesFrom(run, out, result,
|
|
2798
|
+
return passesFrom(run, out, result, i + 1, end, (aheadRun, aheadOut, at) => iterate(aheadRun, scope, aheadOut, values, keys, at, at + 1, shared ? childScope(scope) : null, may), span, may);
|
|
2815
2799
|
}
|
|
2816
2800
|
};
|
|
2817
2801
|
const start = (run, scope, out, value) => {
|
|
2818
2802
|
const { values, keys } = loopItems(run, span, value, keyName !== null);
|
|
2819
2803
|
if (values.length === 0) return alternate?.(run, scope, out);
|
|
2820
2804
|
const reused = shared ? childScope(scope) : null;
|
|
2821
|
-
return iterate(run, scope, out, values, keys, 0, values.length, reused,
|
|
2805
|
+
return iterate(run, scope, out, values, keys, 0, values.length, reused, null);
|
|
2822
2806
|
};
|
|
2823
2807
|
const ev = iterable.ev;
|
|
2824
2808
|
if (!iterable.async) return (run, scope, out) => {
|
|
@@ -2945,31 +2929,20 @@ var Compiler = class {
|
|
|
2945
2929
|
}
|
|
2946
2930
|
#blockStatement(node) {
|
|
2947
2931
|
this.#defineBlock(node);
|
|
2948
|
-
const { name, span
|
|
2932
|
+
const { name, span } = node;
|
|
2949
2933
|
return (run, scope, out) => {
|
|
2950
2934
|
const entry = run.blocks.get(name)?.[0];
|
|
2951
2935
|
if (!entry) return;
|
|
2952
2936
|
const render = () => entry.def.body(entry.run.within(run.capture, run.blockDepth), blockScope(entry.def, scope), out);
|
|
2953
|
-
|
|
2954
|
-
if (indent === "") return own ? render() : withCaller(run, span, render);
|
|
2955
|
-
const saved = out.indent;
|
|
2956
|
-
const inline = out.inline;
|
|
2957
|
-
startPlace(out, indent);
|
|
2958
|
-
return endPlace(out, saved, inline, own ? render() : withCaller(run, span, render));
|
|
2937
|
+
return entry.run.template === run.template ? render() : withCaller(run, span, render);
|
|
2959
2938
|
};
|
|
2960
2939
|
}
|
|
2961
2940
|
#include(node) {
|
|
2962
|
-
const { ignoreMissing, span
|
|
2963
|
-
return this.#embedding(node.template, node.with, span, (run, out, name, variables) =>
|
|
2964
|
-
if (indent === "") return embed(run, out, span, name, variables, null, ignoreMissing);
|
|
2965
|
-
const saved = out.indent;
|
|
2966
|
-
const inline = out.inline;
|
|
2967
|
-
startPlace(out, indent);
|
|
2968
|
-
return endPlace(out, saved, inline, embed(run, out, span, name, variables, null, ignoreMissing));
|
|
2969
|
-
});
|
|
2941
|
+
const { ignoreMissing, span } = node;
|
|
2942
|
+
return this.#embedding(node.template, node.with, span, (run, out, name, variables) => embed(run, out, span, name, variables, null, ignoreMissing));
|
|
2970
2943
|
}
|
|
2971
2944
|
#component(node) {
|
|
2972
|
-
const { span
|
|
2945
|
+
const { span } = node;
|
|
2973
2946
|
const fills = node.fills.map((fill) => ({
|
|
2974
2947
|
name: fill.name,
|
|
2975
2948
|
body: this.#body(fill.body),
|
|
@@ -2991,11 +2964,7 @@ var Compiler = class {
|
|
|
2991
2964
|
scope: callerScope,
|
|
2992
2965
|
sets: fill.sets
|
|
2993
2966
|
});
|
|
2994
|
-
|
|
2995
|
-
const saved = out.indent;
|
|
2996
|
-
const inline = out.inline;
|
|
2997
|
-
startPlace(out, indent);
|
|
2998
|
-
return endPlace(out, saved, inline, embed(run, out, span, name, variables, slots, false));
|
|
2967
|
+
return embed(run, out, span, name, variables, slots, false);
|
|
2999
2968
|
});
|
|
3000
2969
|
}
|
|
3001
2970
|
/**
|
|
@@ -3013,11 +2982,10 @@ var Compiler = class {
|
|
|
3013
2982
|
opening = ISLAND_SCRIPT + opening;
|
|
3014
2983
|
if (isRoot(state, out)) state.islandScript = true;
|
|
3015
2984
|
}
|
|
3016
|
-
|
|
3017
|
-
write(run, out, indent === void 0 ? opening : `${lead(indent)}${opening}${closing?.indent === null ? "" : "\n"}`, span);
|
|
2985
|
+
write(run, out, indent === void 0 ? opening : `${indent}${opening}${closing?.indent === null ? "" : "\n"}`, span);
|
|
3018
2986
|
return after(fallback(run, childScope(scope), out), () => {
|
|
3019
2987
|
if (!closing) return write(run, out, ISLAND_CLOSING, span);
|
|
3020
|
-
const start = closing.indent
|
|
2988
|
+
const start = closing.indent ?? "";
|
|
3021
2989
|
const end = closing.newline ? "\n" : "";
|
|
3022
2990
|
return write(run, out, `${start}${ISLAND_CLOSING}${end}`, span);
|
|
3023
2991
|
});
|
|
@@ -3040,11 +3008,7 @@ var Compiler = class {
|
|
|
3040
3008
|
const state = run.state;
|
|
3041
3009
|
const islands = state.islands;
|
|
3042
3010
|
if (islands !== null && (islands.mode === "defer" || state.stream !== null && isRoot(state, out) && !run.capture?.section)) return after(loadTemplate(run, name, span), (template) => template ? render(run, out, scope, islands, template, props) : void 0);
|
|
3043
|
-
|
|
3044
|
-
const saved = out.indent;
|
|
3045
|
-
const inline = out.inline;
|
|
3046
|
-
startPlace(out, indent);
|
|
3047
|
-
return endPlace(out, saved, inline, embed(run, out, span, name, props, null, false));
|
|
3011
|
+
return embed(run, out, span, name, props, null, false);
|
|
3048
3012
|
};
|
|
3049
3013
|
return this.#embedding(node.template, node.with, span, (run, out, name, variables, scope) => run.state.islands === null ? place(run, out, name, variables, scope) : atFront(run, () => place(run, out, name, variables, scope)));
|
|
3050
3014
|
}
|
|
@@ -3071,8 +3035,8 @@ var Compiler = class {
|
|
|
3071
3035
|
}
|
|
3072
3036
|
#slot(node) {
|
|
3073
3037
|
const fallback = this.#body(node.body);
|
|
3074
|
-
const { name, span
|
|
3075
|
-
|
|
3038
|
+
const { name, span } = node;
|
|
3039
|
+
return (run, scope, out) => {
|
|
3076
3040
|
const fill = run.slots?.get(name);
|
|
3077
3041
|
if (!fill) return fallback(run, childScope(scope), out);
|
|
3078
3042
|
try {
|
|
@@ -3085,13 +3049,6 @@ var Compiler = class {
|
|
|
3085
3049
|
throw markCaller(run, span, error);
|
|
3086
3050
|
}
|
|
3087
3051
|
};
|
|
3088
|
-
if (indent === "") return render;
|
|
3089
|
-
return (run, scope, out) => {
|
|
3090
|
-
const saved = out.indent;
|
|
3091
|
-
const inline = out.inline;
|
|
3092
|
-
startPlace(out, indent);
|
|
3093
|
-
return endPlace(out, saved, inline, render(run, scope, out));
|
|
3094
|
-
};
|
|
3095
3052
|
}
|
|
3096
3053
|
#with(node) {
|
|
3097
3054
|
const value = this.#expr(node.value);
|
|
@@ -3134,11 +3091,10 @@ var Compiler = class {
|
|
|
3134
3091
|
if (value instanceof Markup) return value.value;
|
|
3135
3092
|
throw fail(run, span, "type-error", `"cache" keys are made of strings, numbers, booleans, dates and null, but got a ${typeName(value)}`);
|
|
3136
3093
|
};
|
|
3137
|
-
const fullKey = (run,
|
|
3094
|
+
const fullKey = (run, value) => {
|
|
3138
3095
|
const parts = Array.isArray(value) ? value.map((item) => part(run, item)) : [part(run, value)];
|
|
3139
3096
|
const { locale, timeZone, islands } = run.state;
|
|
3140
|
-
|
|
3141
|
-
if (out.indent !== "") key += `|indent|${JSON.stringify([out.indent, out.inline])}`;
|
|
3097
|
+
const key = `${JSON.stringify(run.state.env.cacheNamespace)}|${templateName}|${locale}|${timeZone}|${JSON.stringify(parts)}`;
|
|
3142
3098
|
return islands?.mode === "defer" ? `${key}|islands|${JSON.stringify([islands.url, islands.script])}` : key;
|
|
3143
3099
|
};
|
|
3144
3100
|
const lifetime = (run, value) => {
|
|
@@ -3147,7 +3103,7 @@ var Compiler = class {
|
|
|
3147
3103
|
return value;
|
|
3148
3104
|
};
|
|
3149
3105
|
const save = (run, scope, out, keyValue, secondsValue) => {
|
|
3150
|
-
const name = fullKey(run,
|
|
3106
|
+
const name = fullKey(run, keyValue);
|
|
3151
3107
|
const time = lifetime(run, secondsValue);
|
|
3152
3108
|
const state = run.state;
|
|
3153
3109
|
const store = state.env.cache;
|
|
@@ -3229,7 +3185,7 @@ var Compiler = class {
|
|
|
3229
3185
|
* so the outlet must write to that output, not to a capture or a cached section.
|
|
3230
3186
|
*/
|
|
3231
3187
|
#outlet(node) {
|
|
3232
|
-
const { name, span
|
|
3188
|
+
const { name, span } = node;
|
|
3233
3189
|
const mark = (run, out) => {
|
|
3234
3190
|
const state = run.state;
|
|
3235
3191
|
if (!isRoot(state, out) || run.capture?.section) throw fail(run, span, "misplaced-outlet", `Outlet "${name}" can't be inside "cache", "set", "apply" or a macro`);
|
|
@@ -3238,8 +3194,6 @@ var Compiler = class {
|
|
|
3238
3194
|
state.outlets.set(name, {
|
|
3239
3195
|
out,
|
|
3240
3196
|
offset: out.s.length,
|
|
3241
|
-
indent: indent === void 0 ? out.indent : out.indent + indent,
|
|
3242
|
-
inline: indent === void 0,
|
|
3243
3197
|
content: null
|
|
3244
3198
|
});
|
|
3245
3199
|
};
|
|
@@ -3267,9 +3221,8 @@ var Compiler = class {
|
|
|
3267
3221
|
};
|
|
3268
3222
|
}
|
|
3269
3223
|
/**
|
|
3270
|
-
* `add to`: renders its content and records it for the outlet.
|
|
3271
|
-
*
|
|
3272
|
-
* section saves it.
|
|
3224
|
+
* `add to`: renders its content and records it for the outlet. A `once` tag that already added doesn't render again,
|
|
3225
|
+
* but is still recorded, so a cached section saves it.
|
|
3273
3226
|
*/
|
|
3274
3227
|
#add(node) {
|
|
3275
3228
|
const body = this.#body(node.body);
|
|
@@ -3285,12 +3238,7 @@ var Compiler = class {
|
|
|
3285
3238
|
}, front);
|
|
3286
3239
|
return;
|
|
3287
3240
|
}
|
|
3288
|
-
const capture =
|
|
3289
|
-
s: "",
|
|
3290
|
-
indent: OUTLET_INDENT,
|
|
3291
|
-
inline: false,
|
|
3292
|
-
ahead: null
|
|
3293
|
-
};
|
|
3241
|
+
const capture = emptyOut();
|
|
3294
3242
|
return after(body(run, childScope(scope), capture), () => recordAddition(run, span, {
|
|
3295
3243
|
outlet,
|
|
3296
3244
|
html: capture.s,
|
|
@@ -4208,7 +4156,7 @@ const isPrecompiled = (value) => typeof value === "object" && value !== null &&
|
|
|
4208
4156
|
const mismatch = (name, detail) => new KilnRenderError("precompiled-mismatch", `Precompiled template "${name}" ${detail}. Precompile it again`, name);
|
|
4209
4157
|
/** Compiles a precompiled template: its source, with the generated statements in place of the ones they cover. */
|
|
4210
4158
|
const compilePrecompiled = (env, name, template) => {
|
|
4211
|
-
if (template.kiln !==
|
|
4159
|
+
if (template.kiln !== 5) throw mismatch(name, "was made by another version of Kiln");
|
|
4212
4160
|
if (template.autoescape !== env.autoescape) throw mismatch(name, "was compiled with another \"autoescape\" option");
|
|
4213
4161
|
const runs = /* @__PURE__ */ new Map();
|
|
4214
4162
|
const create = template.create;
|
|
@@ -4288,30 +4236,29 @@ const runtime = {
|
|
|
4288
4236
|
unhold,
|
|
4289
4237
|
/**
|
|
4290
4238
|
* Continues a generated run after a statement that returned a promise, `pending`: the rest of the run starts at
|
|
4291
|
-
* once, ahead of it, when it may, or else once the statement is done.
|
|
4292
|
-
* function started. See `runAhead`.
|
|
4239
|
+
* once, ahead of it, when it may, or else once the statement is done. See `runAhead`.
|
|
4293
4240
|
*/
|
|
4294
|
-
restAhead: (run, out, pending,
|
|
4241
|
+
restAhead: (run, out, pending, rest, span) => mayRunAhead(run.state) ? runAhead(run, out, pending, rest, span) : pending.then(() => rest(run, out)),
|
|
4295
4242
|
contentSets,
|
|
4296
4243
|
/**
|
|
4297
4244
|
* Continues a generated loop after a pass that returned a promise, `pending`: passes `from` to `to` run one at a
|
|
4298
4245
|
* time with `pass`, ahead of it when they may, see `passesAhead`. `sets` are the variables the loop's body sets,
|
|
4299
4246
|
* and `elsewhere` whether it places content from elsewhere.
|
|
4300
4247
|
*/
|
|
4301
|
-
passAhead: (run, scope, out, pending,
|
|
4248
|
+
passAhead: (run, scope, out, pending, sets, elsewhere, from, to, pass, span) => passesFrom(run, out, pending, from, to, pass, span, passesAhead(run, scope, sets, elsewhere)),
|
|
4302
4249
|
/**
|
|
4303
4250
|
* For a generated loop that pauses inside a pass: starts passes `from` to `to` ahead of it when they may, and returns
|
|
4304
4251
|
* what the loop calls once the pass is done. Returns null when they may not, and the loop carries on as usual.
|
|
4305
4252
|
*/
|
|
4306
|
-
startAhead: (run, scope, out,
|
|
4307
|
-
if (!mayRunAhead(run.state
|
|
4253
|
+
startAhead: (run, scope, out, sets, elsewhere, from, to, pass, span) => {
|
|
4254
|
+
if (!mayRunAhead(run.state) || !passesAhead(run, scope, sets, elsewhere)) return null;
|
|
4308
4255
|
let done = NOTHING;
|
|
4309
4256
|
let failed = NOTHING;
|
|
4310
4257
|
const pending = new Promise((resolve, reject) => {
|
|
4311
4258
|
done = resolve;
|
|
4312
4259
|
failed = reject;
|
|
4313
4260
|
});
|
|
4314
|
-
const joined = passesFrom(run, out, pending,
|
|
4261
|
+
const joined = passesFrom(run, out, pending, from, to, pass, span, true);
|
|
4315
4262
|
return {
|
|
4316
4263
|
join: () => {
|
|
4317
4264
|
done();
|
|
@@ -4323,10 +4270,6 @@ const runtime = {
|
|
|
4323
4270
|
}
|
|
4324
4271
|
};
|
|
4325
4272
|
},
|
|
4326
|
-
startPlace,
|
|
4327
|
-
endPlace,
|
|
4328
|
-
indentText,
|
|
4329
|
-
indentedText,
|
|
4330
4273
|
embed,
|
|
4331
4274
|
embedScope,
|
|
4332
4275
|
embedKeyed,
|
|
@@ -4671,10 +4614,6 @@ const HELPERS = [
|
|
|
4671
4614
|
"contentSets",
|
|
4672
4615
|
"passAhead",
|
|
4673
4616
|
"startAhead",
|
|
4674
|
-
"startPlace",
|
|
4675
|
-
"endPlace",
|
|
4676
|
-
"indentText",
|
|
4677
|
-
"indentedText",
|
|
4678
4617
|
"truthy",
|
|
4679
4618
|
"isEmpty",
|
|
4680
4619
|
"equals",
|
|
@@ -4861,7 +4800,7 @@ var Generator = class {
|
|
|
4861
4800
|
return [
|
|
4862
4801
|
"// Precompiled by Kiln. Don't edit this file: precompile the template again.",
|
|
4863
4802
|
"export default {",
|
|
4864
|
-
`\tkiln:
|
|
4803
|
+
`\tkiln: 5,`,
|
|
4865
4804
|
`\tautoescape: ${JSON.stringify(this.#env.autoescape)},`,
|
|
4866
4805
|
`\tsource: ${JSON.stringify(source)},`,
|
|
4867
4806
|
" create(rt) {",
|
|
@@ -4988,7 +4927,7 @@ var Generator = class {
|
|
|
4988
4927
|
const next = `${base}_${index + 1}(run, scope, out)`;
|
|
4989
4928
|
const body = lines.map((line) => line.replace(WAIT_LINE, (_, tabs, result, ahead) => {
|
|
4990
4929
|
const then = `${result}.then(() => ${next})`;
|
|
4991
|
-
const rest = `restAhead(run, out, ${result},
|
|
4930
|
+
const rest = `restAhead(run, out, ${result}, (run, out) => ${next}, ${span})`;
|
|
4992
4931
|
return `${tabs}if (${result} !== undefined) return ${ahead === AHEAD ? rest : ahead === GUARDED ? `contentSets(run) ? ${then} : ${rest}` : then};`;
|
|
4993
4932
|
}));
|
|
4994
4933
|
const last = index === segments.length - 1;
|
|
@@ -5039,8 +4978,6 @@ var Generator = class {
|
|
|
5039
4978
|
"let steps = state.steps;",
|
|
5040
4979
|
"const signal = state.signal;",
|
|
5041
4980
|
`signal !== undefined && signal.aborted && aborted(run, ${span});`,
|
|
5042
|
-
"const ind = out.indent;",
|
|
5043
|
-
"const inl = out.inline;",
|
|
5044
4981
|
"let s = \"\";",
|
|
5045
4982
|
`let ${[
|
|
5046
4983
|
"q",
|
|
@@ -5188,7 +5125,7 @@ var Generator = class {
|
|
|
5188
5125
|
}
|
|
5189
5126
|
#statement(statement, context) {
|
|
5190
5127
|
switch (statement.type) {
|
|
5191
|
-
case "Text": return [
|
|
5128
|
+
case "Text": return [`s += ${JSON.stringify(statement.value)};`];
|
|
5192
5129
|
case "Output": return this.#output(statement.expression, statement.span, context);
|
|
5193
5130
|
case "If": return this.#if(statement, context);
|
|
5194
5131
|
case "For": return this.#for(statement, context);
|
|
@@ -5205,26 +5142,6 @@ var Generator = class {
|
|
|
5205
5142
|
default: return unsupported();
|
|
5206
5143
|
}
|
|
5207
5144
|
}
|
|
5208
|
-
/** Text, with its lines indented to where it is inserted. See `indentText`. */
|
|
5209
|
-
#text(statement) {
|
|
5210
|
-
const text = JSON.stringify(statement.value);
|
|
5211
|
-
if (!statement.lines) return `s += ${text};`;
|
|
5212
|
-
const lines = JSON.stringify(statement.lines);
|
|
5213
|
-
const entry = this.#constant(`text:${statement.span.start}:${statement.span.end}`, "T", `indentedText(${text}, ${lines})`);
|
|
5214
|
-
return `s += ind === "" ? ${text} : ${entry}.indent === ind && !out.inline ? ${entry}.indented : indentText(${entry}, ind, s === "" && out.inline);`;
|
|
5215
|
-
}
|
|
5216
|
-
/**
|
|
5217
|
-
* Inserts content at the indentation of the tag that inserts it, with `startPlace` and `endPlace`. Tags at the start
|
|
5218
|
-
* of a line need nothing. Saved values go in temporaries rather than a closure, so the function's locals stay fast.
|
|
5219
|
-
*/
|
|
5220
|
-
#place(at, call) {
|
|
5221
|
-
if (at === "") return call;
|
|
5222
|
-
const [saved, inline] = [this.#temp(), this.#temp()];
|
|
5223
|
-
return `(${saved} = out.indent, ${inline} = out.inline, startPlace(out, ${this.#at(at)}), endPlace(out, ${saved}, ${inline}, ${call}))`;
|
|
5224
|
-
}
|
|
5225
|
-
#at(at) {
|
|
5226
|
-
return at === void 0 ? "undefined" : JSON.stringify(at);
|
|
5227
|
-
}
|
|
5228
5145
|
/** Statements inside another, such as a loop's body. */
|
|
5229
5146
|
#body(list, context) {
|
|
5230
5147
|
const inner = {
|
|
@@ -5513,7 +5430,7 @@ var Generator = class {
|
|
|
5513
5430
|
const call = (part, value) => `${name}_${part}(${partParams}${value === void 0 ? "" : `, ${value}`})`;
|
|
5514
5431
|
const one = `(run, out, j) => ${name}(run, scope, out, ${loop.values}, ${loop.length}, j, j + 1${keys})`;
|
|
5515
5432
|
const { sets, elsewhere } = this.#setsOf(statement);
|
|
5516
|
-
const handOff = (from, tabs, rest) => from === 0 ? `${tabs}return ${loop.index} + 1 < stop ? passAhead(run, scope, out, ${rest},
|
|
5433
|
+
const handOff = (from, tabs, rest) => from === 0 ? `${tabs}return ${loop.index} + 1 < stop ? passAhead(run, scope, out, ${rest}, ${sets}, ${elsewhere}, ${loop.index} + 1, stop, ${one}, ${loop.span}) : ${rest};` : `${tabs}return ${rest};`;
|
|
5517
5434
|
const continued = (from) => segments.slice(from).flatMap((lines, offset) => this.#forgetLines(lines).flatMap((line) => {
|
|
5518
5435
|
const next = from + offset + 1;
|
|
5519
5436
|
const value = VALUE_LINE.exec(line);
|
|
@@ -5602,7 +5519,7 @@ var Generator = class {
|
|
|
5602
5519
|
const ahead = `a${loop.id}`;
|
|
5603
5520
|
const { index, span } = loop;
|
|
5604
5521
|
const { sets, elsewhere } = this.#setsOf(statement);
|
|
5605
|
-
const fork = `if (${ahead} === null && ${index} + 1 < stop) ${ahead} = startAhead(run, ${loop.outer}, out,
|
|
5522
|
+
const fork = `if (${ahead} === null && ${index} + 1 < stop) ${ahead} = startAhead(run, ${loop.outer}, out, ${sets}, ${elsewhere}, ${index} + 1, stop, (run, out, j) => drive(${name}(run, out, j, j + 1)), ${span});`;
|
|
5606
5523
|
const body = this.#forgetLines(this.#setFlags(lines)).flatMap((line) => {
|
|
5607
5524
|
if (line.trim() === FORK) return [line.replace(FORK, fork)];
|
|
5608
5525
|
const wait = WAIT_LINE.exec(line);
|
|
@@ -5767,7 +5684,7 @@ var Generator = class {
|
|
|
5767
5684
|
...target.lines,
|
|
5768
5685
|
...variables.lines,
|
|
5769
5686
|
...variables.charge(span),
|
|
5770
|
-
...this.#wait(span,
|
|
5687
|
+
...this.#wait(span, variables.embed(span, target.name, "null", statement.ignoreMissing), context.top)
|
|
5771
5688
|
];
|
|
5772
5689
|
}
|
|
5773
5690
|
/**
|
|
@@ -5855,7 +5772,7 @@ var Generator = class {
|
|
|
5855
5772
|
`${slots} = new Map();`,
|
|
5856
5773
|
...fills.map((fill) => `${slots}.set(${JSON.stringify(fill.name)}, { body: ${this.#nested(fill.body, statement.span, context)}, run, scope: ${context.scope}, sets: ${mayWrite(fill.body)} });`),
|
|
5857
5774
|
...variables.charge(span),
|
|
5858
|
-
...this.#wait(span,
|
|
5775
|
+
...this.#wait(span, variables.embed(span, target.name, slots, false), context.top),
|
|
5859
5776
|
...fills.some((fill) => setsVariables(fill.body)) ? this.#forgetAll() : fills.some((fill) => containsNode(fill.body, (record) => record.type === "Block")) ? this.#afterBlocks() : []
|
|
5860
5777
|
];
|
|
5861
5778
|
}
|
|
@@ -5863,7 +5780,6 @@ var Generator = class {
|
|
|
5863
5780
|
#slot(statement, context) {
|
|
5864
5781
|
const span = this.#span(statement.span);
|
|
5865
5782
|
const fill = this.#temp();
|
|
5866
|
-
const at = statement.indent;
|
|
5867
5783
|
const sets = [...setsIn(statement.body)];
|
|
5868
5784
|
const scope = sets.length > 0 ? this.#temp() : context.scope;
|
|
5869
5785
|
let fallback = this.#body(statement.body, {
|
|
@@ -5875,23 +5791,10 @@ var Generator = class {
|
|
|
5875
5791
|
...fallback,
|
|
5876
5792
|
...sets.flatMap((name) => this.#forget(name))
|
|
5877
5793
|
];
|
|
5878
|
-
if (at !== "" && !statement.body.every(isBlank)) {
|
|
5879
|
-
const [saved, inline] = [this.#temp(), this.#temp()];
|
|
5880
|
-
fallback = [
|
|
5881
|
-
`${saved} = out.indent;`,
|
|
5882
|
-
`${inline} = out.inline;`,
|
|
5883
|
-
`startPlace(out, ${this.#at(at)});`,
|
|
5884
|
-
"{",
|
|
5885
|
-
...indent(["const ind = out.indent;", ...fallback]),
|
|
5886
|
-
"}",
|
|
5887
|
-
`out.indent = ${saved};`,
|
|
5888
|
-
`if (out.inline) out.inline = ${inline};`
|
|
5889
|
-
];
|
|
5890
|
-
}
|
|
5891
5794
|
return [
|
|
5892
5795
|
`${fill} = run.slots === null ? undefined : run.slots.get(${JSON.stringify(statement.name)});`,
|
|
5893
5796
|
`if (${fill} !== undefined) {`,
|
|
5894
|
-
...indent(this.#wait(span,
|
|
5797
|
+
...indent(this.#wait(span, `fillSlot(run, ${span}, ${fill}, out)`, context.top)),
|
|
5895
5798
|
"} else {",
|
|
5896
5799
|
...indent(fallback),
|
|
5897
5800
|
"}"
|
|
@@ -5905,7 +5808,7 @@ var Generator = class {
|
|
|
5905
5808
|
if (context.inLoop) return unsupported();
|
|
5906
5809
|
this.#pending.push([statement.body, context.strategy]);
|
|
5907
5810
|
const span = this.#span(statement.span);
|
|
5908
|
-
return [...this.#wait(span,
|
|
5811
|
+
return [...this.#wait(span, `placeBlock(run, ${span}, ${JSON.stringify(statement.name)}, ${context.scope}, out)`, context.top), ...this.#afterBlocks()];
|
|
5909
5812
|
}
|
|
5910
5813
|
/** Forgets every variable lookup after a block is placed when the block, perhaps a child template's version, may set any variable. */
|
|
5911
5814
|
#afterBlocks() {
|