@wcstack/state 4.1.1 → 4.3.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.
Files changed (60) hide show
  1. package/README.ja.md +23 -19
  2. package/README.md +23 -19
  3. package/dist/auto.min.js +1 -1
  4. package/dist/auto.min.js.map +1 -1
  5. package/dist/index.esm.js +1 -1
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/manifest.esm.js +78 -38
  8. package/dist/parser.esm.js +10 -4
  9. package/dist/split/auto.js +1 -1
  10. package/dist/split/chunks/chunk-2RBI6DVS.js +2 -0
  11. package/dist/split/chunks/chunk-2RBI6DVS.js.map +1 -0
  12. package/dist/split/chunks/chunk-5Q4M6A3C.js +2 -0
  13. package/dist/split/chunks/{chunk-7QVEF5E3.js → chunk-6I7GGFNJ.js} +2 -2
  14. package/dist/split/chunks/{chunk-7ZU3CLEG.js → chunk-BGUJ3HF6.js} +2 -2
  15. package/dist/split/chunks/chunk-BKLFDVOP.js +2 -0
  16. package/dist/split/chunks/chunk-BKLFDVOP.js.map +1 -0
  17. package/dist/split/chunks/{chunk-R5OJ52SF.js → chunk-CIBJLAA3.js} +2 -2
  18. package/dist/split/chunks/{chunk-R5OJ52SF.js.map → chunk-CIBJLAA3.js.map} +1 -1
  19. package/dist/split/chunks/chunk-DOWWBZVS.js +2 -0
  20. package/dist/split/chunks/chunk-F3DVWVH3.js +2 -0
  21. package/dist/split/chunks/chunk-F3DVWVH3.js.map +1 -0
  22. package/dist/split/chunks/chunk-M67C46SN.js +2 -0
  23. package/dist/split/chunks/{chunk-JZW5KGXQ.js.map → chunk-M67C46SN.js.map} +1 -1
  24. package/dist/split/chunks/chunk-NMOSSDKJ.js +2 -0
  25. package/dist/split/chunks/chunk-NMOSSDKJ.js.map +1 -0
  26. package/dist/split/chunks/{chunk-GGSHXG7N.js → chunk-UBGJGMSG.js} +2 -2
  27. package/dist/split/chunks/chunk-UBGJGMSG.js.map +1 -0
  28. package/dist/split/core.js +1 -1
  29. package/dist/split/features/devtools.js +1 -1
  30. package/dist/split/features/diagnostics.js +1 -1
  31. package/dist/split/features/diagnostics.js.map +1 -1
  32. package/dist/split/features/formats.d.ts +1 -1
  33. package/dist/split/features/formats.js +1 -1
  34. package/dist/split/features/formats.js.map +1 -1
  35. package/dist/split/features/list-keys.js +1 -1
  36. package/dist/split/features/native-commands.js +1 -1
  37. package/dist/split/features/recursion.js +1 -1
  38. package/dist/split/features/scopes.js +1 -1
  39. package/dist/split/features/ssr.js +1 -1
  40. package/dist/split/features/ssr.js.map +1 -1
  41. package/dist/split/features/temporal.js +1 -1
  42. package/dist/split/features/temporal.js.map +1 -1
  43. package/dist/wcs-manifest.json +29 -15
  44. package/package.json +1 -1
  45. package/dist/split/chunks/chunk-4HLDITUB.js +0 -2
  46. package/dist/split/chunks/chunk-4HLDITUB.js.map +0 -1
  47. package/dist/split/chunks/chunk-BWGPKDHS.js +0 -2
  48. package/dist/split/chunks/chunk-BWGPKDHS.js.map +0 -1
  49. package/dist/split/chunks/chunk-GGSHXG7N.js.map +0 -1
  50. package/dist/split/chunks/chunk-JAEYZSVS.js +0 -2
  51. package/dist/split/chunks/chunk-JZW5KGXQ.js +0 -2
  52. package/dist/split/chunks/chunk-UFIDBJBP.js +0 -2
  53. package/dist/split/chunks/chunk-UFIDBJBP.js.map +0 -1
  54. package/dist/split/chunks/chunk-V3HFN3MW.js +0 -2
  55. package/dist/split/chunks/chunk-V3HFN3MW.js.map +0 -1
  56. package/dist/split/chunks/chunk-XEGL4FW5.js +0 -2
  57. /package/dist/split/chunks/{chunk-XEGL4FW5.js.map → chunk-5Q4M6A3C.js.map} +0 -0
  58. /package/dist/split/chunks/{chunk-7QVEF5E3.js.map → chunk-6I7GGFNJ.js.map} +0 -0
  59. /package/dist/split/chunks/{chunk-7ZU3CLEG.js.map → chunk-BGUJ3HF6.js.map} +0 -0
  60. /package/dist/split/chunks/{chunk-JAEYZSVS.js.map → chunk-DOWWBZVS.js.map} +0 -0
@@ -51,11 +51,17 @@ function optionsRequired(fnName) {
51
51
  function optionMustBeNumber(fnName) {
52
52
  raise(27 /* FilterOptionNotNumber */, [fnName]);
53
53
  }
54
- function valueMustBeNumber(fnName) {
55
- raise(28 /* FilterValueNotNumber */, [fnName]);
54
+ function styleInvalid(fnName, value) {
55
+ raise(52 /* FilterStyleInvalid */, [fnName, value]);
56
56
  }
57
- function valueMustBeDate(fnName) {
58
- raise(29 /* FilterValueNotDate */, [fnName]);
57
+ function currencyInvalid(value) {
58
+ raise(53 /* FilterCurrencyInvalid */, [value]);
59
+ }
60
+ function valueMustBeNumber(fnName, value) {
61
+ raise(28 /* FilterValueNotNumber */, [fnName, value]);
62
+ }
63
+ function valueMustBeDate(fnName, value) {
64
+ raise(29 /* FilterValueNotDate */, [fnName, value]);
59
65
  }
60
66
  function valueMustBeArray(fnName) {
61
67
  raise(30 /* FilterValueNotArray */, [fnName]);
@@ -126,7 +132,7 @@ var numeric = (name, op) => ({
126
132
  const opt = requiredNumberOption(options, 0, name);
127
133
  return (value) => {
128
134
  if (typeof value !== "number") {
129
- valueMustBeNumber(name);
135
+ valueMustBeNumber(name, value);
130
136
  }
131
137
  return op(value, opt);
132
138
  };
@@ -158,7 +164,7 @@ var toFixed = (options) => {
158
164
  const opt = numberOption(options?.[0] ?? "0", "toFixed");
159
165
  return (value) => {
160
166
  if (typeof value !== "number") {
161
- valueMustBeNumber("toFixed");
167
+ valueMustBeNumber("toFixed", value);
162
168
  }
163
169
  return value.toFixed(opt);
164
170
  };
@@ -167,7 +173,7 @@ var round = (options) => {
167
173
  const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "round"));
168
174
  return (value) => {
169
175
  if (typeof value !== "number") {
170
- valueMustBeNumber("round");
176
+ valueMustBeNumber("round", value);
171
177
  }
172
178
  return Math.round(value * optValue) / optValue;
173
179
  };
@@ -176,7 +182,7 @@ var floor = (options) => {
176
182
  const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "floor"));
177
183
  return (value) => {
178
184
  if (typeof value !== "number") {
179
- valueMustBeNumber("floor");
185
+ valueMustBeNumber("floor", value);
180
186
  }
181
187
  return Math.floor(value * optValue) / optValue;
182
188
  };
@@ -185,7 +191,7 @@ var ceil = (options) => {
185
191
  const optValue = Math.pow(10, numberOption(options?.[0] ?? "0", "ceil"));
186
192
  return (value) => {
187
193
  if (typeof value !== "number") {
188
- valueMustBeNumber("ceil");
194
+ valueMustBeNumber("ceil", value);
189
195
  }
190
196
  return Math.ceil(value * optValue) / optValue;
191
197
  };
@@ -194,7 +200,7 @@ var percent = (options) => {
194
200
  const opt = numberOption(options?.[0] ?? "0", "percent");
195
201
  return (value) => {
196
202
  if (typeof value !== "number") {
197
- valueMustBeNumber("percent");
203
+ valueMustBeNumber("percent", value);
198
204
  }
199
205
  return `${(value * 100).toFixed(opt)}%`;
200
206
  };
@@ -221,11 +227,29 @@ var locale = (options) => {
221
227
  const explicit = options?.[0];
222
228
  return (value) => {
223
229
  if (typeof value !== "number") {
224
- valueMustBeNumber("locale");
230
+ valueMustBeNumber("locale", value);
225
231
  }
226
232
  return value.toLocaleString(explicit ?? defaultLocale());
227
233
  };
228
234
  };
235
+ var currency = (options) => {
236
+ const code = options?.[0] ?? optionsRequired("currency");
237
+ const explicit = options?.[1];
238
+ const format = { style: "currency", currency: code };
239
+ try {
240
+ new Intl.NumberFormat("en", format);
241
+ const known = Intl.supportedValuesOf?.("currency");
242
+ if (known && !known.includes(code.toUpperCase())) throw 0;
243
+ } catch {
244
+ currencyInvalid(code);
245
+ }
246
+ return (value) => {
247
+ if (typeof value !== "number") {
248
+ valueMustBeNumber("currency", value);
249
+ }
250
+ return value.toLocaleString(explicit ?? defaultLocale(), format);
251
+ };
252
+ };
229
253
  var upper = () => (value) => String(value).toUpperCase();
230
254
  var lower = () => (value) => String(value).toLowerCase();
231
255
  var capitalize = () => (value) => {
@@ -282,38 +306,48 @@ var join = (options) => {
282
306
  return value.join(opt);
283
307
  };
284
308
  };
309
+ var STYLES = ["full", "long", "medium", "short"];
310
+ function dateOptions(options, fn) {
311
+ let [loc, style] = options ?? [];
312
+ if (style === void 0 && loc !== void 0 && STYLES.includes(loc)) [loc, style] = [void 0, loc];
313
+ if (style !== void 0 && !STYLES.includes(style)) styleInvalid(fn, style);
314
+ return [loc, style];
315
+ }
285
316
  var date = (options) => {
286
- const explicit = options?.[0];
317
+ const [explicit, style] = dateOptions(options, "date");
318
+ const format = style && { dateStyle: style };
287
319
  return (value) => {
288
320
  if (!(value instanceof Date)) {
289
- valueMustBeDate("date");
321
+ valueMustBeDate("date", value);
290
322
  }
291
- return value.toLocaleDateString(explicit ?? defaultLocale());
323
+ return value.toLocaleDateString(explicit ?? defaultLocale(), format);
292
324
  };
293
325
  };
294
326
  var time = (options) => {
295
- const explicit = options?.[0];
327
+ const [explicit, style] = dateOptions(options, "time");
328
+ const format = style && { timeStyle: style };
296
329
  return (value) => {
297
330
  if (!(value instanceof Date)) {
298
- valueMustBeDate("time");
331
+ valueMustBeDate("time", value);
299
332
  }
300
- return value.toLocaleTimeString(explicit ?? defaultLocale());
333
+ return value.toLocaleTimeString(explicit ?? defaultLocale(), format);
301
334
  };
302
335
  };
303
336
  var datetime = (options) => {
304
- const explicit = options?.[0];
337
+ const [explicit, style] = dateOptions(options, "datetime");
338
+ const format = style && { dateStyle: style, timeStyle: style };
305
339
  return (value) => {
306
340
  if (!(value instanceof Date)) {
307
- valueMustBeDate("datetime");
341
+ valueMustBeDate("datetime", value);
308
342
  }
309
- return value.toLocaleString(explicit ?? defaultLocale());
343
+ return value.toLocaleString(explicit ?? defaultLocale(), format);
310
344
  };
311
345
  };
312
346
  var ymd = (options) => {
313
347
  const opt = options?.[0] ?? "-";
314
348
  return (value) => {
315
349
  if (!(value instanceof Date)) {
316
- valueMustBeDate("ymd");
350
+ valueMustBeDate("ymd", value);
317
351
  }
318
352
  const year = value.getFullYear().toString();
319
353
  const month = (value.getMonth() + 1).toString().padStart(2, "0");
@@ -325,7 +359,7 @@ var hms = (options) => {
325
359
  const opt = options?.[0] ?? ":";
326
360
  return (value) => {
327
361
  if (!(value instanceof Date)) {
328
- valueMustBeDate("hms");
362
+ valueMustBeDate("hms", value);
329
363
  }
330
364
  const hours = value.getHours().toString().padStart(2, "0");
331
365
  const minutes = value.getMinutes().toString().padStart(2, "0");
@@ -335,7 +369,7 @@ var hms = (options) => {
335
369
  };
336
370
  var abs = () => (value) => {
337
371
  if (typeof value !== "number") {
338
- valueMustBeNumber("abs");
372
+ valueMustBeNumber("abs", value);
339
373
  }
340
374
  return Math.abs(value);
341
375
  };
@@ -344,7 +378,7 @@ var clamp = (options) => {
344
378
  const max = requiredNumberOption(options, 1, "clamp");
345
379
  return (value) => {
346
380
  if (typeof value !== "number") {
347
- valueMustBeNumber("clamp");
381
+ valueMustBeNumber("clamp", value);
348
382
  }
349
383
  return Math.min(Math.max(value, min), max);
350
384
  };
@@ -391,10 +425,10 @@ var registered = {
391
425
  ceil: { factory: ceil, arity: [0, 1] },
392
426
  percent: { factory: percent, arity: [0, 1] },
393
427
  unit: { factory: nullishPassthrough(unit), arity: [1, 1] },
394
- // The locale-dependent three take a locale like `locale` does (`date(ja-JP)`)
395
- date: { factory: date, arity: [0, 1] },
396
- time: { factory: time, arity: [0, 1] },
397
- datetime: { factory: datetime, arity: [0, 1] },
428
+ // The locale-dependent three take a locale like `locale` does (`date(ja-JP)`), and a style (`date(ja-JP,long)`)
429
+ date: { factory: date, arity: [0, 2] },
430
+ time: { factory: time, arity: [0, 2] },
431
+ datetime: { factory: datetime, arity: [0, 2] },
398
432
  ymd: { factory: ymd, arity: [0, 1] },
399
433
  hms: { factory: hms, arity: [0, 1] },
400
434
  // the core set of 4.0.0-rc.3 (the core's own: eq ne not lt le gt ge falsy truthy boolean)
@@ -421,7 +455,9 @@ var registered = {
421
455
  boolean: boolean2,
422
456
  number: { factory: number, arity: [0, 0] },
423
457
  string: { factory: string, arity: [0, 0] },
424
- nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] }
458
+ nullIfEmpty: { factory: nullIfEmpty, arity: [0, 0] },
459
+ // (added in 4.2: last, so the order of the others is unchanged)
460
+ currency: { factory: currency, arity: [1, 2] }
425
461
  };
426
462
  var formatFilters = /* @__PURE__ */ Object.fromEntries(
427
463
  /* @__PURE__ */ Object.entries(registered).filter(([name]) => !(name in coreFilters))
@@ -459,10 +495,11 @@ var builtinFilterMeta = {
459
495
  // `not` は真偽性(truthy / falsy)の反転。`if:` が `Boolean()` で寄せるのと同じ規則で、
460
496
  // `else:` はこのフィルタを足した束縛として組み立てられる(structural/createNotFilter.ts)
461
497
  not: { description: "\u771F\u507D\u6027\u3092\u53CD\u8EE2\uFF08falsy \u2192 true\uFF09", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
462
- lt: { description: "\u3088\u308A\u5C0F\u3055\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
463
- le: { description: "\u4EE5\u4E0B\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
464
- gt: { description: "\u3088\u308A\u5927\u304D\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
465
- ge: { description: "\u4EE5\u4E0A\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number", "string"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
498
+ // 比較は数値だけを受ける(filters/core.ts の `numeric` は数値以外の値で #28。3.x も同じで、"string" は誤りだった)
499
+ lt: { description: "\u3088\u308A\u5C0F\u3055\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
500
+ le: { description: "\u4EE5\u4E0B\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
501
+ gt: { description: "\u3088\u308A\u5927\u304D\u3044\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
502
+ ge: { description: "\u4EE5\u4E0A\u304B", hasArgs: true, resultType: "boolean", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
466
503
  // 算術
467
504
  add: { description: "\u52A0\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
468
505
  sub: { description: "\u6E1B\u7B97", hasArgs: true, resultType: "number", acceptTypes: ["number"], minArgs: 1, maxArgs: 1, argTypes: ["number"] },
@@ -498,10 +535,11 @@ var builtinFilterMeta = {
498
535
  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"] },
499
536
  // 日付・時刻
500
537
  // `locale` と同じくロケールを 1 つ受ける(`date(ja-JP)`)。実装は最初からこれを読んでいたが、
501
- // メタデータ側が maxArgs: 0 だったため lint と補完が正しい書き方を誤りとして報告していた
502
- 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"] },
503
- 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"] },
504
- 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"] },
538
+ // メタデータ側が maxArgs: 0 だったため lint と補完が正しい書き方を誤りとして報告していた。
539
+ // 4.2: 2 つ目は書式(full / long / medium / short — Intl の dateStyle / timeStyle)。書式だけなら既定のロケール
540
+ date: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u65E5\u4ED8 ([locale][, style]\u3002style \u306F full / long / medium / short\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 2, argTypes: ["string", "string"] },
541
+ time: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u6642\u523B ([locale][, style]\u3002style \u306F full / long / medium / short\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 2, argTypes: ["string", "string"] },
542
+ datetime: { description: "\u30ED\u30B1\u30FC\u30EB\u5F62\u5F0F\u306E\u65E5\u6642 ([locale][, style]\u3002style \u306F full / long / medium / short\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 2, argTypes: ["string", "string"] },
505
543
  ymd: { description: "YYYY-MM-DD \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F -)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
506
544
  hms: { description: "HH:MM:SS \u5F62\u5F0F ([separator]\u3002\u65E2\u5B9A\u306F :)", hasArgs: true, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 1, argTypes: ["string"] },
507
545
  // 真偽値・変換
@@ -512,7 +550,9 @@ var builtinFilterMeta = {
512
550
  boolean: { description: "\u30D6\u30FC\u30EB\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "boolean", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
513
551
  number: { description: "\u6570\u5024\u306B\u5909\u63DB", hasArgs: false, resultType: "number", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
514
552
  string: { description: "\u6587\u5B57\u5217\u306B\u5909\u63DB", hasArgs: false, resultType: "string", acceptTypes: "any", minArgs: 0, maxArgs: 0 },
515
- nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 }
553
+ nullIfEmpty: { description: "\u7A7A\u6587\u5B57\u5217\u3092null\u306B\u5909\u63DB", hasArgs: false, resultType: "passthrough", acceptTypes: ["string"], minArgs: 0, maxArgs: 0 },
554
+ // 4.2(formats の最後に登録)
555
+ currency: { description: "\u901A\u8CA8\u306E\u66F8\u5F0F (code[, locale]\u3002code \u306F ISO 4217 \u2014 JPY / USD / EUR\u3001\u65E2\u5B9A\u306E\u30ED\u30B1\u30FC\u30EB\u306F config.locale)", hasArgs: true, resultType: "string", acceptTypes: ["number"], minArgs: 1, maxArgs: 2, argTypes: ["string", "string"] }
516
556
  };
517
557
 
518
558
  // src/public/manifest.ts
@@ -92,7 +92,8 @@ var FORMATS_FILTER_NAMES = [
92
92
  "coalesce",
93
93
  "number",
94
94
  "string",
95
- "nullIfEmpty"
95
+ "nullIfEmpty",
96
+ "currency"
96
97
  ];
97
98
  var definitions = /* @__PURE__ */ new Map();
98
99
  function hasFilter(name) {
@@ -325,6 +326,8 @@ var codeOf = (id) => {
325
326
  return c ? `[wcs/${c}] ` : "";
326
327
  };
327
328
  var MOVED = ["enableMustache", "sameValueGuard", "enableDirectionalInitialSync"];
329
+ var was = (v) => v == null ? String(v) : v instanceof Date ? "a Date" : Array.isArray(v) ? "an array" : typeof v === "string" ? `a string (${JSON.stringify(v.length > 32 ? v.slice(0, 32) + "\u2026" : v)})` : typeof v === "object" ? "an object" : `a ${typeof v} (${String(v)})`;
330
+ var NAMESPACES = ["", "", "class.", "attr.", "style."];
328
331
  var element = (tag, at) => `<${tag}${at.map((a, i) => i % 2 ? `="${a}"` : ` ${a}`).join("")}>`;
329
332
  var CSP_GUIDE = "https://github.com/wcstack/wcstack/blob/main/docs/csp.md";
330
333
  var SENTENCES = {
@@ -340,7 +343,8 @@ var SENTENCES = {
340
343
  [10 /* SetAllSpreadLength */]: (p, n) => `$setAll("${p}", \u2026, { spread: true }) needs an array of ${n} values`,
341
344
  [11 /* DrainNotSettled */]: () => `updates did not settle after ${MAX_DRAIN_PASSES} passes`,
342
345
  [41 /* RenderChain */]: () => `render chain depth limit exceeded (${MAX_RENDER_CHAIN} drains that rendering itself started); bindings for this batch were not applied.`,
343
- [12 /* BindingFailed */]: (type, p) => `binding "${type}: ${p}" failed to apply.`,
346
+ // (named as written — `textContent: iso`, `class.active: x` — when the binding has a member; else its type)
347
+ [12 /* BindingFailed */]: (type, p, name, kind) => `binding "${name ? (NAMESPACES[kind] ?? "") + name : type}: ${p}" failed to apply.`,
344
348
  [13 /* LoadFailed */]: (src, status) => `failed to load "${src}": ${status}`,
345
349
  [14 /* ElementFailed */]: () => "this <wcs-state> failed to initialize; create a new one",
346
350
  [15 /* NotInitialized */]: () => "state is not initialized",
@@ -358,8 +362,10 @@ var SENTENCES = {
358
362
  [25 /* NamingLimit */]: (limit) => `view-transition naming-limit (${limit}) reached.`,
359
363
  [26 /* FilterOptionsRequired */]: (fn) => `filter ${fn} requires at least one option`,
360
364
  [27 /* FilterOptionNotNumber */]: (fn) => `filter ${fn} requires a number as option`,
361
- [28 /* FilterValueNotNumber */]: (fn) => `filter ${fn} requires a number value`,
362
- [29 /* FilterValueNotDate */]: (fn) => `filter ${fn} requires a date value`,
365
+ [28 /* FilterValueNotNumber */]: (fn, v) => `filter ${fn} requires a number value, not ${was(v)}${typeof v === "string" ? ` \u2014 put |number before |${fn}, or convert it where it is read` : ""}`,
366
+ [29 /* FilterValueNotDate */]: (fn, v) => `filter ${fn} requires a date value (a Date), not ${was(v)}${typeof v === "string" || typeof v === "number" ? " \u2014 make the Date where it is read: a getter returning new Date(\u2026)" : ""}`,
367
+ [52 /* FilterStyleInvalid */]: (fn, v) => `filter ${fn} takes a style of full, long, medium or short, not "${v}"`,
368
+ [53 /* FilterCurrencyInvalid */]: (v) => `filter currency takes an ISO 4217 currency code (JPY, USD, EUR), not "${v}"`,
363
369
  [30 /* FilterValueNotArray */]: (fn) => `filter ${fn} requires an array value`,
364
370
  [31 /* DirectionalSyncDisabled */]: () => "init=/sync= modifiers require enableDirectionalInitialSync.",
365
371
  [33 /* ModifierUnknown */]: (key, modifier) => `Unknown binding modifier "${key}" in "${modifier}".`,
@@ -1,2 +1,2 @@
1
- import{d as t}from"./chunks/chunk-V3HFN3MW.js";import"./chunks/chunk-JAEYZSVS.js";import"./chunks/chunk-UFIDBJBP.js";import"./chunks/chunk-BWGPKDHS.js";import"./chunks/chunk-4HLDITUB.js";import{a as n}from"./chunks/chunk-R5OJ52SF.js";import"./chunks/chunk-XEGL4FW5.js";import"./chunks/chunk-7QVEF5E3.js";import"./chunks/chunk-GGSHXG7N.js";import{a as s,g as o}from"./chunks/chunk-7ZU3CLEG.js";var e,r=["formats","diagnostics","temporal","list-keys","scopes","recursion","ssr","devtools","native-commands"],a=(e=import.meta.url,t=>Promise.all(t.map(async t=>{if(!r.includes(t))throw new Error(`[@wcstack/state] [wcs/feature-unknown] "${t}" is not an add-on (${r.join(", ")}).`);return(await(import(new URL(`./features/${t}.js`,e).href))).default})));s.wt=t=>a(t).then(o),"loading"===document.readyState&&await new Promise(t=>document.addEventListener("DOMContentLoaded",t,{once:!0}));var c=document.querySelector(`${n.tagNames.state}:not([mount]):not([bind-component])`);o(await a(c?.getAttribute("features")?.split(/\s+/).filter(Boolean)??[])),t();
1
+ import{d as t}from"./chunks/chunk-BKLFDVOP.js";import"./chunks/chunk-DOWWBZVS.js";import"./chunks/chunk-NMOSSDKJ.js";import"./chunks/chunk-2RBI6DVS.js";import"./chunks/chunk-F3DVWVH3.js";import{a as n}from"./chunks/chunk-CIBJLAA3.js";import"./chunks/chunk-5Q4M6A3C.js";import"./chunks/chunk-6I7GGFNJ.js";import"./chunks/chunk-UBGJGMSG.js";import{a as s,g as o}from"./chunks/chunk-BGUJ3HF6.js";var e,r=["formats","diagnostics","temporal","list-keys","scopes","recursion","ssr","devtools","native-commands"],a=(e=import.meta.url,t=>Promise.all(t.map(async t=>{if(!r.includes(t))throw new Error(`[@wcstack/state] [wcs/feature-unknown] "${t}" is not an add-on (${r.join(", ")}).`);return(await(import(new URL(`./features/${t}.js`,e).href))).default})));s.bt=t=>a(t).then(o),"loading"===document.readyState&&await new Promise(t=>document.addEventListener("DOMContentLoaded",t,{once:!0}));var c=document.querySelector(`${n.tagNames.state}:not([mount]):not([bind-component])`);o(await a(c?.getAttribute("features")?.split(/\s+/).filter(Boolean)??[])),t();
2
2
  //# sourceMappingURL=auto.js.map
@@ -0,0 +1,2 @@
1
+ import{e as t}from"./chunk-CIBJLAA3.js";import{b as n}from"./chunk-UBGJGMSG.js";function r(t){n(26,[t])}function e(t){n(27,[t])}function o(t,r){n(52,[t,r])}function a(t){n(53,[t])}function f(t,r){n(28,[t,r])}function u(t,r){n(29,[t,r])}function i(t){n(30,[t])}function y(t){return!(!t||isNaN(Number(t)))}function c(t,n){return y(t)||e(n),Number(t)}function s(t,n,e){return c(t?.[n]??r(e),e)}function l(t,n){return void 0!==n&&n.length>0?n[0]:t}var m=(t,n)=>({factory:r=>{let e=s(r,0,t);return r=>("number"!=typeof r&&f(t,r),n(r,e))},arity:[1,1]}),b={eq:{factory:(t,n)=>{let o=t?.[0]??r("eq"),a=l(o,n);return t=>"number"==typeof t?"string"!=typeof a?t===a:(y(o)||e("eq"),t===Number(o)):"string"==typeof t?t===o:t===a},arity:[1,1]},ne:{factory:(t,n)=>{let o=t?.[0]??r("ne"),a=l(o,n);return t=>"number"==typeof t?"string"!=typeof a?t!==a:(y(o)||e("ne"),t!==Number(o)):"string"==typeof t?t!==o:t!==a},arity:[1,1]},not:{factory:()=>t=>!t,arity:[0,0]},lt:m("lt",(t,n)=>t<n),le:m("le",(t,n)=>t<=n),gt:m("gt",(t,n)=>t>n),ge:m("ge",(t,n)=>t>=n),falsy:{factory:()=>t=>!t,arity:[0,0]},truthy:{factory:()=>t=>!!t,arity:[0,0]},boolean:{factory:()=>t=>!!t,arity:[0,0]}},g=!1;function p(){g||(g=!0,t(b))}export{r as a,o as b,a as c,f as d,u as e,i as f,c as g,s as h,l as i,m as j,b as k,p as l};
2
+ //# sourceMappingURL=chunk-2RBI6DVS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["optionsRequired","fnName","raise","optionMustBeNumber","styleInvalid","value","currencyInvalid","valueMustBeNumber","valueMustBeDate","valueMustBeArray","validateNumberString","isNaN","Number","numberOption","requiredNumberOption","options","index","firstLiteral","opt","literals","length","numeric","name","op","factory","arity","coreFilters","eq","literal","ne","not","lt","le","gt","ge","falsy","truthy","boolean","installed","installCoreFilters","registerFilters","u","M","R","c","v","D","m","y","a","l","x","C"],"sources":["../../../src/filters/errorMessages.ts","../../../src/filters/options.ts","../../../src/filters/core.ts"],"sourcesContent":["/**\n * filters/errorMessages.ts — the filters' error messages, ported from `@wcstack/state`\n * (`formats/errorMessages.ts`). Numbered core messages (src/messages.ts): the sentences, the same\n * as the source's, are the diagnostics add-on's.\n */\n\nimport { raise, M } from \"../messages\";\n\n/** The filter requires an option but none was given (the factory-side guard; arity usually fires first). */\nexport function optionsRequired(fnName: string): never {\n raise(M.FilterOptionsRequired, [fnName]);\n}\n\n/** A numeric option is not a number. */\nexport function optionMustBeNumber(fnName: string): never {\n raise(M.FilterOptionNotNumber, [fnName]);\n}\n\n/** A date filter's style is not one of full / long / medium / short. */\nexport function styleInvalid(fnName: string, value: string): never {\n raise(M.FilterStyleInvalid, [fnName, value]);\n}\n\n/** `currency`'s code is not a currency Intl knows. */\nexport function currencyInvalid(value: string): never {\n raise(M.FilterCurrencyInvalid, [value]);\n}\n\n/** The value given to a numeric filter is not a number (the message says what it was). */\nexport function valueMustBeNumber(fnName: string, value: unknown): never {\n raise(M.FilterValueNotNumber, [fnName, value]);\n}\n\n/** The value given to a date filter is not a Date (the message says what it was). */\nexport function valueMustBeDate(fnName: string, value: unknown): never {\n raise(M.FilterValueNotDate, [fnName, value]);\n}\n\n/** The value given to an array filter is not an array. */\nexport function valueMustBeArray(fnName: string): never {\n raise(M.FilterValueNotArray, [fnName]);\n}\n","/**\n * filters/options.ts — option parsing shared by the core set and the formats add-on, ported\n * verbatim from `@wcstack/state` (`formats/builtinFilters.ts`).\n *\n * Numeric options are read **once, when the filter is built**: the checks stay in one place and the\n * `Number()` conversion stays off the apply path.\n */\nimport { optionMustBeNumber, optionsRequired } from \"./errorMessages\";\n\n/** `\"\"` and anything `Number()` cannot read are rejected (so `lt('')` is an error, not `lt(0)`). */\nexport function validateNumberString(value: string): boolean {\n if (!value || isNaN(Number(value))) {\n return false;\n }\n return true;\n}\n\n/** One numeric option, converted: non-numeric → `optionMustBeNumber`. */\nexport function numberOption(value: string, fnName: string): number {\n if (!validateNumberString(value)) {optionMustBeNumber(fnName);}\n return Number(value);\n}\n\n/** A required numeric option: missing → `optionsRequired`, non-numeric → `optionMustBeNumber`. */\nexport function requiredNumberOption(options: readonly string[] | undefined, index: number, fnName: string): number {\n return numberOption(options?.[index] ?? optionsRequired(fnName), fnName);\n}\n\n/**\n * The typed literal of the first argument (requirement B9): an unquoted `true` / `false` / `null` /\n * number arrives typed, a quoted argument as a string. Without literals (tooling calling a factory\n * directly) the raw option text stands in.\n */\nexport function firstLiteral(opt: string, literals: readonly unknown[] | undefined): unknown {\n return literals !== undefined && literals.length > 0 ? literals[0] : opt;\n}\n","/**\n * filters/core.ts — the core filter set (10): the conditions a binding tests, as opposed to the\n * values the formats add-on (`./formats`) computes and shows. Ported from `@wcstack/state`\n * (`formats/builtinFilters.ts`) with the semantics unchanged.\n *\n * - conditions: `eq ne not lt le gt ge truthy falsy boolean`\n *\n * The arithmetic (`add sub mul div mod abs clamp`), conversion (`number string int float`) and\n * missing-value (`defaults coalesce nullIfEmpty`) filters were here up to 4.0.0-rc.3; they are the\n * formats add-on's since, for the core's size target.\n *\n * `installCoreFilters()` puts them in the registry; the engine calls it before it plans bindings\n * (`else:` is built with an injected `not`, so the core set is never optional).\n */\nimport { optionMustBeNumber, optionsRequired, valueMustBeNumber } from \"./errorMessages\";\nimport { firstLiteral, requiredNumberOption, validateNumberString } from \"./options\";\nimport { registerFilters, type FilterDefinition, type FilterFn } from \"./registry\";\n\n/** Equality — compares with the option (a typed literal compares as itself, B9). */\nconst eq = (options: string[], literals?: readonly unknown[]): FilterFn => {\n const opt = options?.[0] ?? optionsRequired('eq');\n const literal = firstLiteral(opt, literals);\n return (value: unknown): boolean => {\n if (typeof value === 'number') {\n // A typed literal that is not a string compares as itself (B9): a number is never equal to\n // `true` / `false` / `null`, so `selectedId|eq(null)` is false once the id is a number instead\n // of throwing on every apply. Only an unquoted non-number (`eq(abc)`) still reports the type\n // mismatch, and it has to stay here: `eq` accepts values of any type (`status|eq(active)` is\n // valid), so it cannot be rejected at construction the way `lt` / `add` can.\n if (typeof literal !== 'string') {return value === literal;}\n if (!validateNumberString(opt)) {optionMustBeNumber('eq');}\n return value === Number(opt);\n }\n if (typeof value === 'string') {\n return value === opt;\n }\n // Booleans, null and the rest compare with the typed literal: eq(true) matches true (B9)\n return value === literal;\n };\n};\n\n/** Inequality — the negation of `eq`, with the same typing rules (B9). */\nconst ne = (options: string[], literals?: readonly unknown[]): FilterFn => {\n const opt = options?.[0] ?? optionsRequired('ne');\n const literal = firstLiteral(opt, literals);\n return (value: unknown): boolean => {\n if (typeof value === 'number') {\n if (typeof literal !== 'string') {return value !== literal;}\n if (!validateNumberString(opt)) {optionMustBeNumber('ne');}\n return value !== Number(opt);\n }\n if (typeof value === 'string') {\n return value !== opt;\n }\n return value !== literal;\n };\n};\n\n/**\n * Inverts truthiness (lenient `!value`). `else:` is built as the `if` condition plus an injected\n * `not`, and `if:` coerces with `Boolean()`; a strict `not` made `else:` throw — rendering neither\n * branch — whenever the condition was a falsy non-boolean (`0` / `\"\"` / `undefined` / `null`).\n */\nconst not = (): FilterFn => (value: unknown): boolean => !value;\n\n/**\n * A comparison or arithmetic filter: one numeric option, a number value (`lt` … `ge` here, `add` …\n * `mod` in the formats add-on).\n */\nexport const numeric = (name: string, op: (value: number, opt: number) => unknown): FilterDefinition => ({\n factory: (options: string[]): FilterFn => {\n const opt = requiredNumberOption(options, 0, name);\n return (value: unknown): unknown => {\n if (typeof value !== 'number') {valueMustBeNumber(name, value);}\n return op(value, opt);\n };\n },\n arity: [1, 1],\n});\n\n/** JavaScript's truthiness, the same as `boolean` (B10). */\nconst truthy = (): FilterFn => (value: unknown): boolean => !!value;\n\n/** JavaScript's falsiness (`!value`: false, null, undefined, 0, -0, 0n, '' and NaN — B10). */\nconst falsy = (): FilterFn => (value: unknown): boolean => !value;\n\nconst boolean = (): FilterFn => (value: unknown): boolean => Boolean(value);\n\n/**\n * The core set: factory and [min, max] argument count (B3 — the same bounds lint uses).\n *\n * The key order is the source's (`builtinFilterMeta`, which lint reads): the did-you-mean\n * suggestion breaks ties by registration order (see `installFormats` for the order the full\n * build registers).\n */\nexport const coreFilters: Readonly<Record<string, FilterDefinition>> = {\n eq: { factory: eq, arity: [1, 1] },\n ne: { factory: ne, arity: [1, 1] },\n not: { factory: not, arity: [0, 0] },\n lt: numeric('lt', (value, opt) => value < opt),\n le: numeric('le', (value, opt) => value <= opt),\n gt: numeric('gt', (value, opt) => value > opt),\n ge: numeric('ge', (value, opt) => value >= opt),\n falsy: { factory: falsy, arity: [0, 0] },\n truthy: { factory: truthy, arity: [0, 0] },\n boolean: { factory: boolean, arity: [0, 0] },\n};\n\nlet installed = false;\n\n/** Puts the core set in the registry. Idempotent; the engine calls it before planning any binding. */\nexport function installCoreFilters(): void {\n if (installed) return;\n installed = true;\n registerFilters(coreFilters);\n}\n"],"mappings":"gFASO,SAASA,EAAgBC,GAC9BC,KAA+B,CAACD,GAClC,CAGO,SAASE,EAAmBF,GACjCC,KAA+B,CAACD,GAClC,CAGO,SAASG,EAAaH,EAAgBI,GAC3CH,KAA4B,CAACD,EAAQI,GACvC,CAGO,SAASC,EAAgBD,GAC9BH,KAA+B,CAACG,GAClC,CAGO,SAASE,EAAkBN,EAAgBI,GAChDH,KAA8B,CAACD,EAAQI,GACzC,CAGO,SAASG,EAAgBP,EAAgBI,GAC9CH,KAA4B,CAACD,EAAQI,GACvC,CAGO,SAASI,EAAiBR,GAC/BC,KAA6B,CAACD,GAChC,CC/BO,SAASS,EAAqBL,GACnC,SAAKA,GAASM,MAAMC,OAAOP,IAI7B,CAGO,SAASQ,EAAaR,EAAeJ,GAC1C,OAAKS,EAAqBL,IAASF,EAAmBF,GAC/CW,OAAOP,EAChB,CAGO,SAASS,EAAqBC,EAAwCC,EAAef,GAC1F,OAAOY,EAAaE,IAAUC,IAAUhB,EAAgBC,GAASA,EACnE,CAOO,SAASgB,EAAaC,EAAaC,GACxC,YAAoB,IAAbA,GAA0BA,EAASC,OAAS,EAAID,EAAS,GAAKD,CACvE,CChBA,IAkDaG,EAAU,CAACC,EAAcC,MACpCC,QAAUT,IACR,IAAMG,EAAMJ,EAAqBC,EAAS,EAAGO,GAC7C,OAAQjB,IACe,iBAAVA,GAAqBE,EAAkBe,EAAMjB,GACjDkB,EAAGlB,EAAOa,KAGrBO,MAAO,CAAC,EAAG,KAkBAC,EAA0D,CACrEC,GAAI,CAAEH,QA7EG,CAACT,EAAmBI,KAC7B,IAAMD,EAAMH,IAAU,IAAMf,EAAgB,MACtC4B,EAAUX,EAAaC,EAAKC,GAClC,OAAQd,GACe,iBAAVA,EAMc,iBAAZuB,EAA8BvB,IAAUuB,GAC9ClB,EAAqBQ,IAAOf,EAAmB,MAC7CE,IAAUO,OAAOM,IAEL,iBAAVb,EACFA,IAAUa,EAGZb,IAAUuB,GA2DAH,MAAO,CAAC,EAAG,IAC9BI,GAAI,CAAEL,QAvDG,CAACT,EAAmBI,KAC7B,IAAMD,EAAMH,IAAU,IAAMf,EAAgB,MACtC4B,EAAUX,EAAaC,EAAKC,GAClC,OAAQd,GACe,iBAAVA,EACc,iBAAZuB,EAA8BvB,IAAUuB,GAC9ClB,EAAqBQ,IAAOf,EAAmB,MAC7CE,IAAUO,OAAOM,IAEL,iBAAVb,EACFA,IAAUa,EAEZb,IAAUuB,GA2CAH,MAAO,CAAC,EAAG,IAC9BK,IAAK,CAAEN,QAnCG,IAAiBnB,IAA6BA,EAmCnCoB,MAAO,CAAC,EAAG,IAChCM,GAAIV,EAAQ,KAAM,CAAChB,EAAOa,IAAQb,EAAQa,GAC1Cc,GAAIX,EAAQ,KAAM,CAAChB,EAAOa,IAAQb,GAASa,GAC3Ce,GAAIZ,EAAQ,KAAM,CAAChB,EAAOa,IAAQb,EAAQa,GAC1CgB,GAAIb,EAAQ,KAAM,CAAChB,EAAOa,IAAQb,GAASa,GAC3CiB,MAAO,CAAEX,QAnBG,IAAiBnB,IAA6BA,EAmBjCoB,MAAO,CAAC,EAAG,IACpCW,OAAQ,CAAEZ,QAvBG,IAAiBnB,KAA8BA,EAuBjCoB,MAAO,CAAC,EAAG,IACtCY,QAAS,CAAEb,QAnBG,IAAiBnB,KAAoCA,EAmBtCoB,MAAO,CAAC,EAAG,KAGtCa,GAAY,EAGT,SAASC,IACVD,IACJA,GAAY,EACZE,EAAgBd,GAClB,QAAAe,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ var t=class{constructor(t,l,i){this.c=[],this.getter=null,this.ie=null,this.se=!1,this.W=[],this.Q=[],this.pt=null,this.F=-1,this.Y=s,this.je=null,this.It=null,this.Dt=null,this._=null,this.pn=!1,this.mn=!1,this.Wn=!1,this.Z=0,this.mt=new Set,this.t=t,this.d=i,this.s=l;let e=null===i?[null]:i.h.slice(),h="*"===l;h&&e.push(i),this.n=e.length-1,this.z=h?[]:null===i?[l]:[...i.z,l],this.h=e}_n(t){this.mt.has(t)||(this.mt.add(t),this.W.push(t),t.Q.push(this))}Io(t){this.mt.delete(t);let s=this.W;s.splice(s.indexOf(t),1)}Do(){this.getter=null,this.ie=null,this.F=-1,this.Y=s,this.W.length=0,this.mt.clear(),this.Q.length=0,this.pt=null,this.je=null,this.It=null,this.Dt=null,this._=null}ee(t){let s=this;for(;null!==s;){if(s===t)return!0;s=s.d}return!1}},s=Symbol("unset"),l=Symbol("dirty"),i=Symbol("failed"),e=class{constructor(t=null){this.ht=new Map,this.Vn=t}jt(t){return this.ht.get(t)}get(s){let l=this.ht.get(s);if(void 0!==l)return l;let i=s.lastIndexOf("."),e=i<0?null:this.get(s.slice(0,i));return l=new t(s,s.slice(i+1),e),this.Vn?.(l),this.ht.set(s,l),e&&e.c.push(l),l}all(){return this.ht.values()}Lt(t){this.ht.delete(t.t)}},h=new Map;function n(t){let s=h.get(t);if(void 0!==s)return s;let l=!0,i=t.split("."),e=[];for(let t=0;t<i.length;t++){let s=i[t],h=s.charCodeAt(0);t>0&&h>=48&&h<=57?(l=!1,e.push(Number(s)),i[t]="*"):"*"===s&&e.push(-1)}if(!l)return{o:i.join("."),indexes:e};let n={o:t,indexes:null};return h.size>4095&&h.clear(),h.set(t,n),n}export{s as a,l as b,i as c,e as d,n as e};
2
+ //# sourceMappingURL=chunk-5Q4M6A3C.js.map
@@ -1,2 +1,2 @@
1
- import{b as t}from"./chunk-GGSHXG7N.js";var e="else",l="eventToken",n="state",s="command",r="class",i="attr",u="style",a=/^\$[1-9]\d{0,2}$/,c=/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;function o(e){let l=[],n=[],s="",r=null,i=!1,u=-1,a=-1,o=t=>{let e=function(t,e,l){let n=-1===e?t.length:e,s=-1===l?0:l;return t.slice(n-t.slice(0,n).trimStart().length,s+t.slice(s).trimEnd().length)}(s,u,a);(!t||e||i)&&(l.push(e),n.push(function(t,e){return e?t:"true"===t||"false"!==t&&("null"===t?null:c.test(t)?Number(t):t)}(e,i))),s="",i=!1,u=-1,a=-1};for(let t=0;t<e.length;t++){let l=e[t];r?l===r?r=null:(-1===u&&(u=s.length),s+=l,a=s.length):'"'===l||"'"===l?(r=l,i=!0):","===l?o():s+=l}return null!==r&&t(107,[r,e]),o(!0),{args:l,literals:n}}var f=t=>t.trim();function h(t,e){let l=[],n=null;for(let s=0;s<t.length;s++){let r=t[s];null!==n?r===n&&(n=null):"'"===r||'"'===r?n=r:r===e&&l.push(s)}return l}var g=(t,e)=>h(t,e)[0]??-1;function m(t,e){let l=[],n=0;for(let s of h(t,e))l.push(t.slice(n,s)),n=s+1;return l.push(t.slice(n)),l}function p(e,l,n){let s=g(e,"|");if(-1===s)return[e.trim(),[]];let r=e.slice(s+1).trim(),i=n.get(r);return void 0===i&&(i=function(e,l,n){let s=n??e.join("|");return e.map(e=>{let n=g(e,"("),r=(t=>h(t,")").pop()??-1)(e);if(-1===r&&(r=e.lastIndexOf(")")),-1!==n&&-1===r&&t(108,[e]),-1!==r&&-1===n&&t(109,[e]),-1!==r&&r<n&&t(110,[e]),-1!==r&&e.slice(r+1).trim().length>0){let l=e.slice(r+1).trim();t(111,[e,l])}let i=(-1===n?e:e.substring(0,n)).trim();if(0===i.length&&t(112,[s]),i.includes("#")){let[,e]=i.split("#");t("input"===l?113:114,[i,e])}return-1===n?{Hn:i,args:[],literals:[]}:{Hn:i,...o(e.substring(n+1,r))}})}(m(r,"|").map(f),l,e),n.set(r,i)),[e.slice(0,s).trim(),i]}var d=new Map;function v(e){t(1101,[e])}function b(e){let[l,n]=p(e,"output",d);l.includes("@")&&t(32,[l]);let s=l,r=s.startsWith("."),i=r?s.slice(1):s;return(i.length>0&&i.split(".").some(t=>0===t.length)||!r&&0===i.length)&&t(119,[e]),function(e){e.includes("**")&&v(e);let l=e.split(".").length;l>512&&t(117,[e,l])}(s),{Ze:s,et:n}}export{e as a,l as b,n as c,s as d,r as e,i as f,u as g,a as h,f as i,g as j,m as k,p as l,v as m,b as n};
2
- //# sourceMappingURL=chunk-7QVEF5E3.js.map
1
+ import{b as t}from"./chunk-UBGJGMSG.js";var e="else",l="eventToken",n="state",s="command",r="class",i="attr",u="style",a=/^\$[1-9]\d{0,2}$/,c=/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;function o(e){let l=[],n=[],s="",r=null,i=!1,u=-1,a=-1,o=t=>{let e=function(t,e,l){let n=-1===e?t.length:e,s=-1===l?0:l;return t.slice(n-t.slice(0,n).trimStart().length,s+t.slice(s).trimEnd().length)}(s,u,a);(!t||e||i)&&(l.push(e),n.push(function(t,e){return e?t:"true"===t||"false"!==t&&("null"===t?null:c.test(t)?Number(t):t)}(e,i))),s="",i=!1,u=-1,a=-1};for(let t=0;t<e.length;t++){let l=e[t];r?l===r?r=null:(-1===u&&(u=s.length),s+=l,a=s.length):'"'===l||"'"===l?(r=l,i=!0):","===l?o():s+=l}return null!==r&&t(107,[r,e]),o(!0),{args:l,literals:n}}var f=t=>t.trim();function h(t,e){let l=[],n=null;for(let s=0;s<t.length;s++){let r=t[s];null!==n?r===n&&(n=null):"'"===r||'"'===r?n=r:r===e&&l.push(s)}return l}var g=(t,e)=>h(t,e)[0]??-1;function m(t,e){let l=[],n=0;for(let s of h(t,e))l.push(t.slice(n,s)),n=s+1;return l.push(t.slice(n)),l}function p(e,l,n){let s=g(e,"|");if(-1===s)return[e.trim(),[]];let r=e.slice(s+1).trim(),i=n.get(r);return void 0===i&&(i=function(e,l,n){let s=n??e.join("|");return e.map(e=>{let n=g(e,"("),r=(t=>h(t,")").pop()??-1)(e);if(-1===r&&(r=e.lastIndexOf(")")),-1!==n&&-1===r&&t(108,[e]),-1!==r&&-1===n&&t(109,[e]),-1!==r&&r<n&&t(110,[e]),-1!==r&&e.slice(r+1).trim().length>0){let l=e.slice(r+1).trim();t(111,[e,l])}let i=(-1===n?e:e.substring(0,n)).trim();if(0===i.length&&t(112,[s]),i.includes("#")){let[,e]=i.split("#");t("input"===l?113:114,[i,e])}return-1===n?{Hn:i,args:[],literals:[]}:{Hn:i,...o(e.substring(n+1,r))}})}(m(r,"|").map(f),l,e),n.set(r,i)),[e.slice(0,s).trim(),i]}var d=new Map;function v(e){t(1101,[e])}function b(e){let[l,n]=p(e,"output",d);l.includes("@")&&t(32,[l]);let s=l,r=s.startsWith("."),i=r?s.slice(1):s;return(i.length>0&&i.split(".").some(t=>0===t.length)||!r&&0===i.length)&&t(119,[e]),function(e){e.includes("**")&&v(e);let l=e.split(".").length;l>512&&t(117,[e,l])}(s),{Qe:s,Ze:n}}export{e as a,l as b,n as c,s as d,r as e,i as f,u as g,a as h,f as i,g as j,m as k,p as l,v as m,b as n};
2
+ //# sourceMappingURL=chunk-6I7GGFNJ.js.map
@@ -1,2 +1,2 @@
1
- var t={};function a(t,a){return null==t?a:(...e)=>{t(...e),a(...e)}}function e(t,a,e){return null==a?e:(...n)=>{let r=a(...n);return t(r)?r:e(...n)}}var n=t=>!0===t,r=t=>void 0!==t,s=t=>null!=t,l=new Set;function o(t){for(let a of t)l.has(a.name)||(l.add(a.name),a.install())}function u(a){let e=a.$features;if(null!=t.wt&&Array.isArray(e)){let a=e.filter(t=>!l.has(t));if(a.length>0)return t.wt(a)}}function f(t,a){if(!l.has(t))throw new Error(`[@wcstack/state] [wcs/feature-not-installed] ${a} needs the add-on @wcstack/state/features/${t}`)}function i(a,e,n){throw new Error(`[@wcstack/state] ${a}${t.Lo?.(a,e,n)??""}`)}export{t as a,a as b,e as c,n as d,r as e,s as f,o as g,u as h,f as i,i as j};
2
- //# sourceMappingURL=chunk-7ZU3CLEG.js.map
1
+ var t={};function a(t,a){return null==t?a:(...e)=>{t(...e),a(...e)}}function e(t,a,e){return null==a?e:(...n)=>{let r=a(...n);return t(r)?r:e(...n)}}var n=t=>!0===t,r=t=>void 0!==t,s=t=>null!=t,l=new Set;function o(t){for(let a of t)l.has(a.name)||(l.add(a.name),a.install())}function u(a){let e=a.$features;if(null!=t.bt&&Array.isArray(e)){let a=e.filter(t=>!l.has(t));if(a.length>0)return t.bt(a)}}function f(t,a){if(!l.has(t))throw new Error(`[@wcstack/state] [wcs/feature-not-installed] ${a} needs the add-on @wcstack/state/features/${t}`)}function i(a,e,n){throw new Error(`[@wcstack/state] ${a}${t.Lo?.(a,e,n)??""}`)}export{t as a,a as b,e as c,n as d,r as e,s as f,o as g,u as h,f as i,i as j};
2
+ //# sourceMappingURL=chunk-BGUJ3HF6.js.map
@@ -0,0 +1,2 @@
1
+ import{b as t,c as e,d as s}from"./chunk-DOWWBZVS.js";import{n as i,o as n}from"./chunk-NMOSSDKJ.js";import{f as o}from"./chunk-F3DVWVH3.js";import{a,b as r}from"./chunk-CIBJLAA3.js";import{a as l,b as c}from"./chunk-UBGJGMSG.js";import{a as h,h as u,i as d}from"./chunk-BGUJ3HF6.js";var m=0,f=new WeakMap;function p(t,e=t.getRootNode()){f.set(e,[...f.get(e)??[],t].filter((t,e,s)=>t.isConnected&&s.lastIndexOf(t)===e))}function b(t){let e=f.get(t)??[],s=e.filter(e=>e.getRootNode()===t);return Promise.any(s.map(t=>t.initializePromise.then(()=>t.V||t.connectedCallbackPromise))).then(()=>{},i=>s.length?f.get(t)!==e?b(t):Promise.reject(i.errors[0]):void 0)}var g=typeof HTMLElement>"u"?class{}:HTMLElement,w=class extends g{constructor(){super(),this.engine=null,this.jn=!1,this.ze=!1,this.U=null,this.Xe=null,this.loaded=!1,this.un=null,this.connectedCallbackPromise=new Promise((t,e)=>{this.cn=t,this.Eo=e}),this.connectedCallbackPromise.catch(()=>{}),this.initializePromise=new Promise(t=>{this.an=t})}static{this.getBindingsReady=b}static{this.hasConnectedCallbackPromise=!0}connectedCallback(){if(this.jn){if(null!==this.Xe)return void this.Xe.Ge();p(this);let e=this.engine;if(null!==e){let s=e.root;s===this.getRootNode()&&!i.has(s)&&i.set(s,e),t(),h.element?.(e,"back"),this.No("$connectedCallback",50,()=>{this.isConnected&&h.element?.(e,"connected")})}return}this.jn=!0;let e=this.getRootNode(),s=h.ct?.(this,e);if(s)return this.Xe=s,!s.xo&&this.parentNode instanceof ShadowRoot&&p(this),void(void 0===s.bt?this.Ro():s.bt()).then(t=>(this.loaded=!0,s.start(t,()=>this.Po()))).then(()=>{this.an(),this.cn()},t=>this.xt(t,s.xo));this.start(e),p(this)}disconnectedCallback(){if(null!==this.Xe)return void this.Xe.Ln();let t=this.engine;if(null===t)return;let e=t.root;i.get(e)===t&&i.delete(e),p(this,e),this.No("$disconnectedCallback",51),h.element?.(t,"disconnected")}setInitialState(t){if(this.ze&&c(14),this.loaded)this.Xe.reset(t);else if(null===this.engine)if(null!==this.un){let e=this.un;this.un=null,e(t)}else this.U=t;else this.engine.reset(t)}createState(t,e){let s=this.engine;null===s&&c(15),"readonly"===t&&s.Be++;try{e(s.proxy)}finally{"readonly"===t&&s.Be--}}async createStateAsync(t,e){let s=this.engine;null===s&&c(15),await e("writable"===t?s.proxy:new Proxy(s.proxy,{get(t,e,s){let i=Reflect.get(t,e,s);return"$setAll"===e||"$resolve"===e?(...t)=>(t.length>2&&c(8),i(...t)):i},set(){c(8)}}))}async Ro(){await 0;let t=this.getAttribute("state");if(null!==t){let e=e=>[...e.querySelectorAll('script[type="application/json"]')].find(e=>e.id===t),s=e(this.getRootNode())??e(document);return void 0===s?Promise.reject(new Error(`[@wcstack/state] ${l(16,[t])}`)):Promise.resolve(JSON.parse(s.textContent||"{}"))}let e=this.getAttribute("src");if(null!==e)return async function(t){let e=new URL(t,document.baseURI).href;if(/\.json(?:[?#]|$)/.test(e)){let s=await fetch(e);return s.ok||c(13,[t,s.status]),await s.json()}return(await(import(globalThis[Symbol.for("wcstack.ssr.resolveModule")]?.(e)??e))).default??{}}(e);let s=this.getAttribute("json");if(null!==s)return Promise.resolve(JSON.parse(s));let i=this.querySelector('script[type="module"]');return null!==i?async function(t){let e=!1,s=t=>{t.effectiveDirective.startsWith("script-src")&&(e=!0)};document.addEventListener("securitypolicyviolation",s);let i="function"==typeof URL.createObjectURL,n=i?URL.createObjectURL(new Blob([t.text],{type:"application/javascript"})):"data:text/javascript;charset=utf-8,"+encodeURIComponent(`${t.text}\n//${++m}`);try{return(await(import(n))).default??{}}catch(t){throw await new Promise(t=>setTimeout(t)),new Error(`[@wcstack/state] ${e?l(42):l(43,[t instanceof Error?t.message:String(t)])}`,{cause:t})}finally{document.removeEventListener("securitypolicyviolation",s),i&&URL.revokeObjectURL(n)}}(i):null!==this.U?Promise.resolve(this.U):new Promise(t=>{this.un=t})}async start(e){try{let a=e.host;(this.hasAttribute("mount")||this.hasAttribute("bind-component")||a?.hasAttribute("data-wc-definition"))&&d("scopes","<wcs-state>");let r=await this.Ro(),l=u(r);if(l&&await l,this.getRootNode()!==e)return this.U=r,this.jn=!1,void(this.isConnected&&this.connectedCallback());this.hasAttribute("enable-ssr")&&d("ssr","enable-ssr");let m=i.get(e)?.element;m?.isConnected&&(m.V||m.Xe)&&c(47);let f=new o(r,new s);f.element=this,this.engine=f,h.element?.(f,"mounting"),n(f,e),t(),f.En(),this.Po(),await f.Se("$connectedCallback"),this.isConnected&&h.element?.(f,"connected"),this.cn()}catch(t){this.ze=!this.V,this.xt(t)}}Po(){this.V=!0,this.an()}xt(t,e){this.qe(this.V?50:49,t),this.an(),e?this.cn():this.Eo(t)}qe(t,e){let s=["mount","bind-component","state","src"].flatMap(t=>this.hasAttribute(t)?[t,this.getAttribute(t)]:[]);console.error(`[@wcstack/state] ${l(t,[this.localName,...s])}`,e)}No(t,e,s){(async()=>this.engine.Se(t))().then(s,t=>this.qe(e,t))}},y=[];function v(){return(y=y.filter(t=>t.deref())).map(t=>t.deref())}function k(t,s){t&&r(t),function(t=customElements){e(),v().includes(t)||y.push(new WeakRef(t));let s=a.tagNames.state;void 0===t.get(s)&&t.define(s,class extends w{}),h.To?.(t)}(s)}var R=t=>b(t);export{b as a,g as b,v as c,k as d,R as e};
2
+ //# sourceMappingURL=chunk-BKLFDVOP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["loads","readyByRoot","WeakMap","enroll","el","root","getRootNode","set","get","filter","e","i","a","isConnected","lastIndexOf","getBindingsReady","list","els","Promise","any","map","initializePromise","then","bound","connectedCallbackPromise","length","reject","errors","HTMLElementBase","HTMLElement","WcsState","constructor","super","this","engine","started","failed","initial","claimed","loaded","receiveInitial","resolve","resolveConnected","rejectConnected","catch","resolveInitialize","hasConnectedCallbackPromise","connectedCallback","connected","engines","has","drainBinds","hooks","element","rerun","claim","lenient","parentNode","ShadowRoot","load","loadState","state","start","built","fail","disconnectedCallback","disconnected","delete","setInitialState","raise","reset","receive","createState","mutability","callback","readonlyDepth","proxy","createStateAsync","Proxy","t","k","receiver","v","Reflect","id","getAttribute","find","r","querySelectorAll","x","script","document","Error","text","JSON","parse","textContent","src","async","url","URL","baseURI","href","test","res","fetch","ok","status","json","globalThis","Symbol","for","default","loadSrc","querySelector","blocked","seen","effectiveDirective","startsWith","addEventListener","blob","createObjectURL","Blob","type","encodeURIComponent","setTimeout","message","String","cause","removeEventListener","revokeObjectURL","loadInnerScript","host","hasAttribute","requireFeature","loading","loadFeatures","other","Engine","DirtyStrategy","mount","watchRendered","callHook","report","at","flatMap","n","console","error","localName","name","refs","registries","deref","bootstrapState","partial","registry","setConfig","customElements","installBinder","includes","push","WeakRef","tag","config","tagNames","define","tags","buildBindings","R","j","I","z","q"],"sources":["../../../src/element.ts"],"sourcesContent":["import type { IWritableConfig } from \"./public/types\";\nimport { Engine } from \"./engine\";\nimport { engines, mount } from \"./dom/mount\";\nimport { drainBinds, installBinder } from \"./dom/binder\";\nimport { DirtyStrategy } from \"./strategy/dirty\";\nimport { config, setConfig } from \"./config\";\nimport type { Strategy } from \"./strategy/types\";\nimport { raise, M, text } from \"./messages\";\nimport { hooks, loadFeatures, requireFeature, type Claimed } from \"./hooks\";\n\nlet makeStrategy: () => Strategy = () => new DirtyStrategy();\n\n/** Chooses the invalidation strategy of every engine created from now on. */\nexport function configure(factory: () => Strategy): void {\n makeStrategy = factory;\n}\n\nlet loads = 0;\n\nasync function loadInnerScript(script: HTMLScriptElement): Promise<Record<string, any>> {\n // an import a Content-Security-Policy blocked rejects without saying why: the violation event\n // is the only witness (docs/csp.md §9)\n let blocked = false;\n const seen = (e: SecurityPolicyViolationEvent): void => {\n if (e.effectiveDirective.startsWith(\"script-src\")) blocked = true;\n };\n document.addEventListener(\"securitypolicyviolation\", seen);\n // a server (@wcstack/server) removes createObjectURL: a data: URL, unique so no load is cached\n const blob = typeof URL.createObjectURL === \"function\";\n const url = blob\n ? URL.createObjectURL(new Blob([script.text], { type: \"application/javascript\" }))\n : \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(`${script.text}\\n//${++loads}`);\n try {\n const mod = await import(/* @vite-ignore */ url);\n return (mod.default ?? {}) as Record<string, any>;\n } catch (e) {\n // Firefox fires the violation a task after the rejection (Chromium and WebKit before it)\n await new Promise((r) => setTimeout(r));\n throw new Error(`[@wcstack/state] ${blocked ? text(M.InlineBlocked) : text(M.InlineFailed, [e instanceof Error ? e.message : String(e)])}`, { cause: e });\n } finally {\n document.removeEventListener(\"securitypolicyviolation\", seen);\n if (blob) URL.revokeObjectURL(url);\n }\n}\n\nasync function loadSrc(src: string): Promise<Record<string, any>> {\n const url = new URL(src, document.baseURI).href;\n if (/\\.json(?:[?#]|$)/.test(url)) {\n const res = await fetch(url);\n if (!res.ok) raise(M.LoadFailed, [src, res.status]);\n return (await res.json()) as Record<string, any>;\n }\n // on the server, the renderer's local module for the URL (protocol/ssr-snapshot.ts, resolveModule):\n // Node's loader reads no http: URL\n const mod = await import(/* @vite-ignore */ (globalThis as any)[Symbol.for(\"wcstack.ssr.resolveModule\")]?.(url) ?? url);\n return (mod.default ?? {}) as Record<string, any>;\n}\n\n/**\n * The root `<wcs-state>` elements of each root node (and the one a component mount or a DCC definition\n * has in its shadow root): a new list whenever one connects, without the ones no longer in the page.\n */\nconst readyByRoot = new WeakMap<Node, WcsState[]>();\n\n/**\n * Puts `el` among the `<wcs-state>` elements of `root` (a new list, without the ones that left) — or,\n * taken out of it, takes it off: the list holds nothing of a page that went.\n */\nfunction enroll(el: WcsState, root: Node = el.getRootNode()): void {\n readyByRoot.set(root, [...(readyByRoot.get(root) ?? []), el].filter((e, i, a) => e.isConnected && a.lastIndexOf(e) === i));\n}\n\n/**\n * Resolves when the bindings of `root` are built — by any `<wcs-state>` in it now, whatever its\n * `$connectedCallback` does then, as 3.x — and rejects, with the first failure, only when every one\n * failed before building them. A stray one (a second root, #47; one that fails to load) changes\n * nothing while another binds the root; one taken out of the page (or moved to another root) counts\n * no more (a root replaced: the new one decides). With none in it — none ever, or only ones that left —\n * it resolves at once: there is nothing to wait for (a page without state).\n */\nexport function getBindingsReady(root: Node): Promise<void> {\n const list = readyByRoot.get(root) ?? [];\n const els = list.filter((e) => e.getRootNode() === root);\n return Promise.any(els.map((el) => el.initializePromise.then((): unknown => el.bound || el.connectedCallbackPromise))).then(\n () => {},\n // none, or every one failed: one connected since (the list is a new one) may still bind the root\n // (quoted: `errors` is a name the build shortens, an AggregateError's is not)\n (e: AggregateError) => (els.length ? readyByRoot.get(root) !== list ? getBindingsReady(root) : Promise.reject(e[\"errors\"][0]) : undefined),\n );\n}\n\n/**\n * The base of the package's elements: HTMLElement, or — where there is none (Node without a DOM)\n * — an inert class, so the entries can be imported headless (a tool reading the manifest, a\n * server framework importing at the top level), as 3.x. Making an element stays a browser's.\n */\nexport const HTMLElementBase = (typeof HTMLElement === \"undefined\" ? class {} : HTMLElement) as typeof HTMLElement;\n\n/**\n * `<wcs-state>` — one engine per element, bound to the element's root node.\n * State resolution order: `state` (id of a JSON script) → `src` → `json` → inner\n * `<script type=\"module\">` → wait for `setInitialState()`.\n */\nexport class WcsState extends HTMLElementBase {\n static getBindingsReady = getBindingsReady;\n /** Servers (@wcstack/server) wait on connectedCallbackPromise when this is set. */\n static hasConnectedCallbackPromise = true;\n\n engine: Engine | null = null;\n readonly connectedCallbackPromise: Promise<void>;\n /**\n * Resolves once the state is loaded and bound (before `$connectedCallback`) — and also when\n * initialization fails: the failure is delivered on connectedCallbackPromise.\n */\n readonly initializePromise: Promise<void>;\n private resolveInitialize!: () => void;\n private resolveConnected!: () => void;\n private rejectConnected!: (e: unknown) => void;\n private started = false;\n /** Initialization failed before the page was bound: `setInitialState` refuses (#14). */\n private failed = false;\n private initial: Record<string, any> | null = null;\n /** Taken over by an add-on (a volume, a DCC definition): it never becomes a root. */\n private claimed: Claimed | null = null;\n /** A claimed element's state is loaded: `setInitialState` from now on is the add-on's re-set. */\n private loaded = false;\n /** The root's bindings are built (getBindingsReady resolves, whatever `$connectedCallback` does). */\n bound?: boolean;\n private receiveInitial: ((state: Record<string, any>) => void) | null = null;\n\n constructor() {\n super();\n this.connectedCallbackPromise = new Promise<void>((resolve, reject) => {\n this.resolveConnected = resolve;\n this.rejectConnected = reject;\n });\n this.connectedCallbackPromise.catch(() => {});\n this.initializePromise = new Promise<void>((resolve) => {\n this.resolveInitialize = resolve;\n });\n }\n\n connectedCallback(): void {\n if (this.started) {\n if (this.claimed !== null) {\n this.claimed.connected();\n return;\n }\n enroll(this);\n const engine = this.engine;\n if (engine !== null) {\n // back in the page: it holds its root again (unless another <wcs-state> bound it meanwhile),\n // binds what was handed over while it was out, and the add-ons hear of it (the volumes that\n // connected meanwhile graft) — then $connectedCallback runs again\n const root = engine.root;\n if (root === this.getRootNode() && !engines.has(root)) engines.set(root, engine);\n drainBinds();\n hooks.element?.(engine, \"back\");\n this.rerun(\"$connectedCallback\", M.ConnectedFailed, () => {\n if (this.isConnected) hooks.element?.(engine, \"connected\");\n });\n }\n return;\n }\n this.started = true;\n const root = this.getRootNode();\n const claimed = hooks.claim?.(this, root);\n if (claimed) {\n this.claimed = claimed;\n // the `<wcs-state>` of the shadow root it binds (a component's, a DCC definition's) is that\n // root's, as 3.x: getBindingsReady there waits for it — until its bindings are built, as a\n // root's — and fails with it (a volume never fails)\n if (!claimed.lenient && this.parentNode instanceof ShadowRoot) enroll(this);\n void (claimed.load === undefined ? this.loadState() : claimed.load()).then((state) => {\n this.loaded = true;\n return claimed.start(state, () => this.built());\n }).then(() => {\n this.resolveInitialize();\n this.resolveConnected();\n }, (e) => this.fail(e, claimed.lenient));\n return;\n }\n void this.start(root);\n enroll(this);\n }\n\n disconnectedCallback(): void {\n if (this.claimed !== null) {\n this.claimed.disconnected();\n return;\n }\n const engine = this.engine;\n if (engine === null) return;\n // out of the page, it lets go of its root (it holds it again when it is back): what outlives the\n // page's content — its root node, the document — does not keep its state and the DOM it bound\n // (a root that failed before its mount has none: enroll takes the root it is in now)\n const root = engine.root;\n if (engines.get(root!) === engine) engines.delete(root!);\n enroll(this, root);\n this.rerun(\"$disconnectedCallback\", M.DisconnectedFailed);\n hooks.element?.(engine, \"disconnected\");\n }\n\n /**\n * Supplies the initial state; on an initialized element, replaces the whole state and\n * re-applies every binding to it before returning (not a write: no `$renderedCallback`).\n */\n setInitialState(state: Record<string, any>): void {\n if (this.failed) raise(M.ElementFailed);\n // (until a claimed element's state is loaded, this supplies it like a root's)\n if (this.loaded) {\n this.claimed!.reset(state);\n return;\n }\n if (this.engine !== null) {\n this.engine.reset(state);\n return;\n }\n if (this.receiveInitial !== null) {\n const receive = this.receiveInitial;\n this.receiveInitial = null;\n receive(state);\n } else {\n this.initial = state;\n }\n }\n\n /** Runs `callback` with a state proxy; its writes are applied in the next drain. */\n createState(mutability: \"readonly\" | \"writable\", callback: (state: Record<string, any>) => void): void {\n const engine = this.engine;\n if (engine === null) raise(M.NotInitialized);\n if (mutability === \"readonly\") engine.readonlyDepth++;\n try {\n callback(engine.proxy);\n } finally {\n if (mutability === \"readonly\") engine.readonlyDepth--;\n }\n }\n\n /** `createState` whose callback may await; a readonly proxy stays readonly across its awaits. */\n async createStateAsync(mutability: \"readonly\" | \"writable\", callback: (state: Record<string, any>) => Promise<void>): Promise<void> {\n const engine = this.engine;\n if (engine === null) raise(M.NotInitialized);\n await callback(mutability === \"writable\" ? engine.proxy : new Proxy(engine.proxy, {\n // as in createState(\"readonly\"), the writes of $setAll and $resolve (path, indexes, value) refuse;\n // read with this view as the receiver, a method comes as it is and runs on this view\n get(t, k, receiver) {\n const v = Reflect.get(t, k, receiver);\n return k === \"$setAll\" || k === \"$resolve\" ? (...a: unknown[]) => (a.length > 2 && raise(M.Readonly), v(...a)) : v;\n },\n set() {\n raise(M.Readonly);\n },\n }));\n }\n\n private async loadState(): Promise<Record<string, any>> {\n // a parser that inserts the element before its children (a server render) has added them by now\n await 0;\n const id = this.getAttribute(\"state\");\n if (id !== null) {\n // a JSON script of that id (an element of user content with the same id, earlier, is not it)\n const find = (r: Node): HTMLScriptElement | undefined =>\n [...(r as Document).querySelectorAll<HTMLScriptElement>('script[type=\"application/json\"]')].find((x) => x.id === id);\n const script = find(this.getRootNode()) ?? find(document);\n if (script === undefined) return Promise.reject(new Error(`[@wcstack/state] ${text(M.NoScript, [id])}`));\n return Promise.resolve(JSON.parse(script.textContent || \"{}\"));\n }\n const src = this.getAttribute(\"src\");\n if (src !== null) return loadSrc(src);\n const json = this.getAttribute(\"json\");\n if (json !== null) return Promise.resolve(JSON.parse(json));\n const script = this.querySelector('script[type=\"module\"]') as HTMLScriptElement | null;\n if (script !== null) return loadInnerScript(script);\n if (this.initial !== null) return Promise.resolve(this.initial);\n return new Promise((resolve) => {\n this.receiveInitial = resolve;\n });\n }\n\n private async start(root: Node): Promise<void> {\n try {\n // what an add-on serves: a volume, a component mount, a DCC definition, server rendering\n const host = (root as ShadowRoot).host;\n if (this.hasAttribute(\"mount\") || this.hasAttribute(\"bind-component\") || host?.hasAttribute(\"data-wc-definition\")) {\n requireFeature(\"scopes\", \"<wcs-state>\");\n }\n const state = await this.loadState();\n const loading = loadFeatures(state);\n if (loading) await loading;\n // taken out of its root while it loaded (the page's content replaced, or moved to another root):\n // nothing is mounted on the root it left. It starts again where it is now, or when it connects\n // again. A state given by setInitialState() is kept for that; a state= / src= / json= / inline\n // script source is read again (a fetch runs again, an inline module is evaluated again)\n if (this.getRootNode() !== root) {\n this.initial = state;\n this.started = false;\n if (this.isConnected) this.connectedCallback();\n return;\n }\n if (this.hasAttribute(\"enable-ssr\")) requireFeature(\"ssr\", \"enable-ssr\");\n // one state tree per root: another <wcs-state> already bound this root (and still does —\n // whatever its $connectedCallback did then), or a component's took it\n const other = engines.get(root)?.element as WcsState | undefined;\n if (other?.isConnected && (other.bound || other.claimed)) raise(M.SecondRoot);\n const engine = new Engine(state, makeStrategy());\n engine.element = this;\n this.engine = engine;\n hooks.element?.(engine, \"mounting\");\n mount(engine, root as Document | ShadowRoot);\n drainBinds();\n engine.watchRendered();\n this.built();\n await engine.callHook(\"$connectedCallback\");\n if (this.isConnected) hooks.element?.(engine, \"connected\");\n this.resolveConnected();\n } catch (e) {\n // (a root that bound its page and whose $connectedCallback then failed has not: re-set stays open)\n this.failed = !this.bound;\n this.fail(e);\n }\n }\n\n /** The bindings are built (before `$connectedCallback`): getBindingsReady resolves, initializePromise too. */\n private built(): void {\n this.bound = true;\n this.resolveInitialize();\n }\n\n /**\n * Initialization failed: reported once, the element (and where its state comes from) before what\n * was thrown, as 3.5 — `<wcs-state src=\"./state.js\"> failed to initialize.`, or, once its\n * bindings were built, `… $connectedCallback failed.` — and connectedCallbackPromise rejects with\n * it, or resolves for a claim that is `lenient` (a volume).\n */\n private fail(e: unknown, lenient?: boolean): void {\n this.report(this.bound ? M.ConnectedFailed : M.InitFailed, e);\n this.resolveInitialize();\n if (lenient) this.resolveConnected();\n else this.rejectConnected(e);\n }\n\n /** Reports a failure once: the element (and where its state comes from), then what was thrown. */\n private report(id: M, e: unknown): void {\n const at = [\"mount\", \"bind-component\", \"state\", \"src\"].flatMap((n) => (this.hasAttribute(n) ? [n, this.getAttribute(n)] : []));\n console.error(`[@wcstack/state] ${text(id, [this.localName, ...at])}`, e);\n }\n\n /**\n * Runs a lifecycle callback of a root that connected before (on reconnect, on disconnect) at once: a\n * failure — thrown or rejected — is reported as a first connection's is, never thrown out of the\n * element's callback.\n */\n private rerun(name: string, id: M, then?: () => void): void {\n void (async () => this.engine!.callHook(name))().then(then, (e) => this.report(id, e));\n }\n}\n\n/**\n * The registries `<wcs-state>` was defined in: an add-on installed later defines its tags there\n * too. Weak: a server creates a registry per render, and holding them would keep every render's\n * registry (and every constructor defined in it) alive.\n */\nlet refs: WeakRef<CustomElementRegistry>[] = [];\n\n/**\n * The registries still alive (dead references are dropped). A registry deref() returned stays\n * alive until the end of this job, so the second deref() of each kept reference finds it.\n */\nexport function registries(): CustomElementRegistry[] {\n refs = refs.filter((r) => r.deref());\n return refs.map((r) => r.deref()!);\n}\n\n/**\n * Registers `<wcs-state>` (and the installed add-ons' tags) in `registry` — a scoped registry\n * does not inherit the global one, so a tree using one needs its own definitions.\n */\nexport function define(registry: CustomElementRegistry = customElements): void {\n installBinder();\n if (!registries().includes(registry)) refs.push(new WeakRef(registry));\n const tag = config.tagNames.state;\n if (registry.get(tag) === undefined) registry.define(tag, class extends WcsState {});\n hooks.tags?.(registry);\n}\n\n/** Applies `config` and registers `<wcs-state>`. The core only: install the add-ons first. */\nexport function bootstrapState(partial?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (partial) setConfig(partial);\n define(registry);\n}\n\n/**\n * Waits for the bindings under `root` (3.x built them here; the new engine builds them when the\n * root's `<wcs-state>` loads its state, so this only waits — the same as getBindingsReady).\n */\nexport const buildBindings = (root: Document | ShadowRoot): Promise<void> => getBindingsReady(root);\n"],"mappings":"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","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- import{b as t}from"./chunk-GGSHXG7N.js";import{j as e}from"./chunk-7ZU3CLEG.js";var a={bindAttributeName:"data-wcs",commentForPrefix:"wcs-for",commentIfPrefix:"wcs-if",commentElseIfPrefix:"wcs-elseif",commentElsePrefix:"wcs-else",tagNames:{state:"wcs-state",ssr:"wcs-ssr"},locale:typeof document<"u"&&document.documentElement?.lang||"en",enableContractAnalyzer:!1};function r(e){let r=a,s=a.tagNames,n=Object.entries(e).filter(([,t])=>void 0!==t),o=Object.entries(e.tagNames??{}).filter(([,t])=>void 0!==t);for(let[e,a]of n){let s=r[e];(!Object.hasOwn(r,e)||null===a||typeof a!=typeof s||Array.isArray(a)!==Array.isArray(s))&&t(44,["bootstrapState",e])}for(let[e,a]of o)(!Object.hasOwn(s,e)||"string"!=typeof a)&&t(44,["bootstrapState",`tagNames.${e}`]);for(let[t,e]of n)"tagNames"!==t&&(r[t]=e);for(let[t,e]of o)s[t]=e}var s=()=>a,n=["toFixed","locale","upper","lower","capitalize","trim","slice","padStart","padEnd","repeat","reverse","truncate","join","round","floor","ceil","percent","unit","date","time","datetime","ymd","hms","add","sub","mul","div","mod","abs","clamp","int","float","defaults","coalesce","number","string","nullIfEmpty"],o=new Map,i=new Map;function f(t){for(let e of Object.keys(t))o.set(e,{...t[e]});i.clear()}function l(t){return o.has(t)}function c(a,r,s){let f=`${a}${function(t,e){return`${JSON.stringify(t)}${JSON.stringify(e)}`}(r,s)}`,l=i.get(f);if(typeof l<"u")return l;let c=o.get(a);void 0===c&&function(a,r){n.includes(a)&&e(`[wcs/filter-unknown] filter not found: ${a}. "${a}" is in the formats add-on — install it with installFeatures([formats]) from "@wcstack/state/features/formats".`,a,r),t(501,[a],a,r)}(a,o.keys());let[m,u]=c.arity;r.length<m&&t(601,[a,m,r.length]),r.length>u&&t(602,[a,u,r.length]);let d=c.factory(r,s);return i.set(f,d),d}export{a,r as b,s as c,n as d,f as e,l as f,c as g};
2
- //# sourceMappingURL=chunk-R5OJ52SF.js.map
1
+ import{b as t}from"./chunk-UBGJGMSG.js";import{j as e}from"./chunk-BGUJ3HF6.js";var a={bindAttributeName:"data-wcs",commentForPrefix:"wcs-for",commentIfPrefix:"wcs-if",commentElseIfPrefix:"wcs-elseif",commentElsePrefix:"wcs-else",tagNames:{state:"wcs-state",ssr:"wcs-ssr"},locale:typeof document<"u"&&document.documentElement?.lang||"en",enableContractAnalyzer:!1};function r(e){let r=a,s=a.tagNames,n=Object.entries(e).filter(([,t])=>void 0!==t),o=Object.entries(e.tagNames??{}).filter(([,t])=>void 0!==t);for(let[e,a]of n){let s=r[e];(!Object.hasOwn(r,e)||null===a||typeof a!=typeof s||Array.isArray(a)!==Array.isArray(s))&&t(44,["bootstrapState",e])}for(let[e,a]of o)(!Object.hasOwn(s,e)||"string"!=typeof a)&&t(44,["bootstrapState",`tagNames.${e}`]);for(let[t,e]of n)"tagNames"!==t&&(r[t]=e);for(let[t,e]of o)s[t]=e}var s=()=>a,n=["toFixed","locale","upper","lower","capitalize","trim","slice","padStart","padEnd","repeat","reverse","truncate","join","round","floor","ceil","percent","unit","date","time","datetime","ymd","hms","add","sub","mul","div","mod","abs","clamp","int","float","defaults","coalesce","number","string","nullIfEmpty","currency"],o=new Map,i=new Map;function f(t){for(let e of Object.keys(t))o.set(e,{...t[e]});i.clear()}function l(t){return o.has(t)}function c(a,r,s){let f=`${a}${function(t,e){return`${JSON.stringify(t)}${JSON.stringify(e)}`}(r,s)}`,l=i.get(f);if(typeof l<"u")return l;let c=o.get(a);void 0===c&&function(a,r){n.includes(a)&&e(`[wcs/filter-unknown] filter not found: ${a}. "${a}" is in the formats add-on — install it with installFeatures([formats]) from "@wcstack/state/features/formats".`,a,r),t(501,[a],a,r)}(a,o.keys());let[m,u]=c.arity;r.length<m&&t(601,[a,m,r.length]),r.length>u&&t(602,[a,u,r.length]);let d=c.factory(r,s);return i.set(f,d),d}export{a,r as b,s as c,n as d,f as e,l as f,c as g};
2
+ //# sourceMappingURL=chunk-CIBJLAA3.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["config","bindAttributeName","commentForPrefix","commentIfPrefix","commentElseIfPrefix","commentElsePrefix","tagNames","state","ssr","locale","document","documentElement","lang","enableContractAnalyzer","setConfig","partial","options","tags","given","Object","entries","filter","value","givenTags","tag","key","current","hasOwn","Array","isArray","raise","name","getConfig","FORMATS_FILTER_NAMES","definitions","Map","resolvedByKey","registerFilters","map","keys","set","clear","hasFilter","has","resolveFilter","literals","args","JSON","stringify","filterArgsKey","resolved","get","definition","known","includes","raiseError","unknownFilter","min","max","arity","length","filterFn","factory","c","x","b","y","A","O","h"],"sources":["../../../src/config.ts","../../../src/filters/registry.ts"],"sourcesContent":["import { raise, M } from \"./messages\";\n\n/**\n * Page-wide configuration (`bootstrapState(config)`): how this page spells wcstack markup (the tag\n * names, the binding attribute, the anchor comments — fixed before the first definition, the same\n * on the server) and the locale default. How a state tree behaves is its own `$behavior` (engine.ts).\n */\nexport interface Config {\n bindAttributeName: string;\n /** The text of a `for` template's anchor comment. */\n commentForPrefix: string;\n /** The texts of an `if` / `elseif` / `else` chain's anchor comments. */\n commentIfPrefix: string;\n commentElseIfPrefix: string;\n commentElsePrefix: string;\n tagNames: { state: string; ssr: string };\n locale: string;\n /** Opt-in `analyzeContract()` (dev time); off, it returns at once. */\n enableContractAnalyzer: boolean;\n}\n\nexport const config: Config = {\n bindAttributeName: \"data-wcs\",\n commentForPrefix: \"wcs-for\",\n commentIfPrefix: \"wcs-if\",\n commentElseIfPrefix: \"wcs-elseif\",\n commentElsePrefix: \"wcs-else\",\n tagNames: { state: \"wcs-state\", ssr: \"wcs-ssr\" },\n locale: typeof document !== \"undefined\" ? document.documentElement?.lang || \"en\" : \"en\",\n enableContractAnalyzer: false,\n};\n\nexport type PartialConfig = Partial<Omit<Config, \"tagNames\">> & { tagNames?: Partial<Config[\"tagNames\"]> };\n\n/**\n * Applies the options given; an undefined value is left out. An option `bootstrapState` does not\n * have (a key 4.0 moved to the state's `$behavior` or removed included), a value of another type\n * than its default (null, or an array for an object, included) or a tag name it does not define\n * throws, and then nothing is applied — the same rule as every package's bootstrap.\n */\nexport function setConfig(partial: PartialConfig): void {\n const options = config as unknown as Record<string, unknown>;\n const tags = config.tagNames as Record<string, string>;\n const given = Object.entries(partial).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partial.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n raise(M.OptionInvalid, [\"bootstrapState\", key]);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") raise(M.OptionInvalid, [\"bootstrapState\", `tagNames.${name}`]);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n}\n\n/** The current configuration (read-only view). */\nexport const getConfig = (): Readonly<Config> => config;\n","/**\n * filters/registry.ts — the filter registry, ported from `@wcstack/state` (`core/filterRegistry.ts`).\n *\n * The grammar (`path|filter(args)`) only produces names and arguments; the functions are looked up\n * here when the bindings are planned. The core set (`./core`) and the formats add-on (`./formats`)\n * each put their filters in with an install call; this module knows neither implementation, so a\n * page that skips the add-on does not carry its code.\n *\n * Differences from the source, all decided:\n * - one registry, not an input / output pair (the source registered the same table in both);\n * - no aliases (`inc dec fix uc lc cap pad rep rev null` are not carried over);\n * - every registered filter has arity bounds (the source allowed them to be absent);\n * - the core set is registered like any other (the source hard-wired `not` into the registry).\n */\nimport { raiseError } from \"../parser/raiseError\";\nimport { raise, M } from \"../messages\";\n\nexport type FilterFn = (value: unknown) => unknown;\n\n/**\n * Builds the function for one use of a filter. `options` are the argument texts (unquoted),\n * `literals` their typed values (requirement B9 — only filters that compare or return an argument\n * read them).\n */\nexport type FilterFactory = (options: string[], literals: readonly unknown[]) => FilterFn;\n\n/** A filter as an install call hands it to the registry: the factory and its [min, max] argument count (B3). */\nexport interface FilterDefinition {\n factory: FilterFactory;\n arity: readonly [number, number];\n}\n\n/**\n * The formats add-on's filters (37: up to 4.0.0-rc.3 the 23 display ones, then the core's\n * arithmetic, conversion and missing-value 14). Only the names live here (not the code), so that a\n * page without the add-on can still say where one of them comes from instead of calling it a typo.\n * A test keeps this list equal to the add-on's table.\n */\nexport const FORMATS_FILTER_NAMES: readonly string[] = [\n \"toFixed\", \"locale\",\n \"upper\", \"lower\", \"capitalize\", \"trim\", \"slice\", \"padStart\", \"padEnd\", \"repeat\", \"reverse\", \"truncate\", \"join\",\n \"round\", \"floor\", \"ceil\", \"percent\", \"unit\",\n \"date\", \"time\", \"datetime\", \"ymd\", \"hms\",\n \"add\", \"sub\", \"mul\", \"div\", \"mod\", \"abs\", \"clamp\", \"int\", \"float\", \"defaults\", \"coalesce\", \"number\", \"string\", \"nullIfEmpty\",\n];\n\n/**\n * A `Map`, not a plain object: bracket access on an object lets the `Object.prototype` members\n * through as filters (`|toString` / `|constructor` / `|valueOf`), which then fail with a\n * meaningless TypeError instead of `[wcs/filter-unknown]`.\n */\nconst definitions = new Map<string, FilterDefinition>();\n\n/** Name + arguments → the function already built for them (each is built once). */\nconst resolvedByKey = new Map<string, FilterFn>();\n\n/**\n * The key of one argument list: **both the raw texts and the typed values** (B3 / B9).\n * - Raw texts alone would make `defaults(0)` and `defaults('0')` the same `[\"0\"]`, sharing one\n * function between two filters of different types.\n * - Typed values alone would fold `1` / `1.0` / `01` / `+1` into the same number, although the\n * factories that read the raw text (`truncate` / `unit` / `join` / `ymd` / `padStart` …) answer\n * them differently.\n * - A structural key, never `args.join(\",\")`: `['a,b']` and `['a', 'b']` are different arguments.\n */\nexport function filterArgsKey(args: readonly string[], literals: readonly unknown[]): string {\n return `${JSON.stringify(args)}${JSON.stringify(literals)}`;\n}\n\n/** Called by the install functions. Idempotent — a name registered again replaces the previous one. */\nexport function registerFilters(map: Record<string, FilterDefinition>): void {\n for (const name of Object.keys(map)) {\n // a copy: the registry keeps what was registered\n definitions.set(name, { ...map[name] });\n }\n // A new registration can change the answers already built (a page installs once; tests and\n // tooling swap registrations)\n resolvedByKey.clear();\n}\n\nexport function hasFilter(name: string): boolean {\n return definitions.has(name);\n}\n\n/** The registered names, which the did-you-mean suggestion reads. */\nexport function knownFilterNames(): string[] {\n return [...definitions.keys()];\n}\n\n/** Drops the functions already built (tooling that clears its parser caches). */\nexport function clearFilterResolutionCache(): void {\n resolvedByKey.clear();\n}\n\n/**\n * `[wcs/filter-unknown]`. A formatting filter on a page without the formats add-on is not a typo:\n * that barrier is kept as full text, since it is met on pages without add-ons (the diagnostics\n * add-on adds the nearest name to either).\n */\nfunction unknownFilter(name: string, known: Iterable<string>): never {\n if (FORMATS_FILTER_NAMES.includes(name)) {\n raiseError(`[wcs/filter-unknown] filter not found: ${name}. \"${name}\" is in the formats add-on — install it with installFeatures([formats]) from \"@wcstack/state/features/formats\".`, name, known);\n }\n raise(M.FilterUnknown, [name], name, known);\n}\n\n/**\n * The function for one use of a filter (binding planning). An unknown name or a wrong argument count\n * fails here, by name — the parser never rejects a filter.\n */\nexport function resolveFilter(name: string, options: string[], literals: readonly unknown[]): FilterFn {\n const key = `${name}${filterArgsKey(options, literals)}`;\n const resolved = resolvedByKey.get(key);\n if (typeof resolved !== \"undefined\") {\n return resolved;\n }\n const definition = definitions.get(name);\n if (definition === undefined) {\n unknownFilter(name, definitions.keys());\n }\n // Same vocabulary as lint's wcs/filter-arity\n const [min, max] = definition.arity;\n if (options.length < min) raise(M.FilterTooFewArgs, [name, min, options.length]);\n if (options.length > max) raise(M.FilterTooManyArgs, [name, max, options.length]);\n const filterFn = definition.factory(options, literals);\n resolvedByKey.set(key, filterFn);\n return filterFn;\n}\n"],"mappings":"gFAqBO,IAAMA,EAAiB,CAC5BC,kBAAmB,WACnBC,iBAAkB,UAClBC,gBAAiB,SACjBC,oBAAqB,aACrBC,kBAAmB,WACnBC,SAAU,CAAEC,MAAO,YAAaC,IAAK,WACrCC,cAAeC,SAAa,KAAcA,SAASC,iBAAiBC,MAAQ,KAC5EC,wBAAwB,GAWnB,SAASC,EAAUC,GACxB,IAAMC,EAAUhB,EACViB,EAAOjB,EAAOM,SACdY,EAAQC,OAAOC,QAAQL,GAASM,OAAO,EAAE,CAAEC,UAAqB,IAAVA,GACtDC,EAAYJ,OAAOC,QAAQL,EAAQT,UAAY,CAAC,GAAGe,OAAO,EAAE,CAAEG,UAAiB,IAARA,GAC7E,QAAYC,EAAKH,KAAUJ,EAAO,CAChC,IAAMQ,EAAUV,EAAQS,KACnBN,OAAOQ,OAAOX,EAASS,IAAkB,OAAVH,UAAyBA,UAAiBI,GAAWE,MAAMC,QAAQP,KAAWM,MAAMC,QAAQH,KAC9HI,KAAuB,CAAC,iBAAkBL,GAE9C,CACA,QAAYM,EAAMP,KAAQD,IACnBJ,OAAOQ,OAAOV,EAAMc,IAAwB,iBAARP,IAAkBM,KAAuB,CAAC,iBAAkB,YAAYC,MAEnH,QAAYN,EAAKH,KAAUJ,EACb,aAARO,IACFT,EAAQS,GAAOH,GAGnB,QAAYS,EAAMP,KAAQD,EAAWN,EAAKc,GAAQP,CACpD,CAGO,IAAMQ,EAAY,IAAwBhC,ECzBpCiC,EAA0C,CACrD,UAAW,SACX,QAAS,QAAS,aAAc,OAAQ,QAAS,WAAY,SAAU,SAAU,UAAW,WAAY,OACxG,QAAS,QAAS,OAAQ,UAAW,OACrC,OAAQ,OAAQ,WAAY,MAAO,MACnC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,QAAS,MAAO,QAAS,WAAY,WAAY,SAAU,SAAU,eAQ3GC,EAAc,IAAIC,IAGlBC,EAAgB,IAAID,IAgBnB,SAASE,EAAgBC,GAC9B,QAAWP,KAAQZ,OAAOoB,KAAKD,GAE7BJ,EAAYM,IAAIT,EAAM,IAAKO,EAAIP,KAIjCK,EAAcK,OAChB,CAEO,SAASC,EAAUX,GACxB,OAAOG,EAAYS,IAAIZ,EACzB,CA4BO,SAASa,EAAcb,EAAcf,EAAmB6B,GAC7D,IAAMpB,EAAM,GAAGM,IA9CV,SAAuBe,EAAyBD,GACrD,MAAO,GAAGE,KAAKC,UAAUF,KAAQC,KAAKC,UAAUH,IAClD,CA4CwBI,CAAcjC,EAAS6B,KACvCK,EAAWd,EAAce,IAAI1B,GACnC,UAAWyB,EAAa,IACtB,OAAOA,EAET,IAAME,EAAalB,EAAYiB,IAAIpB,QAChB,IAAfqB,GAlBN,SAAuBrB,EAAcsB,GAC/BpB,EAAqBqB,SAASvB,IAChCwB,EAAW,0CAA0CxB,OAAUA,mHAAuHA,EAAMsB,GAE9LvB,MAAuB,CAACC,GAAOA,EAAMsB,EACvC,CAcIG,CAAczB,EAAMG,EAAYK,QAGlC,IAAOkB,EAAKC,GAAON,EAAWO,MAC1B3C,EAAQ4C,OAASH,GAAK3B,MAA0B,CAACC,EAAM0B,EAAKzC,EAAQ4C,SACpE5C,EAAQ4C,OAASF,GAAK5B,MAA2B,CAACC,EAAM2B,EAAK1C,EAAQ4C,SACzE,IAAMC,EAAWT,EAAWU,QAAQ9C,EAAS6B,GAC7C,OAAAT,EAAcI,IAAIf,EAAKoC,GAChBA,CACT,QAAAE,EAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC","ignoreList":[]}
1
+ {"version":3,"names":["config","bindAttributeName","commentForPrefix","commentIfPrefix","commentElseIfPrefix","commentElsePrefix","tagNames","state","ssr","locale","document","documentElement","lang","enableContractAnalyzer","setConfig","partial","options","tags","given","Object","entries","filter","value","givenTags","tag","key","current","hasOwn","Array","isArray","raise","name","getConfig","FORMATS_FILTER_NAMES","definitions","Map","resolvedByKey","registerFilters","map","keys","set","clear","hasFilter","has","resolveFilter","literals","args","JSON","stringify","filterArgsKey","resolved","get","definition","known","includes","raiseError","unknownFilter","min","max","arity","length","filterFn","factory","c","x","b","y","A","O","h"],"sources":["../../../src/config.ts","../../../src/filters/registry.ts"],"sourcesContent":["import { raise, M } from \"./messages\";\n\n/**\n * Page-wide configuration (`bootstrapState(config)`): how this page spells wcstack markup (the tag\n * names, the binding attribute, the anchor comments — fixed before the first definition, the same\n * on the server) and the locale default. How a state tree behaves is its own `$behavior` (engine.ts).\n */\nexport interface Config {\n bindAttributeName: string;\n /** The text of a `for` template's anchor comment. */\n commentForPrefix: string;\n /** The texts of an `if` / `elseif` / `else` chain's anchor comments. */\n commentIfPrefix: string;\n commentElseIfPrefix: string;\n commentElsePrefix: string;\n tagNames: { state: string; ssr: string };\n locale: string;\n /** Opt-in `analyzeContract()` (dev time); off, it returns at once. */\n enableContractAnalyzer: boolean;\n}\n\nexport const config: Config = {\n bindAttributeName: \"data-wcs\",\n commentForPrefix: \"wcs-for\",\n commentIfPrefix: \"wcs-if\",\n commentElseIfPrefix: \"wcs-elseif\",\n commentElsePrefix: \"wcs-else\",\n tagNames: { state: \"wcs-state\", ssr: \"wcs-ssr\" },\n locale: typeof document !== \"undefined\" ? document.documentElement?.lang || \"en\" : \"en\",\n enableContractAnalyzer: false,\n};\n\nexport type PartialConfig = Partial<Omit<Config, \"tagNames\">> & { tagNames?: Partial<Config[\"tagNames\"]> };\n\n/**\n * Applies the options given; an undefined value is left out. An option `bootstrapState` does not\n * have (a key 4.0 moved to the state's `$behavior` or removed included), a value of another type\n * than its default (null, or an array for an object, included) or a tag name it does not define\n * throws, and then nothing is applied — the same rule as every package's bootstrap.\n */\nexport function setConfig(partial: PartialConfig): void {\n const options = config as unknown as Record<string, unknown>;\n const tags = config.tagNames as Record<string, string>;\n const given = Object.entries(partial).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partial.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n raise(M.OptionInvalid, [\"bootstrapState\", key]);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") raise(M.OptionInvalid, [\"bootstrapState\", `tagNames.${name}`]);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n}\n\n/** The current configuration (read-only view). */\nexport const getConfig = (): Readonly<Config> => config;\n","/**\n * filters/registry.ts — the filter registry, ported from `@wcstack/state` (`core/filterRegistry.ts`).\n *\n * The grammar (`path|filter(args)`) only produces names and arguments; the functions are looked up\n * here when the bindings are planned. The core set (`./core`) and the formats add-on (`./formats`)\n * each put their filters in with an install call; this module knows neither implementation, so a\n * page that skips the add-on does not carry its code.\n *\n * Differences from the source, all decided:\n * - one registry, not an input / output pair (the source registered the same table in both);\n * - no aliases (`inc dec fix uc lc cap pad rep rev null` are not carried over);\n * - every registered filter has arity bounds (the source allowed them to be absent);\n * - the core set is registered like any other (the source hard-wired `not` into the registry).\n */\nimport { raiseError } from \"../parser/raiseError\";\nimport { raise, M } from \"../messages\";\n\nexport type FilterFn = (value: unknown) => unknown;\n\n/**\n * Builds the function for one use of a filter. `options` are the argument texts (unquoted),\n * `literals` their typed values (requirement B9 — only filters that compare or return an argument\n * read them).\n */\nexport type FilterFactory = (options: string[], literals: readonly unknown[]) => FilterFn;\n\n/** A filter as an install call hands it to the registry: the factory and its [min, max] argument count (B3). */\nexport interface FilterDefinition {\n factory: FilterFactory;\n arity: readonly [number, number];\n}\n\n/**\n * The formats add-on's filters (37: up to 4.0.0-rc.3 the 23 display ones, then the core's\n * arithmetic, conversion and missing-value 14). Only the names live here (not the code), so that a\n * page without the add-on can still say where one of them comes from instead of calling it a typo.\n * A test keeps this list equal to the add-on's table.\n */\nexport const FORMATS_FILTER_NAMES: readonly string[] = [\n \"toFixed\", \"locale\",\n \"upper\", \"lower\", \"capitalize\", \"trim\", \"slice\", \"padStart\", \"padEnd\", \"repeat\", \"reverse\", \"truncate\", \"join\",\n \"round\", \"floor\", \"ceil\", \"percent\", \"unit\",\n \"date\", \"time\", \"datetime\", \"ymd\", \"hms\",\n \"add\", \"sub\", \"mul\", \"div\", \"mod\", \"abs\", \"clamp\", \"int\", \"float\", \"defaults\", \"coalesce\", \"number\", \"string\", \"nullIfEmpty\",\n \"currency\",\n];\n\n/**\n * A `Map`, not a plain object: bracket access on an object lets the `Object.prototype` members\n * through as filters (`|toString` / `|constructor` / `|valueOf`), which then fail with a\n * meaningless TypeError instead of `[wcs/filter-unknown]`.\n */\nconst definitions = new Map<string, FilterDefinition>();\n\n/** Name + arguments → the function already built for them (each is built once). */\nconst resolvedByKey = new Map<string, FilterFn>();\n\n/**\n * The key of one argument list: **both the raw texts and the typed values** (B3 / B9).\n * - Raw texts alone would make `defaults(0)` and `defaults('0')` the same `[\"0\"]`, sharing one\n * function between two filters of different types.\n * - Typed values alone would fold `1` / `1.0` / `01` / `+1` into the same number, although the\n * factories that read the raw text (`truncate` / `unit` / `join` / `ymd` / `padStart` …) answer\n * them differently.\n * - A structural key, never `args.join(\",\")`: `['a,b']` and `['a', 'b']` are different arguments.\n */\nexport function filterArgsKey(args: readonly string[], literals: readonly unknown[]): string {\n return `${JSON.stringify(args)}${JSON.stringify(literals)}`;\n}\n\n/** Called by the install functions. Idempotent — a name registered again replaces the previous one. */\nexport function registerFilters(map: Record<string, FilterDefinition>): void {\n for (const name of Object.keys(map)) {\n // a copy: the registry keeps what was registered\n definitions.set(name, { ...map[name] });\n }\n // A new registration can change the answers already built (a page installs once; tests and\n // tooling swap registrations)\n resolvedByKey.clear();\n}\n\nexport function hasFilter(name: string): boolean {\n return definitions.has(name);\n}\n\n/** The registered names, which the did-you-mean suggestion reads. */\nexport function knownFilterNames(): string[] {\n return [...definitions.keys()];\n}\n\n/** Drops the functions already built (tooling that clears its parser caches). */\nexport function clearFilterResolutionCache(): void {\n resolvedByKey.clear();\n}\n\n/**\n * `[wcs/filter-unknown]`. A formatting filter on a page without the formats add-on is not a typo:\n * that barrier is kept as full text, since it is met on pages without add-ons (the diagnostics\n * add-on adds the nearest name to either).\n */\nfunction unknownFilter(name: string, known: Iterable<string>): never {\n if (FORMATS_FILTER_NAMES.includes(name)) {\n raiseError(`[wcs/filter-unknown] filter not found: ${name}. \"${name}\" is in the formats add-on — install it with installFeatures([formats]) from \"@wcstack/state/features/formats\".`, name, known);\n }\n raise(M.FilterUnknown, [name], name, known);\n}\n\n/**\n * The function for one use of a filter (binding planning). An unknown name or a wrong argument count\n * fails here, by name — the parser never rejects a filter.\n */\nexport function resolveFilter(name: string, options: string[], literals: readonly unknown[]): FilterFn {\n const key = `${name}${filterArgsKey(options, literals)}`;\n const resolved = resolvedByKey.get(key);\n if (typeof resolved !== \"undefined\") {\n return resolved;\n }\n const definition = definitions.get(name);\n if (definition === undefined) {\n unknownFilter(name, definitions.keys());\n }\n // Same vocabulary as lint's wcs/filter-arity\n const [min, max] = definition.arity;\n if (options.length < min) raise(M.FilterTooFewArgs, [name, min, options.length]);\n if (options.length > max) raise(M.FilterTooManyArgs, [name, max, options.length]);\n const filterFn = definition.factory(options, literals);\n resolvedByKey.set(key, filterFn);\n return filterFn;\n}\n"],"mappings":"gFAqBO,IAAMA,EAAiB,CAC5BC,kBAAmB,WACnBC,iBAAkB,UAClBC,gBAAiB,SACjBC,oBAAqB,aACrBC,kBAAmB,WACnBC,SAAU,CAAEC,MAAO,YAAaC,IAAK,WACrCC,cAAeC,SAAa,KAAcA,SAASC,iBAAiBC,MAAQ,KAC5EC,wBAAwB,GAWnB,SAASC,EAAUC,GACxB,IAAMC,EAAUhB,EACViB,EAAOjB,EAAOM,SACdY,EAAQC,OAAOC,QAAQL,GAASM,OAAO,EAAE,CAAEC,UAAqB,IAAVA,GACtDC,EAAYJ,OAAOC,QAAQL,EAAQT,UAAY,CAAC,GAAGe,OAAO,EAAE,CAAEG,UAAiB,IAARA,GAC7E,QAAYC,EAAKH,KAAUJ,EAAO,CAChC,IAAMQ,EAAUV,EAAQS,KACnBN,OAAOQ,OAAOX,EAASS,IAAkB,OAAVH,UAAyBA,UAAiBI,GAAWE,MAAMC,QAAQP,KAAWM,MAAMC,QAAQH,KAC9HI,KAAuB,CAAC,iBAAkBL,GAE9C,CACA,QAAYM,EAAMP,KAAQD,IACnBJ,OAAOQ,OAAOV,EAAMc,IAAwB,iBAARP,IAAkBM,KAAuB,CAAC,iBAAkB,YAAYC,MAEnH,QAAYN,EAAKH,KAAUJ,EACb,aAARO,IACFT,EAAQS,GAAOH,GAGnB,QAAYS,EAAMP,KAAQD,EAAWN,EAAKc,GAAQP,CACpD,CAGO,IAAMQ,EAAY,IAAwBhC,ECzBpCiC,EAA0C,CACrD,UAAW,SACX,QAAS,QAAS,aAAc,OAAQ,QAAS,WAAY,SAAU,SAAU,UAAW,WAAY,OACxG,QAAS,QAAS,OAAQ,UAAW,OACrC,OAAQ,OAAQ,WAAY,MAAO,MACnC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,QAAS,MAAO,QAAS,WAAY,WAAY,SAAU,SAAU,cAC/G,YAQIC,EAAc,IAAIC,IAGlBC,EAAgB,IAAID,IAgBnB,SAASE,EAAgBC,GAC9B,QAAWP,KAAQZ,OAAOoB,KAAKD,GAE7BJ,EAAYM,IAAIT,EAAM,IAAKO,EAAIP,KAIjCK,EAAcK,OAChB,CAEO,SAASC,EAAUX,GACxB,OAAOG,EAAYS,IAAIZ,EACzB,CA4BO,SAASa,EAAcb,EAAcf,EAAmB6B,GAC7D,IAAMpB,EAAM,GAAGM,IA9CV,SAAuBe,EAAyBD,GACrD,MAAO,GAAGE,KAAKC,UAAUF,KAAQC,KAAKC,UAAUH,IAClD,CA4CwBI,CAAcjC,EAAS6B,KACvCK,EAAWd,EAAce,IAAI1B,GACnC,UAAWyB,EAAa,IACtB,OAAOA,EAET,IAAME,EAAalB,EAAYiB,IAAIpB,QAChB,IAAfqB,GAlBN,SAAuBrB,EAAcsB,GAC/BpB,EAAqBqB,SAASvB,IAChCwB,EAAW,0CAA0CxB,OAAUA,mHAAuHA,EAAMsB,GAE9LvB,MAAuB,CAACC,GAAOA,EAAMsB,EACvC,CAcIG,CAAczB,EAAMG,EAAYK,QAGlC,IAAOkB,EAAKC,GAAON,EAAWO,MAC1B3C,EAAQ4C,OAASH,GAAK3B,MAA0B,CAACC,EAAM0B,EAAKzC,EAAQ4C,SACpE5C,EAAQ4C,OAASF,GAAK5B,MAA2B,CAACC,EAAM2B,EAAK1C,EAAQ4C,SACzE,IAAMC,EAAWT,EAAWU,QAAQ9C,EAAS6B,GAC7C,OAAAT,EAAcI,IAAIf,EAAKoC,GAChBA,CACT,QAAAE,EAAAC,OAAAC,OAAAC,OAAAC,OAAAC,OAAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import{n,p as t}from"./chunk-NMOSSDKJ.js";import{a as l,b as e,c as r}from"./chunk-5Q4M6A3C.js";import{a as o}from"./chunk-BGUJ3HF6.js";var i=Symbol.for("wcstack.binder"),u=Symbol.for("wcstack.binder.pending"),s=Symbol.for("wcstack.binder.taken");var a=new Map;function f(l,e){if(1!==l.nodeType||!l.isConnected)return;let r=n.get(l.getRootNode());void 0===r||!1===r.element?.isConnected?a.set(l,e):t(r,l,e?.range)}function c(){let n=[...a];a.clear();for(let[t,l]of n)f(t,l);!function(){let n=function(){let n=globalThis[i];return null==n||"wcs-binder"!==n.protocol||"number"!=typeof n.version||n.version<1||"function"!=typeof n.bind?null:n}();if(null===n)return;let t=function(){let n=globalThis,t=n[u];return void 0===t&&(t=[],n[u]=t),t}();if(0===t.length)return;let l=t.splice(0,t.length),e=function(){let n=globalThis,t=n[s];return void 0===t&&(t=new WeakSet,n[s]=t),t}();for(let t of l)e.add(t),n.bind(t)}()}function d(){let n=globalThis;void 0===n[i]&&(n[i]={protocol:"wcs-binder",version:1,bind:f})}var b=class{constructor(){this.name="dirty",this.Z=(n,t)=>{if(0===n.n){let t=n.Y;return t!==l&&t!==e&&(n.Y=e,!0)}let r=null===t?null:t.yt;if(null===r)return!1;let o=r[n.F];return o!==l&&o!==e&&(r[n.F]=e,!0)}}Jo(n,t,l){null!==t.getter&&this.Z(t,l),n.Et(t,l),n.Nn(t,l,this.Z)}Ho(n,t){let l=t.l.o.Dt;if(null!==l)for(let e of l)e.n===t.l.n?n.it(e,t,this.Z):n.en(t,e,t=>n.it(e,t,this.Z))}be(n,t,l){this.Z(t,l),o.ke?.(n,t,l),n.Et(t,l),n.Nn(t,l,this.Z)}Ko(n,t,o){let i=0===t.n;if(!i&&null===o)return;let u=i?null:o.yt??=new Array(n.Le).fill(l),s=null===u?t.Y:u[t.F];if(s!==l&&s!==e&&s!==r&&(null===u||t.F in u))return s;s=r;try{return s=n.Uo(t,null===u?null:o)}finally{null===u?t.Y=s:u[t.F]=s}}Xt(n){n.yt=null}kt(n){for(let t of n.I.all())null!==t.getter&&(0===t.n?t.Y===e&&(t.Y=r):n.nn(t.h[t.n],n=>{let l=n.yt;null!==l&&l[t.F]===e&&(l[t.F]=r)}))}};export{f as a,c as b,d as c,b as d};
2
+ //# sourceMappingURL=chunk-DOWWBZVS.js.map