@wcstack/typescript 3.5.4 → 4.0.0-rc.3
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.esm.js +1 -1
- package/dist/schema-core.cjs +2460 -2208
- package/dist/tsc-core.cjs +657 -54
- package/dist/wcs-schema.mjs +1 -1
- package/dist/wcs-tsc.mjs +1 -1
- package/package.json +1 -1
package/dist/tsc-core.cjs
CHANGED
|
@@ -28,8 +28,48 @@ __export(tscCore_exports, {
|
|
|
28
28
|
module.exports = __toCommonJS(tscCore_exports);
|
|
29
29
|
|
|
30
30
|
// src/language/htmlParse.ts
|
|
31
|
+
function asciiLowerCase(text2) {
|
|
32
|
+
return text2.replace(/[A-Z]+/g, (upper2) => upper2.toLowerCase());
|
|
33
|
+
}
|
|
31
34
|
function parseWcsScriptBlocks(html, stateTagName = "wcs-state") {
|
|
32
|
-
|
|
35
|
+
return parseWcsStateElements(html, stateTagName).flatMap((element) => element.scriptBlocks);
|
|
36
|
+
}
|
|
37
|
+
var RAW_TEXT_ELEMENTS = /* @__PURE__ */ new Set([
|
|
38
|
+
"script",
|
|
39
|
+
"style",
|
|
40
|
+
"textarea",
|
|
41
|
+
"title",
|
|
42
|
+
"xmp",
|
|
43
|
+
"iframe",
|
|
44
|
+
"noembed",
|
|
45
|
+
"noframes",
|
|
46
|
+
"noscript",
|
|
47
|
+
"plaintext"
|
|
48
|
+
]);
|
|
49
|
+
function matchRawTextElement(html, lower2, pos) {
|
|
50
|
+
if (html[pos] !== "<") return null;
|
|
51
|
+
for (const tag of RAW_TEXT_ELEMENTS) {
|
|
52
|
+
const open = matchOpenTag(html, pos, tag);
|
|
53
|
+
if (open === null) continue;
|
|
54
|
+
if (tag === "plaintext") return { tag, open, contentEnd: html.length, closed: false };
|
|
55
|
+
let from = open.end;
|
|
56
|
+
for (; ; ) {
|
|
57
|
+
const idx = lower2.indexOf(`</${tag}`, from);
|
|
58
|
+
if (idx === -1) return { tag, open, contentEnd: html.length, closed: false };
|
|
59
|
+
const after = html[idx + tag.length + 2];
|
|
60
|
+
if (after === void 0 || after === ">" || after === "/" || /\s/.test(after)) return { tag, open, contentEnd: idx, closed: true };
|
|
61
|
+
from = idx + 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function afterCloseTag(html, closeStart) {
|
|
67
|
+
const gt = html.indexOf(">", closeStart);
|
|
68
|
+
return gt === -1 ? html.length : gt + 1;
|
|
69
|
+
}
|
|
70
|
+
function parseWcsStateElements(html, stateTagName = "wcs-state") {
|
|
71
|
+
const elements = [];
|
|
72
|
+
const lower2 = asciiLowerCase(html);
|
|
33
73
|
let pos = 0;
|
|
34
74
|
const len = html.length;
|
|
35
75
|
while (pos < len) {
|
|
@@ -39,15 +79,27 @@ function parseWcsScriptBlocks(html, stateTagName = "wcs-state") {
|
|
|
39
79
|
pos = commentEnd + 3;
|
|
40
80
|
continue;
|
|
41
81
|
}
|
|
82
|
+
const raw = matchRawTextElement(html, lower2, pos);
|
|
83
|
+
if (raw !== null) {
|
|
84
|
+
pos = raw.closed ? afterCloseTag(html, raw.contentEnd) : len;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
42
87
|
const wcsMatch = matchOpenTag(html, pos, stateTagName);
|
|
43
88
|
if (wcsMatch === null) {
|
|
44
89
|
pos++;
|
|
45
90
|
continue;
|
|
46
91
|
}
|
|
47
92
|
const mountPath = extractAttribute(wcsMatch.tagContent, "mount");
|
|
93
|
+
const bindComponent = parseAttributeNames(wcsMatch.tagContent).has("bind-component");
|
|
94
|
+
const jsonAttr = extractAttribute(wcsMatch.tagContent, "json") ?? void 0;
|
|
95
|
+
const stateAttr = extractAttribute(wcsMatch.tagContent, "state") ?? void 0;
|
|
96
|
+
const srcAttr = extractAttribute(wcsMatch.tagContent, "src") ?? void 0;
|
|
97
|
+
const tagStart = pos;
|
|
98
|
+
const tagEnd = wcsMatch.end;
|
|
48
99
|
pos = wcsMatch.end;
|
|
49
|
-
const
|
|
50
|
-
|
|
100
|
+
const scriptBlocks = [];
|
|
101
|
+
let wcsCloseIdx = findCloseTag(html, pos, stateTagName, lower2);
|
|
102
|
+
let wcsEnd = wcsCloseIdx === -1 ? len : wcsCloseIdx;
|
|
51
103
|
while (pos < wcsEnd) {
|
|
52
104
|
if (html.startsWith("<!--", pos)) {
|
|
53
105
|
const commentEnd = html.indexOf("-->", pos + 4);
|
|
@@ -55,47 +107,49 @@ function parseWcsScriptBlocks(html, stateTagName = "wcs-state") {
|
|
|
55
107
|
pos = commentEnd + 3;
|
|
56
108
|
continue;
|
|
57
109
|
}
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
110
|
+
const inner = matchRawTextElement(html, lower2, pos);
|
|
111
|
+
if (inner === null) {
|
|
60
112
|
pos++;
|
|
61
113
|
continue;
|
|
62
114
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
115
|
+
if (inner.tag === "script") {
|
|
116
|
+
const typeAttr = extractAttribute(inner.open.tagContent, "type");
|
|
117
|
+
if (typeAttr?.toLowerCase() === "module" && inner.closed) {
|
|
118
|
+
const contentStart = inner.open.end;
|
|
119
|
+
scriptBlocks.push({
|
|
120
|
+
contentStart,
|
|
121
|
+
contentEnd: inner.contentEnd,
|
|
122
|
+
content: html.slice(contentStart, inner.contentEnd),
|
|
123
|
+
mountPath,
|
|
124
|
+
bindComponent
|
|
125
|
+
});
|
|
126
|
+
}
|
|
67
127
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
128
|
+
if (!inner.closed) {
|
|
129
|
+
pos = len;
|
|
130
|
+
wcsCloseIdx = -1;
|
|
131
|
+
wcsEnd = len;
|
|
72
132
|
break;
|
|
73
133
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
mountPath
|
|
80
|
-
});
|
|
81
|
-
pos = html.indexOf(">", scriptCloseIdx) + 1;
|
|
82
|
-
if (pos === 0) break;
|
|
134
|
+
pos = afterCloseTag(html, inner.contentEnd);
|
|
135
|
+
if (pos > wcsEnd) {
|
|
136
|
+
wcsCloseIdx = findCloseTag(html, pos, stateTagName, lower2);
|
|
137
|
+
wcsEnd = wcsCloseIdx === -1 ? len : wcsCloseIdx;
|
|
138
|
+
}
|
|
83
139
|
}
|
|
140
|
+
elements.push({ mountPath, bindComponent, jsonAttr, stateAttr, srcAttr, scriptBlocks, tagStart, tagEnd });
|
|
84
141
|
pos = wcsEnd;
|
|
85
|
-
if (wcsCloseIdx !== -1)
|
|
86
|
-
const closeEnd = html.indexOf(">", wcsCloseIdx);
|
|
87
|
-
if (closeEnd !== -1) pos = closeEnd + 1;
|
|
88
|
-
}
|
|
142
|
+
if (wcsCloseIdx !== -1) pos = afterCloseTag(html, wcsCloseIdx);
|
|
89
143
|
}
|
|
90
|
-
return
|
|
144
|
+
return elements;
|
|
91
145
|
}
|
|
92
146
|
function matchOpenTag(html, pos, tagName) {
|
|
93
147
|
if (html[pos] !== "<") return null;
|
|
94
148
|
const nameStart = pos + 1;
|
|
95
149
|
const nameEnd = nameStart + tagName.length;
|
|
96
150
|
if (nameEnd > html.length) return null;
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
151
|
+
const slice2 = html.slice(nameStart, nameEnd);
|
|
152
|
+
if (asciiLowerCase(slice2) !== asciiLowerCase(tagName)) return null;
|
|
99
153
|
const charAfter = html[nameEnd];
|
|
100
154
|
if (charAfter !== ">" && charAfter !== " " && charAfter !== " " && charAfter !== "\n" && charAfter !== "\r" && charAfter !== "/") {
|
|
101
155
|
return null;
|
|
@@ -124,10 +178,10 @@ function matchOpenTag(html, pos, tagName) {
|
|
|
124
178
|
}
|
|
125
179
|
return null;
|
|
126
180
|
}
|
|
127
|
-
function findCloseTag(html, startPos, tagName) {
|
|
181
|
+
function findCloseTag(html, startPos, tagName, lower2 = asciiLowerCase(html)) {
|
|
128
182
|
const pattern = "</" + tagName;
|
|
129
|
-
const patternLower = pattern
|
|
130
|
-
const htmlLower =
|
|
183
|
+
const patternLower = asciiLowerCase(pattern);
|
|
184
|
+
const htmlLower = lower2;
|
|
131
185
|
let pos = startPos;
|
|
132
186
|
while (pos < html.length) {
|
|
133
187
|
const idx = htmlLower.indexOf(patternLower, pos);
|
|
@@ -143,6 +197,15 @@ function findCloseTag(html, startPos, tagName) {
|
|
|
143
197
|
}
|
|
144
198
|
return -1;
|
|
145
199
|
}
|
|
200
|
+
function parseAttributeNames(tagContent) {
|
|
201
|
+
const names = /* @__PURE__ */ new Set();
|
|
202
|
+
const attribute = /([^\s"'<>/=]+)(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'<>`=]+))?/g;
|
|
203
|
+
let match;
|
|
204
|
+
while ((match = attribute.exec(tagContent)) !== null) {
|
|
205
|
+
names.add(match[1].toLowerCase());
|
|
206
|
+
}
|
|
207
|
+
return names;
|
|
208
|
+
}
|
|
146
209
|
function extractAttribute(tagContent, attrName) {
|
|
147
210
|
const regex = new RegExp(
|
|
148
211
|
`(?:^|\\s)${attrName}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|(\\S+))`,
|
|
@@ -153,7 +216,556 @@ function extractAttribute(tagContent, attrName) {
|
|
|
153
216
|
return match[1] ?? match[2] ?? match[3] ?? null;
|
|
154
217
|
}
|
|
155
218
|
|
|
219
|
+
// ../state/dist/manifest.esm.js
|
|
220
|
+
var hooks = {};
|
|
221
|
+
function raiseError(message, subject, candidates) {
|
|
222
|
+
throw new Error(`[@wcstack/state] ${message}${hooks.explain?.(message, subject, candidates) ?? ""}`);
|
|
223
|
+
}
|
|
224
|
+
var CODES = [
|
|
225
|
+
"",
|
|
226
|
+
"binding-syntax",
|
|
227
|
+
"template-syntax",
|
|
228
|
+
"binding-path-missing",
|
|
229
|
+
"binding-type-expectation",
|
|
230
|
+
"filter-unknown",
|
|
231
|
+
"filter-arity",
|
|
232
|
+
"getter-cycle",
|
|
233
|
+
"getter-depth-exceeded",
|
|
234
|
+
"index-arity",
|
|
235
|
+
"index-param-range",
|
|
236
|
+
"recursion-unsupported",
|
|
237
|
+
"token-misconfigured",
|
|
238
|
+
"token-undeclared",
|
|
239
|
+
"wildcard-rank",
|
|
240
|
+
"spread-no-bindable",
|
|
241
|
+
"declaration-alias",
|
|
242
|
+
"name-alias"
|
|
243
|
+
];
|
|
244
|
+
var codeOf = (id) => {
|
|
245
|
+
const c = CODES[id / 100 | 0];
|
|
246
|
+
return c ? `[wcs/${c}] ` : "";
|
|
247
|
+
};
|
|
248
|
+
function text(id, args = []) {
|
|
249
|
+
return hooks.render?.(id, args) ?? `${codeOf(id)}#${id}${args.map((a) => ` ${typeof a === "string" ? JSON.stringify(a) : String(a)}`).join("")}`;
|
|
250
|
+
}
|
|
251
|
+
function raise(id, args, subject, candidates) {
|
|
252
|
+
raiseError(text(id, args), subject, candidates);
|
|
253
|
+
}
|
|
254
|
+
var config = {
|
|
255
|
+
bindAttributeName: "data-wcs",
|
|
256
|
+
commentForPrefix: "wcs-for",
|
|
257
|
+
commentIfPrefix: "wcs-if",
|
|
258
|
+
commentElseIfPrefix: "wcs-elseif",
|
|
259
|
+
commentElsePrefix: "wcs-else",
|
|
260
|
+
tagNames: { state: "wcs-state", ssr: "wcs-ssr" },
|
|
261
|
+
locale: typeof document !== "undefined" ? document.documentElement?.lang || "en" : "en",
|
|
262
|
+
enableContractAnalyzer: false
|
|
263
|
+
};
|
|
264
|
+
var FEATURE_NAMES = ["formats", "diagnostics", "temporal", "list-keys", "scopes", "recursion", "ssr", "devtools"];
|
|
265
|
+
var WILDCARD = "*";
|
|
266
|
+
function optionsRequired(fnName) {
|
|
267
|
+
raise(26, [fnName]);
|
|
268
|
+
}
|
|
269
|
+
function optionMustBeNumber(fnName) {
|
|
270
|
+
raise(27, [fnName]);
|
|
271
|
+
}
|
|
272
|
+
function valueMustBeNumber(fnName) {
|
|
273
|
+
raise(28, [fnName]);
|
|
274
|
+
}
|
|
275
|
+
function valueMustBeDate(fnName) {
|
|
276
|
+
raise(29, [fnName]);
|
|
277
|
+
}
|
|
278
|
+
function valueMustBeArray(fnName) {
|
|
279
|
+
raise(30, [fnName]);
|
|
280
|
+
}
|
|
281
|
+
function validateNumberString(value) {
|
|
282
|
+
if (!value || isNaN(Number(value))) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
function numberOption(value, fnName) {
|
|
288
|
+
if (!validateNumberString(value)) {
|
|
289
|
+
optionMustBeNumber(fnName);
|
|
290
|
+
}
|
|
291
|
+
return Number(value);
|
|
292
|
+
}
|
|
293
|
+
function requiredNumberOption(options, index, fnName) {
|
|
294
|
+
return numberOption(options?.[index] ?? optionsRequired(fnName), fnName);
|
|
295
|
+
}
|
|
296
|
+
function firstLiteral(opt, literals) {
|
|
297
|
+
return literals !== void 0 && literals.length > 0 ? literals[0] : opt;
|
|
298
|
+
}
|
|
299
|
+
var eq = (options, literals) => {
|
|
300
|
+
const opt = options?.[0] ?? optionsRequired("eq");
|
|
301
|
+
const literal = firstLiteral(opt, literals);
|
|
302
|
+
return (value) => {
|
|
303
|
+
if (typeof value === "number") {
|
|
304
|
+
if (typeof literal !== "string") {
|
|
305
|
+
return value === literal;
|
|
306
|
+
}
|
|
307
|
+
if (!validateNumberString(opt)) {
|
|
308
|
+
optionMustBeNumber("eq");
|
|
309
|
+
}
|
|
310
|
+
return value === Number(opt);
|
|
311
|
+
}
|
|
312
|
+
if (typeof value === "string") {
|
|
313
|
+
return value === opt;
|
|
314
|
+
}
|
|
315
|
+
return value === literal;
|
|
316
|
+
};
|
|
317
|
+
};
|
|
318
|
+
var ne = (options, literals) => {
|
|
319
|
+
const opt = options?.[0] ?? optionsRequired("ne");
|
|
320
|
+
const literal = firstLiteral(opt, literals);
|
|
321
|
+
return (value) => {
|
|
322
|
+
if (typeof value === "number") {
|
|
323
|
+
if (typeof literal !== "string") {
|
|
324
|
+
return value !== literal;
|
|
325
|
+
}
|
|
326
|
+
if (!validateNumberString(opt)) {
|
|
327
|
+
optionMustBeNumber("ne");
|
|
328
|
+
}
|
|
329
|
+
return value !== Number(opt);
|
|
330
|
+
}
|
|
331
|
+
if (typeof value === "string") {
|
|
332
|
+
return value !== opt;
|
|
333
|
+
}
|
|
334
|
+
return value !== literal;
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
var not = () => (value) => !value;
|
|
338
|
+
var numeric = (name, op) => ({
|
|
339
|
+
factory: (options) => {
|
|
340
|
+
const opt = requiredNumberOption(options, 0, name);
|
|
341
|
+
return (value) => {
|
|
342
|
+
if (typeof value !== "number") {
|
|
343
|
+
valueMustBeNumber(name);
|
|
344
|
+
}
|
|
345
|
+
return op(value, opt);
|
|
346
|
+
};
|
|
347
|
+
},
|
|
348
|
+
arity: [1, 1]
|
|
349
|
+
});
|
|
350
|
+
var truthy = () => (value) => !!value;
|
|
351
|
+
var falsy = () => (value) => !value;
|
|
352
|
+
var boolean = () => (value) => Boolean(value);
|
|
353
|
+
var abs = () => (value) => {
|
|
354
|
+
if (typeof value !== "number") {
|
|
355
|
+
valueMustBeNumber("abs");
|
|
356
|
+
}
|
|
357
|
+
return Math.abs(value);
|
|
358
|
+
};
|
|
359
|
+
var clamp = (options) => {
|
|
360
|
+
const min = requiredNumberOption(options, 0, "clamp");
|
|
361
|
+
const max = requiredNumberOption(options, 1, "clamp");
|
|
362
|
+
return (value) => {
|
|
363
|
+
if (typeof value !== "number") {
|
|
364
|
+
valueMustBeNumber("clamp");
|
|
365
|
+
}
|
|
366
|
+
return Math.min(Math.max(value, min), max);
|
|
367
|
+
};
|
|
368
|
+
};
|
|
369
|
+
var number = () => (value) => Number(value);
|
|
370
|
+
var string = () => (value) => String(value);
|
|
371
|
+
var int = () => (value) => parseInt(String(value), 10);
|
|
372
|
+
var float = () => (value) => parseFloat(String(value));
|
|
373
|
+
var defaults = (options, literals) => {
|
|
374
|
+
const opt = options?.[0] ?? optionsRequired("defaults");
|
|
375
|
+
const fallback = firstLiteral(opt, literals);
|
|
376
|
+
return (value) => {
|
|
377
|
+
if (!value) {
|
|
378
|
+
return fallback;
|
|
379
|
+
}
|
|
380
|
+
return value;
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
var coalesce = (options, literals) => {
|
|
384
|
+
const opt = options?.[0] ?? optionsRequired("coalesce");
|
|
385
|
+
const fallback = firstLiteral(opt, literals);
|
|
386
|
+
return (value) => value ?? fallback;
|
|
387
|
+
};
|
|
388
|
+
var nullIfEmpty = () => (value) => value === "" ? null : value;
|
|
389
|
+
var coreFilters = {
|
|
390
|
+
eq: { factory: eq, arity: [1, 1] },
|
|
391
|
+
ne: { factory: ne, arity: [1, 1] },
|
|
392
|
+
not: { factory: not, arity: [0, 0] },
|
|
393
|
+
lt: numeric("lt", (value, opt) => value < opt),
|
|
394
|
+
le: numeric("le", (value, opt) => value <= opt),
|
|
395
|
+
gt: numeric("gt", (value, opt) => value > opt),
|
|
396
|
+
ge: numeric("ge", (value, opt) => value >= opt),
|
|
397
|
+
add: numeric("add", (value, opt) => value + opt),
|
|
398
|
+
sub: numeric("sub", (value, opt) => value - opt),
|
|
399
|
+
mul: numeric("mul", (value, opt) => value * opt),
|
|
400
|
+
div: numeric("div", (value, opt) => value / opt),
|
|
401
|
+
mod: numeric("mod", (value, opt) => value % opt),
|
|
402
|
+
abs: { factory: abs, arity: [0, 0] },
|
|
403
|
+
clamp: { factory: clamp, arity: [2, 2] },
|
|
404
|
+
int: { factory: int, arity: [0, 0] },
|
|
405
|
+
float: { factory: float, arity: [0, 0] },
|
|
406
|
+
falsy: { factory: falsy, arity: [0, 0] },
|
|
407
|
+
truthy: { factory: truthy, arity: [0, 0] },
|
|
408
|
+
defaults: { factory: defaults, arity: [1, 1] },
|
|
409
|
+
coalesce: { factory: coalesce, arity: [1, 1] },
|
|
410
|
+
boolean: { factory: boolean, arity: [0, 0] },
|
|
411
|
+
number: { factory: number, arity: [0, 0] },
|
|
412
|
+
string: { factory: string, arity: [0, 0] },
|
|
413
|
+
nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] }
|
|
414
|
+
};
|
|
415
|
+
var nullishPassthrough = (factory) => (options) => {
|
|
416
|
+
const filterFn = factory(options);
|
|
417
|
+
return (value) => value == null ? value : filterFn(value);
|
|
418
|
+
};
|
|
419
|
+
var toFixed = (options) => {
|
|
420
|
+
const opt = numberOption(options?.[0] ?? "0", "toFixed");
|
|
421
|
+
return (value) => {
|
|
422
|
+
if (typeof value !== "number") {
|
|
423
|
+
valueMustBeNumber("toFixed");
|
|
424
|
+
}
|
|
425
|
+
return value.toFixed(opt);
|
|
426
|
+
};
|
|
427
|
+
};
|
|
428
|
+
var round = (options) => {
|
|
429
|
+
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "round"));
|
|
430
|
+
return (value) => {
|
|
431
|
+
if (typeof value !== "number") {
|
|
432
|
+
valueMustBeNumber("round");
|
|
433
|
+
}
|
|
434
|
+
return Math.round(value * optValue) / optValue;
|
|
435
|
+
};
|
|
436
|
+
};
|
|
437
|
+
var floor = (options) => {
|
|
438
|
+
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "floor"));
|
|
439
|
+
return (value) => {
|
|
440
|
+
if (typeof value !== "number") {
|
|
441
|
+
valueMustBeNumber("floor");
|
|
442
|
+
}
|
|
443
|
+
return Math.floor(value * optValue) / optValue;
|
|
444
|
+
};
|
|
445
|
+
};
|
|
446
|
+
var ceil = (options) => {
|
|
447
|
+
const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "ceil"));
|
|
448
|
+
return (value) => {
|
|
449
|
+
if (typeof value !== "number") {
|
|
450
|
+
valueMustBeNumber("ceil");
|
|
451
|
+
}
|
|
452
|
+
return Math.ceil(value * optValue) / optValue;
|
|
453
|
+
};
|
|
454
|
+
};
|
|
455
|
+
var percent = (options) => {
|
|
456
|
+
const opt = numberOption(options?.[0] ?? "0", "percent");
|
|
457
|
+
return (value) => {
|
|
458
|
+
if (typeof value !== "number") {
|
|
459
|
+
valueMustBeNumber("percent");
|
|
460
|
+
}
|
|
461
|
+
return `${(value * 100).toFixed(opt)}%`;
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
var unit = (options) => {
|
|
465
|
+
const opt = options?.[0] ?? optionsRequired("unit");
|
|
466
|
+
return (value) => String(value) + opt;
|
|
467
|
+
};
|
|
468
|
+
var seen;
|
|
469
|
+
var valid = "en";
|
|
470
|
+
function defaultLocale() {
|
|
471
|
+
if (config.locale !== seen) {
|
|
472
|
+
seen = config.locale;
|
|
473
|
+
try {
|
|
474
|
+
valid = Intl.getCanonicalLocales(seen)[0];
|
|
475
|
+
} catch {
|
|
476
|
+
console.warn(`[@wcstack/state] ${text(48, [seen])}`);
|
|
477
|
+
valid = "en";
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return valid;
|
|
481
|
+
}
|
|
482
|
+
var locale = (options) => {
|
|
483
|
+
const explicit = options?.[0];
|
|
484
|
+
return (value) => {
|
|
485
|
+
if (typeof value !== "number") {
|
|
486
|
+
valueMustBeNumber("locale");
|
|
487
|
+
}
|
|
488
|
+
return value.toLocaleString(explicit ?? defaultLocale());
|
|
489
|
+
};
|
|
490
|
+
};
|
|
491
|
+
var upper = () => (value) => String(value).toUpperCase();
|
|
492
|
+
var lower = () => (value) => String(value).toLowerCase();
|
|
493
|
+
var capitalize = () => (value) => {
|
|
494
|
+
const v = String(value);
|
|
495
|
+
if (v.length === 0) {
|
|
496
|
+
return v;
|
|
497
|
+
}
|
|
498
|
+
if (v.length === 1) {
|
|
499
|
+
return v.toUpperCase();
|
|
500
|
+
}
|
|
501
|
+
return v.charAt(0).toUpperCase() + v.slice(1);
|
|
502
|
+
};
|
|
503
|
+
var trim = () => (value) => String(value).trim();
|
|
504
|
+
var slice = (options) => {
|
|
505
|
+
const numberedOpts = [requiredNumberOption(options, 0, "slice")];
|
|
506
|
+
const opt2 = options?.[1];
|
|
507
|
+
if (typeof opt2 !== "undefined") {
|
|
508
|
+
numberedOpts.push(numberOption(opt2, "slice"));
|
|
509
|
+
}
|
|
510
|
+
return (value) => String(value).slice(...numberedOpts);
|
|
511
|
+
};
|
|
512
|
+
var padStart = (options) => {
|
|
513
|
+
const opt1 = requiredNumberOption(options, 0, "padStart");
|
|
514
|
+
const opt2 = options?.[1] ?? "0";
|
|
515
|
+
return (value) => String(value).padStart(opt1, opt2);
|
|
516
|
+
};
|
|
517
|
+
var padEnd = (options) => {
|
|
518
|
+
const opt1 = requiredNumberOption(options, 0, "padEnd");
|
|
519
|
+
const opt2 = options?.[1] ?? " ";
|
|
520
|
+
return (value) => String(value).padEnd(opt1, opt2);
|
|
521
|
+
};
|
|
522
|
+
var repeat = (options) => {
|
|
523
|
+
const opt = requiredNumberOption(options, 0, "repeat");
|
|
524
|
+
return (value) => String(value).repeat(opt);
|
|
525
|
+
};
|
|
526
|
+
var reverse = () => (value) => String(value).split("").reverse().join("");
|
|
527
|
+
var truncate = (options) => {
|
|
528
|
+
const maxLength = requiredNumberOption(options, 0, "truncate");
|
|
529
|
+
const suffix = options?.[1] ?? "\u2026";
|
|
530
|
+
return (value) => {
|
|
531
|
+
const v = String(value);
|
|
532
|
+
if (v.length <= maxLength) {
|
|
533
|
+
return v;
|
|
534
|
+
}
|
|
535
|
+
return v.slice(0, maxLength) + suffix;
|
|
536
|
+
};
|
|
537
|
+
};
|
|
538
|
+
var join = (options) => {
|
|
539
|
+
const opt = options?.[0] ?? ", ";
|
|
540
|
+
return (value) => {
|
|
541
|
+
if (!Array.isArray(value)) {
|
|
542
|
+
valueMustBeArray("join");
|
|
543
|
+
}
|
|
544
|
+
return value.join(opt);
|
|
545
|
+
};
|
|
546
|
+
};
|
|
547
|
+
var date = (options) => {
|
|
548
|
+
const explicit = options?.[0];
|
|
549
|
+
return (value) => {
|
|
550
|
+
if (!(value instanceof Date)) {
|
|
551
|
+
valueMustBeDate("date");
|
|
552
|
+
}
|
|
553
|
+
return value.toLocaleDateString(explicit ?? defaultLocale());
|
|
554
|
+
};
|
|
555
|
+
};
|
|
556
|
+
var time = (options) => {
|
|
557
|
+
const explicit = options?.[0];
|
|
558
|
+
return (value) => {
|
|
559
|
+
if (!(value instanceof Date)) {
|
|
560
|
+
valueMustBeDate("time");
|
|
561
|
+
}
|
|
562
|
+
return value.toLocaleTimeString(explicit ?? defaultLocale());
|
|
563
|
+
};
|
|
564
|
+
};
|
|
565
|
+
var datetime = (options) => {
|
|
566
|
+
const explicit = options?.[0];
|
|
567
|
+
return (value) => {
|
|
568
|
+
if (!(value instanceof Date)) {
|
|
569
|
+
valueMustBeDate("datetime");
|
|
570
|
+
}
|
|
571
|
+
return value.toLocaleString(explicit ?? defaultLocale());
|
|
572
|
+
};
|
|
573
|
+
};
|
|
574
|
+
var ymd = (options) => {
|
|
575
|
+
const opt = options?.[0] ?? "-";
|
|
576
|
+
return (value) => {
|
|
577
|
+
if (!(value instanceof Date)) {
|
|
578
|
+
valueMustBeDate("ymd");
|
|
579
|
+
}
|
|
580
|
+
const year = value.getFullYear().toString();
|
|
581
|
+
const month = (value.getMonth() + 1).toString().padStart(2, "0");
|
|
582
|
+
const day = value.getDate().toString().padStart(2, "0");
|
|
583
|
+
return `${year}${opt}${month}${opt}${day}`;
|
|
584
|
+
};
|
|
585
|
+
};
|
|
586
|
+
var hms = (options) => {
|
|
587
|
+
const opt = options?.[0] ?? ":";
|
|
588
|
+
return (value) => {
|
|
589
|
+
if (!(value instanceof Date)) {
|
|
590
|
+
valueMustBeDate("hms");
|
|
591
|
+
}
|
|
592
|
+
const hours = value.getHours().toString().padStart(2, "0");
|
|
593
|
+
const minutes = value.getMinutes().toString().padStart(2, "0");
|
|
594
|
+
const seconds = value.getSeconds().toString().padStart(2, "0");
|
|
595
|
+
return `${hours}${opt}${minutes}${opt}${seconds}`;
|
|
596
|
+
};
|
|
597
|
+
};
|
|
598
|
+
var formatFilters = {
|
|
599
|
+
toFixed: { factory: toFixed, arity: [0, 1] },
|
|
600
|
+
locale: { factory: locale, arity: [0, 1] },
|
|
601
|
+
// The `String(value)` family passes an absent value through (B8 — see nullishPassthrough)
|
|
602
|
+
upper: { factory: nullishPassthrough(upper), arity: [0, 0] },
|
|
603
|
+
lower: { factory: nullishPassthrough(lower), arity: [0, 0] },
|
|
604
|
+
capitalize: { factory: nullishPassthrough(capitalize), arity: [0, 0] },
|
|
605
|
+
trim: { factory: nullishPassthrough(trim), arity: [0, 0] },
|
|
606
|
+
slice: { factory: nullishPassthrough(slice), arity: [1, 2] },
|
|
607
|
+
// The length is required too (the implementation reads both)
|
|
608
|
+
padStart: { factory: nullishPassthrough(padStart), arity: [1, 2] },
|
|
609
|
+
padEnd: { factory: nullishPassthrough(padEnd), arity: [1, 2] },
|
|
610
|
+
repeat: { factory: nullishPassthrough(repeat), arity: [1, 1] },
|
|
611
|
+
reverse: { factory: nullishPassthrough(reverse), arity: [0, 0] },
|
|
612
|
+
truncate: { factory: nullishPassthrough(truncate), arity: [1, 2] },
|
|
613
|
+
join: { factory: join, arity: [0, 1] },
|
|
614
|
+
round: { factory: round, arity: [0, 1] },
|
|
615
|
+
floor: { factory: floor, arity: [0, 1] },
|
|
616
|
+
ceil: { factory: ceil, arity: [0, 1] },
|
|
617
|
+
percent: { factory: percent, arity: [0, 1] },
|
|
618
|
+
unit: { factory: nullishPassthrough(unit), arity: [1, 1] },
|
|
619
|
+
// The locale-dependent three take a locale like `locale` does (`date(ja-JP)`)
|
|
620
|
+
date: { factory: date, arity: [0, 1] },
|
|
621
|
+
time: { factory: time, arity: [0, 1] },
|
|
622
|
+
datetime: { factory: datetime, arity: [0, 1] },
|
|
623
|
+
ymd: { factory: ymd, arity: [0, 1] },
|
|
624
|
+
hms: { factory: hms, arity: [0, 1] }
|
|
625
|
+
};
|
|
626
|
+
var STRUCTURAL_BINDING_TYPE_SET = /* @__PURE__ */ new Set([
|
|
627
|
+
"if",
|
|
628
|
+
"elseif",
|
|
629
|
+
"else",
|
|
630
|
+
"for"
|
|
631
|
+
]);
|
|
632
|
+
var DELIMITER = ".";
|
|
633
|
+
var BINDING_SEPARATOR = ";";
|
|
634
|
+
var PROP_VALUE_SEPARATOR = ":";
|
|
635
|
+
var MODIFIER_SEPARATOR = "#";
|
|
636
|
+
var FILTER_SEPARATOR = "|";
|
|
637
|
+
var ELSE_KEYWORD = "else";
|
|
638
|
+
var SPREAD_PROP = "...";
|
|
639
|
+
var EVENT_PROP_PREFIX = "on";
|
|
640
|
+
var EVENT_TOKEN_NAMESPACE = "eventToken";
|
|
641
|
+
var COMMAND_NAMESPACE = "command";
|
|
642
|
+
var CLASS_NAMESPACE = "class";
|
|
643
|
+
var ATTR_NAMESPACE = "attr";
|
|
644
|
+
var STYLE_NAMESPACE = "style";
|
|
645
|
+
var MAX_INDEX_PARAM = 128;
|
|
646
|
+
var builtinFilterMeta = {
|
|
647
|
+
// 比較・論理
|
|
648
|
+
eq: { description: "\u7B49\u3057\u3044\u304B\u6BD4\u8F03", hasArgs: true, resultType: "boolean", acceptTypes: "any", minArgs: 1, maxArgs: 1, argTypes: ["any"] },
|
|
649
|
+
ne: { description: "\u7570\u306A\u308B\u304B\u6BD4\u8F03", hasArgs: true, resultType: "boolean", acceptTypes: "any", minArgs: 1, maxArgs: 1, argTypes: ["any"] },
|
|
650
|
+
// `not` は真偽性(truthy / falsy)の反転。`if:` が `Boolean()` で寄せるのと同じ規則で、
|
|
651
|
+
// `else:` はこのフィルタを足した束縛として組み立てられる(structural/createNotFilter.ts)
|
|
652
|
+
not: { description: "\u771F\u507D\u6027\u3092\u53CD\u8EE2\uFF08falsy \u2192 true\uFF09", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
653
|
+
lt: { description: "\u3088\u308A\u5C0F\u3055\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
654
|
+
le: { description: "\u4EE5\u4E0B\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
655
|
+
gt: { description: "\u3088\u308A\u5927\u304D\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
656
|
+
ge: { description: "\u4EE5\u4E0A\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
657
|
+
// 算術
|
|
658
|
+
add: { description: "\u52A0\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
659
|
+
sub: { description: "\u6E1B\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
660
|
+
mul: { description: "\u4E57\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
661
|
+
div: { description: "\u9664\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
662
|
+
mod: { description: "\u5270\u4F59", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
663
|
+
abs: { description: "\u7D76\u5BFE\u5024", hasArgs: false, resultType: "number", acceptTypes: ["number"], minArgs: 0, maxArgs: 0 },
|
|
664
|
+
clamp: { description: "\u7BC4\u56F2\u5185\u306B\u4E38\u3081\u308B (min,max)", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 2, maxArgs: 2, argTypes: ["number", "number"] },
|
|
665
|
+
// 数値フォーマット
|
|
666
|
+
toFixed: { description: "\u56FA\u5B9A\u5C0F\u6570\u70B9\u8868\u8A18", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["number"] },
|
|
667
|
+
locale: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u3067\u6570\u5024\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
668
|
+
// 文字列
|
|
669
|
+
upper: { description: "\u5927\u6587\u5B57\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
670
|
+
lower: { description: "\u5C0F\u6587\u5B57\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
671
|
+
capitalize: { description: "\u5148\u982D\u6587\u5B57\u3092\u5927\u6587\u5B57\u306B", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
672
|
+
trim: { description: "\u524D\u5F8C\u306E\u7A7A\u767D\u3092\u524A\u9664", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
673
|
+
slice: { description: "\u90E8\u5206\u6587\u5B57\u5217 (start[,end])", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "number"] },
|
|
674
|
+
padStart: { description: "\u5148\u982D\u3092\u57CB\u3081\u308B (length[,char]\u3002char \u306E\u65E2\u5B9A\u306F 0 \u2014 JS \u306E\u65E2\u5B9A\u306F\u7A7A\u767D\u306A\u306E\u3067\u6CE8\u610F)", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "string"] },
|
|
675
|
+
padEnd: { description: "\u672B\u5C3E\u3092\u57CB\u3081\u308B (length[,char]\u3002char \u306E\u65E2\u5B9A\u306F\u7A7A\u767D \u2014 JS \u3068\u540C\u3058)", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "string"] },
|
|
676
|
+
repeat: { description: "\u7E70\u308A\u8FD4\u3057 (count)", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
|
|
677
|
+
reverse: { description: "\u6587\u5B57\u9806\u3092\u53CD\u8EE2", hasArgs: false, resultType: "string", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
|
|
678
|
+
truncate: { description: "\u5207\u308A\u8A70\u3081\u3066\u7701\u7565\u8A18\u53F7 (length[,suffix]\u3002suffix \u306E\u65E2\u5B9A\u306F \u2026 \u2014 U+2026 \u306E 1 \u6587\u5B57)", hasArgs: true, resultType: "string", acceptTypes: ["string"], minArgs: 1, maxArgs: 2, argTypes: ["number", "string"] },
|
|
679
|
+
join: { description: "\u914D\u5217\u3092\u9023\u7D50 ([separator]\u3002\u65E2\u5B9A\u306F\u30AB\u30F3\u30DE + \u7A7A\u767D)", hasArgs: true, resultType: "string", acceptTypes: ["array"], minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
680
|
+
// 数値パース・丸め
|
|
681
|
+
int: { description: "\u6574\u6570\u306B\u30D1\u30FC\u30B9", hasArgs: false, resultType: "number", acceptTypes: ["string", "number"], minArgs: 0, maxArgs: 0 },
|
|
682
|
+
float: { description: "\u6D6E\u52D5\u5C0F\u6570\u70B9\u6570\u306B\u30D1\u30FC\u30B9", hasArgs: false, resultType: "number", acceptTypes: ["string", "number"], minArgs: 0, maxArgs: 0 },
|
|
683
|
+
round: { description: "\u56DB\u6368\u4E94\u5165", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["number"] },
|
|
684
|
+
floor: { description: "\u5207\u308A\u4E0B\u3052", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["number"] },
|
|
685
|
+
ceil: { description: "\u5207\u308A\u4E0A\u3052", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["number"] },
|
|
686
|
+
percent: { description: "\u30D1\u30FC\u30BB\u30F3\u30C6\u30FC\u30B8\u5F62\u5F0F", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 0, maxArgs: 1, argTypes: ["number"] },
|
|
687
|
+
// number だけでなく string も受ける。実用チェーンは fix / percent の後ろに繋がり、
|
|
688
|
+
// それらは既に string を返すため(builtinFilters.ts の unit を参照)
|
|
689
|
+
unit: { description: "\u5358\u4F4D\uFF08\u63A5\u5C3E\u8F9E\uFF09\u3092\u4ED8\u52A0", hasArgs: true, resultType: "string", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["string"] },
|
|
690
|
+
// 日付・時刻
|
|
691
|
+
// `locale` と同じくロケールを 1 つ受ける(`date(ja-JP)`)。実装は最初からこれを読んでいたが、
|
|
692
|
+
// メタデータ側が maxArgs: 0 だったため lint と補完が正しい書き方を誤りとして報告していた
|
|
693
|
+
date: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u65E5\u4ED8 ([locale]\u3002\u65E2\u5B9A\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
694
|
+
time: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u6642\u523B ([locale]\u3002\u65E2\u5B9A\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
695
|
+
datetime: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u65E5\u6642 ([locale]\u3002\u65E2\u5B9A\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
696
|
+
ymd: { description: "YYYY-MM-DD \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F -)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
697
|
+
hms: { description: "HH:MM:SS \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F :)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
|
|
698
|
+
// 真偽値・変換
|
|
699
|
+
falsy: { description: "\u507D\u5024\u304B\u5224\u5B9A", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
700
|
+
truthy: { description: "\u771F\u5024\u304B\u5224\u5B9A", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
701
|
+
defaults: { description: "\u507D\u5024\u306E\u5834\u5408\u30C7\u30D5\u30A9\u30EB\u30C8\u5024", hasArgs: true, resultType: "passthrough", acceptTypes: "any", minArgs: 1, maxArgs: 1, argTypes: ["any"] },
|
|
702
|
+
coalesce: { description: "null / undefined \u306E\u5834\u5408\u30C7\u30D5\u30A9\u30EB\u30C8\u5024", hasArgs: true, resultType: "passthrough", acceptTypes: "any", minArgs: 1, maxArgs: 1, argTypes: ["any"] },
|
|
703
|
+
boolean: { description: "\u30D6\u30FC\u30EB\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
704
|
+
number: { description: "\u6570\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "number", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
705
|
+
string: { description: "\u6587\u5B57\u5217\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
|
|
706
|
+
nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 }
|
|
707
|
+
};
|
|
708
|
+
var WCS_MANIFEST_VERSION = 2;
|
|
709
|
+
var builtinFilterAliases = Object.freeze({});
|
|
710
|
+
var DECLARATION_ALIASES = Object.freeze({});
|
|
711
|
+
var STATE_API_ALIASES = Object.freeze({});
|
|
712
|
+
var MODIFIER_FLAGS = Object.freeze(["prevent", "stop", "ro", "direct"]);
|
|
713
|
+
var MODIFIER_KEYS = Object.freeze(["init", "sync"]);
|
|
714
|
+
var INDEX_PARAM_PREFIX = "$";
|
|
715
|
+
var BEHAVIOR_OPTION_KEYS = ["enableMustache", "sameValueGuard", "enableDirectionalInitialSync"];
|
|
716
|
+
function getWcsManifest() {
|
|
717
|
+
return {
|
|
718
|
+
version: WCS_MANIFEST_VERSION,
|
|
719
|
+
syntax: {
|
|
720
|
+
bindAttribute: config.bindAttributeName,
|
|
721
|
+
tagName: config.tagNames.state,
|
|
722
|
+
pathDelimiter: DELIMITER,
|
|
723
|
+
wildcard: WILDCARD,
|
|
724
|
+
delimiters: { binding: BINDING_SEPARATOR, propValue: PROP_VALUE_SEPARATOR, modifier: MODIFIER_SEPARATOR, filter: FILTER_SEPARATOR },
|
|
725
|
+
structuralDirectives: Array.from(STRUCTURAL_BINDING_TYPE_SET),
|
|
726
|
+
modifiers: { flags: MODIFIER_FLAGS, keyValue: MODIFIER_KEYS, eventNamePrefix: EVENT_PROP_PREFIX },
|
|
727
|
+
indexParam: { prefix: INDEX_PARAM_PREFIX, maxDepth: MAX_INDEX_PARAM },
|
|
728
|
+
bindingTypes: {
|
|
729
|
+
elseKeyword: ELSE_KEYWORD,
|
|
730
|
+
spread: SPREAD_PROP,
|
|
731
|
+
eventPropertyPrefix: EVENT_PROP_PREFIX,
|
|
732
|
+
explicitPropertyPrefix: DELIMITER,
|
|
733
|
+
propNamespaces: { eventToken: EVENT_TOKEN_NAMESPACE, command: COMMAND_NAMESPACE, class: CLASS_NAMESPACE, attr: ATTR_NAMESPACE, style: STYLE_NAMESPACE }
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
// quoted: `filters` is an internal name the bundles shorten (mangle.mjs)
|
|
737
|
+
"filters": [...Object.keys(coreFilters), ...Object.keys(formatFilters)],
|
|
738
|
+
filterMeta: builtinFilterMeta,
|
|
739
|
+
filterAliases: builtinFilterAliases,
|
|
740
|
+
declarationAliases: DECLARATION_ALIASES,
|
|
741
|
+
apiAliases: STATE_API_ALIASES,
|
|
742
|
+
reservedLifecycle: ["$connectedCallback", "$disconnectedCallback", "$renderedCallback", "$errorCallback", "$stateReadyCallback"],
|
|
743
|
+
reservedStateApi: [
|
|
744
|
+
"$bindables",
|
|
745
|
+
"$commands",
|
|
746
|
+
"$commandTokens",
|
|
747
|
+
"$command",
|
|
748
|
+
"$eventTokens",
|
|
749
|
+
"$on",
|
|
750
|
+
"$stream",
|
|
751
|
+
"$watch",
|
|
752
|
+
"$listKeys",
|
|
753
|
+
"$recursion",
|
|
754
|
+
"$streamStatus",
|
|
755
|
+
"$streamError",
|
|
756
|
+
"$behavior",
|
|
757
|
+
"$features"
|
|
758
|
+
],
|
|
759
|
+
// every option is a boolean, true when left out (engine.ts `loadTarget`: `typeof … === "boolean"`, `?? true`)
|
|
760
|
+
behaviorOptions: Object.fromEntries(BEHAVIOR_OPTION_KEYS.map((key) => [key, { type: "boolean", default: true }])),
|
|
761
|
+
features: [...FEATURE_NAMES]
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
|
|
156
765
|
// src/language/preamble.ts
|
|
766
|
+
var manifest = getWcsManifest();
|
|
767
|
+
var BEHAVIOR_TYPE = `{ ${Object.entries(manifest.behaviorOptions).map(([key, option]) => `${key}?: ${option.type}`).join("; ")} }`;
|
|
768
|
+
var FEATURE_NAME_TYPE = manifest.features.map((name) => JSON.stringify(name)).join(" | ");
|
|
157
769
|
var WCS_PREAMBLE = `
|
|
158
770
|
// --- @wcstack/state type preamble (auto-injected by vscode-wcs) ---
|
|
159
771
|
type _IsAny<T> = 0 extends (1 & T) ? true : false;
|
|
@@ -206,10 +818,6 @@ interface WcsStateApi {
|
|
|
206
818
|
$resolve(path: string, indexes: number[], value?: any): any;
|
|
207
819
|
$dependOn(path: string): void;
|
|
208
820
|
$untracked<T>(fn: () => T): T;
|
|
209
|
-
/** @deprecated $dependOn \u306E\u65E7\u540D\uFF08@wcstack/state 3.2 \u2014 4.0 \u3067\u524A\u9664\u3055\u308C\u308B / removed in 4.0\uFF09 */
|
|
210
|
-
$trackDependency(path: string): void;
|
|
211
|
-
/** @deprecated $untracked \u306E\u65E7\u540D\uFF08@wcstack/state 3.2 \u2014 4.0 \u3067\u524A\u9664\u3055\u308C\u308B / removed in 4.0\uFF09 */
|
|
212
|
-
$untrackDependency<T>(fn: () => T): T;
|
|
213
821
|
$eq(path: string, key: unknown): boolean;
|
|
214
822
|
$eqPath(path: string, keyPath: string): boolean;
|
|
215
823
|
$eqIndex(path: string, level?: number): boolean;
|
|
@@ -231,14 +839,12 @@ interface WcsStateApi {
|
|
|
231
839
|
// \u672B\u5C3E\u304C \`.**\` \u306E\u30AD\u30FC\u306B\u3082\u540C\u3058\u7D22\u5F15\u3092\u7F6E\u304F\uFF08@wcstack/state \u306E defineState \u3068\u5BFE\uFF09\u3002
|
|
232
840
|
readonly [key: \`\${string}.**\`]: any;
|
|
233
841
|
}
|
|
234
|
-
// $
|
|
235
|
-
// \
|
|
236
|
-
//
|
|
842
|
+
// $stream \u306E\u5024\u306F\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u304C\u5BA3\u8A00\u30AD\u30FC\u306E\u540D\u524D\u3067\u5B9F\u4F53\u5316\u3059\u308B\u30D7\u30ED\u30D1\u30C6\u30A3\u3002T \u306B\u306F\u5BA3\u8A00\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u4E2D\u306B\u3057\u304B
|
|
843
|
+
// \u73FE\u308C\u306A\u3044\u306E\u3067\u3001getter \u3084\u30E1\u30BD\u30C3\u30C9\u306E this \u304B\u3089\u8AAD\u3081\u308B\u3088\u3046 any \u3067\u5199\u3059\u3002initial \u306E\u578B\u306F\u4F7F\u308F\u306A\u3044 \u2014 \u7A7A\u914D\u5217\u306E
|
|
844
|
+
// initial \u304C never[] \u306B\u306A\u308A\u3001\u6B63\u3057\u3044\u8AAD\u307F\uFF08\u8981\u7D20\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\uFF09\u307E\u3067\u578B\u30A8\u30E9\u30FC\u306B\u306A\u308B\u305F\u3081\u3002
|
|
237
845
|
// T \u306B\u540C\u540D\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u660E\u793A\u7684\u306B\u4E8B\u524D\u5BA3\u8A00\u3057\u3066\u3044\u308C\u3070\u5199\u3055\u306A\u3044\uFF08\u4EA4\u5DEE\u3067\u305D\u306E\u578B\u307E\u3067 any \u306B\u6F70\u3055\u306A\u3044\u305F\u3081\uFF09\u3002
|
|
238
846
|
type _WcsDeclaredValues<T> =
|
|
239
|
-
(T extends { $
|
|
240
|
-
(T extends { $stream: infer S } ? { [K in Exclude<keyof S & string, keyof T>]: any } : {}) &
|
|
241
|
-
(T extends { $streams: infer S } ? { [K in Exclude<keyof S & string, keyof T>]: any } : {});
|
|
847
|
+
(T extends { $stream: infer S } ? { [K in Exclude<keyof S & string, keyof T>]: any } : {});
|
|
242
848
|
type _WcsThis<T> = T & WcsStateApi & _WcsPathAccessor<T> & _WcsDeclaredValues<T>;
|
|
243
849
|
// $listKeys: { "<listPath>": "<field>" | (row) => key }\uFF08list/listKeys.ts\uFF09\u3002
|
|
244
850
|
// \u30AD\u30FC\u6307\u5B9A\u306E\u95A2\u6570\u5F15\u6570\u306B\u6587\u8108\u578B\u3092\u4E0E\u3048\u308B\u305F\u3081\u3060\u3051\u306E\u5BA3\u8A00\uFF08noImplicitAny \u4E0B\u306E\u507D\u30A8\u30E9\u30FC\u56DE\u907F\uFF09\u3002
|
|
@@ -247,23 +853,20 @@ type _WcsListKeys = Record<string, string | ((row: any) => unknown)>;
|
|
|
247
853
|
// \u30CF\u30F3\u30C9\u30E9\u5F15\u6570\u306B\u6587\u8108\u578B\u3092\u4E0E\u3048\u308B\u305F\u3081\u3060\u3051\u306E\u5BA3\u8A00\uFF08$listKeys \u3068\u540C\u3058\u7406\u7531\uFF09\u3002
|
|
248
854
|
// this \u306F ThisType<_WcsThis<T>> \u306B\u3088\u308A state \u578B\u306B\u306A\u308B\u3002
|
|
249
855
|
type _WcsWatch = Record<string, (cur: any, prev: any, ...indexes: number[]) => void>;
|
|
250
|
-
// $scan: { "<output>": { from | on, initial, fold, resetOn? } }\uFF08scan/processScanDeclaration.ts\uFF09\u3002
|
|
251
|
-
// fold \u306E\u5F15\u6570\u306B\u6587\u8108\u578B\u3092\u4E0E\u3048\u308B\u305F\u3081\u3060\u3051\u306E\u5BA3\u8A00\u3002from \u3068 on \u3067\u7B2C 2 \u5F15\u6570\u306E\u610F\u5473\u304C\u5909\u308F\u308B\uFF08cur \u304B event\uFF09\u306E\u3067
|
|
252
|
-
// \u5F15\u6570\u306F any \u306B\u5012\u3059\u3002fold \u306B this \u306F\u6E21\u3089\u306A\u3044\uFF08\u30E9\u30F3\u30BF\u30A4\u30E0\u306F this \u7121\u3057\u3067\u547C\u3076\uFF09\u306E\u3067 this: void \u3068\u66F8\u304F \u2014
|
|
253
|
-
// \u66F8\u304B\u306A\u3044\u3068 defineState \u306E ThisType \u304C\u30E1\u30BD\u30C3\u30C9\u5F62\u306E fold \u306B\u3082 state \u578B\u306E this \u3092\u4E0E\u3048\u3066\u3057\u307E\u3046\u3002
|
|
254
|
-
type _WcsScan = Record<string, {
|
|
255
|
-
from?: string;
|
|
256
|
-
on?: string;
|
|
257
|
-
initial: any;
|
|
258
|
-
fold: (this: void, acc: any, ...args: any[]) => any;
|
|
259
|
-
resetOn?: string[];
|
|
260
|
-
}>;
|
|
261
856
|
// $recursion: { "<anchor>": "<repeat>" }\uFF08recursion/declaration.ts\uFF09\u3002\u521D\u7248\u306F\u5358\u4E00\u306E\u81EA\u5DF1\u518D\u5E30
|
|
262
857
|
// \u306E\u307F\u3067\u3001\u30A2\u30F3\u30AB\u30FC\u3082\u53CD\u5FA9\u30B5\u30D6\u30D1\u30B9\u3082\u300C\u56FA\u5B9A\u30D7\u30ED\u30D1\u30C6\u30A3\u5217 + \u672B\u5C3E\u306E .*\u300D\u306B\u9650\u308B\u3002\u5F62\u306E\u691C\u8A3C\u306F
|
|
263
858
|
// service/recursionValidator.ts\uFF08wcs/recursion-declaration-invalid\uFF09\u304C\u62C5\u3046\u3002
|
|
264
859
|
type _WcsRecursion = Record<string, string>;
|
|
860
|
+
// $behavior: \u305D\u306E\u6728\u306E\u632F\u308B\u821E\u3044\uFF084.0 \u3067 bootstrapState \u304B\u3089\u79FB\u3063\u305F 3 \u30AD\u30FC\u3002\u65E2\u5B9A\u306F\u3069\u308C\u3082 true\uFF09\u3002
|
|
861
|
+
// \u5024\u304C boolean \u3067\u306A\u3044\u5F62\u306F\u578B\u30A8\u30E9\u30FC\u306B\u306A\u308B\u3002\u77E5\u3089\u306A\u3044\u30AD\u30FC\u306F lint\uFF08wcs/behavior-invalid\uFF09\u304C\u5831\u544A\u3059\u308B\u3002
|
|
862
|
+
type _WcsBehavior = ${BEHAVIOR_TYPE};
|
|
863
|
+
// $features: \u305D\u306E state \u304C\u8981\u308B\u5F8C\u4ED8\u3051\uFF084.0\u3002\u5206\u5272 auto \u306F\u8AAD\u307F\u8FBC\u307F\u3001\u5168\u90E8\u5165\u308A\u30FB\u30D0\u30F3\u30C9\u30E9\u306F\u5165\u3063\u3066\u3044\u308B\u304B\u3092\u691C\u67FB\u3059\u308B\uFF09\u3002
|
|
864
|
+
type _WcsFeatureName = ${FEATURE_NAME_TYPE};
|
|
265
865
|
function defineState<T extends Record<string, any>>(
|
|
266
|
-
def: T & {
|
|
866
|
+
def: T & {
|
|
867
|
+
$listKeys?: _WcsListKeys; $watch?: _WcsWatch; $recursion?: _WcsRecursion;
|
|
868
|
+
$behavior?: _WcsBehavior; $features?: readonly _WcsFeatureName[];
|
|
869
|
+
} & ThisType<_WcsThis<T>>
|
|
267
870
|
): T { return def; }
|
|
268
871
|
// --- end preamble ---
|
|
269
872
|
`;
|