@jxsuite/runtime 4.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime.js +720 -442
- package/dist/runtime.js.map +12 -12
- package/package.json +5 -4
- package/src/cookie.ts +4 -2
- package/src/css.ts +31 -18
- package/src/expression.ts +321 -232
- package/src/pointer.ts +10 -4
- package/src/runtime.ts +1318 -566
- package/src/statements.ts +58 -48
- package/src/types.ts +114 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "JSON-native reactive web component runtime",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,10 +33,11 @@
|
|
|
33
33
|
"upgrade": "bun update --latest && bun install"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@jxsuite/schema": "^
|
|
37
|
-
"@vue/reactivity": "3.5.
|
|
36
|
+
"@jxsuite/schema": "^4.0.0",
|
|
37
|
+
"@vue/reactivity": "3.5.44"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@happy-dom/global-registrator": "^
|
|
40
|
+
"@happy-dom/global-registrator": "^21.0.4",
|
|
41
|
+
"@jxsuite/test-support": "^0.0.0"
|
|
41
42
|
}
|
|
42
43
|
}
|
package/src/cookie.ts
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* mis-spelling fails silently in the direction of a cookie that never expires.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
import type { JsonValue } from "@jxsuite/schema/types";
|
|
23
|
+
|
|
22
24
|
/** The cookie attributes an `external-class-def` may declare for the `Cookie` `$prototype`. */
|
|
23
25
|
export interface CookieOptions {
|
|
24
26
|
domain?: string | undefined;
|
|
@@ -67,11 +69,11 @@ export function readCookie(header: string, name: string): string | null {
|
|
|
67
69
|
* - `SameSite=None` requires `Secure` (§5.4.7); without it the cookie is rejected outright.
|
|
68
70
|
*
|
|
69
71
|
* @param {string} name
|
|
70
|
-
* @param {
|
|
72
|
+
* @param {JsonValue} value JSON-encoded, then percent-encoded.
|
|
71
73
|
* @param {CookieOptions} options
|
|
72
74
|
* @returns {string}
|
|
73
75
|
*/
|
|
74
|
-
export function serializeCookie(name: string, value:
|
|
76
|
+
export function serializeCookie(name: string, value: JsonValue, options: CookieOptions): string {
|
|
75
77
|
const hostPrefixed = name.startsWith(HOST_PREFIX);
|
|
76
78
|
const parts = [`${name}=${encodeURIComponent(JSON.stringify(value))}`];
|
|
77
79
|
|
package/src/css.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* has to change. This is a narrow door beside the wide one, not a replacement for it.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import { isRef, isTemplateString } from "@jxsuite/schema/guards";
|
|
24
|
+
import { isNonNullObject, isRef, isString, isTemplateString } from "@jxsuite/schema/guards";
|
|
25
25
|
import type { JxRef, JxStyle } from "@jxsuite/schema/types";
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -196,7 +196,10 @@ export function splitSelectorList(selector: string): string[] {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
members.push(selector.slice(start));
|
|
199
|
-
const trimmed = members.
|
|
199
|
+
const trimmed = members.flatMap((member) => {
|
|
200
|
+
const text = member.trim();
|
|
201
|
+
return text === "" ? [] : [text];
|
|
202
|
+
});
|
|
200
203
|
return trimmed.length > 0 ? trimmed : [selector];
|
|
201
204
|
}
|
|
202
205
|
|
|
@@ -257,7 +260,7 @@ function transposeOpenAttribute(selector: string, options: CanvasOverlayTranspos
|
|
|
257
260
|
return out + selector.slice(from);
|
|
258
261
|
}
|
|
259
262
|
let start = at;
|
|
260
|
-
while (start > 0 && !COMPOUND_BREAK.test(selector
|
|
263
|
+
while (start > 0 && !COMPOUND_BREAK.test(selector.charAt(start - 1))) {
|
|
261
264
|
start -= 1;
|
|
262
265
|
}
|
|
263
266
|
const type = LEADING_TYPE.exec(selector.slice(start, at))?.[0]?.toLowerCase();
|
|
@@ -350,8 +353,16 @@ export const COLOR_SCHEME_STORAGE_KEY = "jx-color-scheme";
|
|
|
350
353
|
* @docs framework/concepts/color-schemes
|
|
351
354
|
*/
|
|
352
355
|
export function pureSchemeOf(query: string): "light" | "dark" | null {
|
|
353
|
-
const
|
|
354
|
-
return
|
|
356
|
+
const scheme = /^\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)$/.exec(query.trim())?.[1];
|
|
357
|
+
return scheme === "light" || scheme === "dark" ? scheme : null;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/** The two selectors a scheme-conditional rule dual-emits under: see {@link schemeSelectors}. */
|
|
361
|
+
export interface SchemeSelectorPair {
|
|
362
|
+
/** Applies inside the scheme's media query, only while no scheme is forced. */
|
|
363
|
+
auto: string;
|
|
364
|
+
/** Applies unconditionally while the root attribute forces the scheme. */
|
|
365
|
+
forced: string;
|
|
355
366
|
}
|
|
356
367
|
|
|
357
368
|
/**
|
|
@@ -362,13 +373,10 @@ export function pureSchemeOf(query: string): "light" | "dark" | null {
|
|
|
362
373
|
*
|
|
363
374
|
* @param {string} selector
|
|
364
375
|
* @param {"light" | "dark"} scheme
|
|
365
|
-
* @returns {
|
|
376
|
+
* @returns {SchemeSelectorPair}
|
|
366
377
|
* @docs framework/concepts/color-schemes
|
|
367
378
|
*/
|
|
368
|
-
export function schemeSelectors(
|
|
369
|
-
selector: string,
|
|
370
|
-
scheme: "light" | "dark",
|
|
371
|
-
): { auto: string; forced: string } {
|
|
379
|
+
export function schemeSelectors(selector: string, scheme: "light" | "dark"): SchemeSelectorPair {
|
|
372
380
|
if (selector === ":root" || selector === "html") {
|
|
373
381
|
return {
|
|
374
382
|
auto: `${selector}:where(:not([${COLOR_SCHEME_ATTR}]))`,
|
|
@@ -640,7 +648,9 @@ export function buildStyleRules(style: JxStyle, options: CssBuildOptions = {}):
|
|
|
640
648
|
} = options;
|
|
641
649
|
const rules: CssRule[] = [];
|
|
642
650
|
|
|
643
|
-
|
|
651
|
+
/* `null` is not in the declared value type, but a style object is JSON from a document, and a
|
|
652
|
+
cleared value arrives as `null`. */
|
|
653
|
+
const isBlock = (value: JxStyle[string] | null): value is JxStyle =>
|
|
644
654
|
value !== null && typeof value === "object" && !Array.isArray(value) && !isRef(value);
|
|
645
655
|
|
|
646
656
|
/**
|
|
@@ -658,7 +668,7 @@ export function buildStyleRules(style: JxStyle, options: CssBuildOptions = {}):
|
|
|
658
668
|
* the a11y lint, the canvas) assumes a block key holds ONE block; allowing it there would leave
|
|
659
669
|
* those reading past it in silence, which is the failure this codebase keeps finding.
|
|
660
670
|
*/
|
|
661
|
-
const blocksOf = (key: string, value:
|
|
671
|
+
const blocksOf = (key: string, value: JxStyle[string]): JxStyle[] => {
|
|
662
672
|
if (isBlock(value)) {
|
|
663
673
|
return [value];
|
|
664
674
|
}
|
|
@@ -670,7 +680,7 @@ export function buildStyleRules(style: JxStyle, options: CssBuildOptions = {}):
|
|
|
670
680
|
|
|
671
681
|
const declarationValue = (
|
|
672
682
|
property: string,
|
|
673
|
-
value:
|
|
683
|
+
value: JxStyle[string] | null,
|
|
674
684
|
reactive: boolean,
|
|
675
685
|
target: CssRuleTarget,
|
|
676
686
|
): string | null => {
|
|
@@ -683,7 +693,7 @@ export function buildStyleRules(style: JxStyle, options: CssBuildOptions = {}):
|
|
|
683
693
|
if (isRef(value)) {
|
|
684
694
|
return reactive ? (resolveValue?.(property, value, target) ?? null) : null;
|
|
685
695
|
}
|
|
686
|
-
if (
|
|
696
|
+
if (isNonNullObject(value)) {
|
|
687
697
|
return null;
|
|
688
698
|
}
|
|
689
699
|
const raw = String(value);
|
|
@@ -739,7 +749,7 @@ export function buildStyleRules(style: JxStyle, options: CssBuildOptions = {}):
|
|
|
739
749
|
selector: string | null,
|
|
740
750
|
declarations: readonly (readonly [string, string])[],
|
|
741
751
|
target: CssRuleTarget,
|
|
742
|
-
description?:
|
|
752
|
+
description?: JxStyle[string],
|
|
743
753
|
) => {
|
|
744
754
|
if (declarations.length === 0) {
|
|
745
755
|
return;
|
|
@@ -753,15 +763,18 @@ export function buildStyleRules(style: JxStyle, options: CssBuildOptions = {}):
|
|
|
753
763
|
resolved = transposed;
|
|
754
764
|
}
|
|
755
765
|
const text = cssRuleText(conditions, resolved, declarations);
|
|
756
|
-
|
|
766
|
+
const rule: CssRule = {
|
|
757
767
|
text,
|
|
758
768
|
conditions: [...conditions],
|
|
759
769
|
selector: resolved,
|
|
760
770
|
declarations,
|
|
761
771
|
target,
|
|
762
772
|
key: hashCss(text),
|
|
763
|
-
|
|
764
|
-
|
|
773
|
+
};
|
|
774
|
+
if (isString(description) && description !== "") {
|
|
775
|
+
rule.description = description;
|
|
776
|
+
}
|
|
777
|
+
rules.push(rule);
|
|
765
778
|
};
|
|
766
779
|
|
|
767
780
|
/**
|