@jxsuite/runtime 1.1.0 → 1.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.
- package/LICENSE +21 -0
- package/README.md +7 -7
- package/dist/runtime.js +71 -14
- package/dist/runtime.js.map +4 -4
- package/package.json +4 -4
- package/src/runtime.ts +122 -12
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kevin Shenk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -49,13 +49,13 @@ Each document goes through four steps:
|
|
|
49
49
|
|
|
50
50
|
## `$ref` bindings
|
|
51
51
|
|
|
52
|
-
| Pattern | Example | Meaning
|
|
53
|
-
| -------- | ------------------------------ |
|
|
54
|
-
| State | `{ "$ref": "#/state/count" }` | Reactive state binding
|
|
55
|
-
| Map item | `{ "$ref": "$map/item" }` | Current item in `Array` iteration
|
|
56
|
-
| Parent | `{ "$ref": "parent#/color" }` | Prop passed via `$props`
|
|
57
|
-
| Window | `{ "$ref": "window#/config" }` | Window global
|
|
58
|
-
| External | `{ "$ref": "./card.json" }` |
|
|
52
|
+
| Pattern | Example | Meaning |
|
|
53
|
+
| -------- | ------------------------------ | ----------------------------------------------------------- |
|
|
54
|
+
| State | `{ "$ref": "#/state/count" }` | Reactive state binding |
|
|
55
|
+
| Map item | `{ "$ref": "$map/item" }` | Current item in `Array` iteration |
|
|
56
|
+
| Parent | `{ "$ref": "parent#/color" }` | Prop passed via `$props` |
|
|
57
|
+
| Window | `{ "$ref": "window#/config" }` | Window global |
|
|
58
|
+
| External | `{ "$ref": "./card.json" }` | Component doc — via `$switch`/`$elements`, not a bare child |
|
|
59
59
|
|
|
60
60
|
## Custom element support
|
|
61
61
|
|
package/dist/runtime.js
CHANGED
|
@@ -616,7 +616,7 @@ function track(target, type, key) {
|
|
|
616
616
|
type,
|
|
617
617
|
key
|
|
618
618
|
});
|
|
619
|
-
}
|
|
619
|
+
} else {}
|
|
620
620
|
}
|
|
621
621
|
}
|
|
622
622
|
function trigger(target, type, key, newValue, oldValue, oldTarget) {
|
|
@@ -636,7 +636,7 @@ function trigger(target, type, key, newValue, oldValue, oldTarget) {
|
|
|
636
636
|
oldValue,
|
|
637
637
|
oldTarget
|
|
638
638
|
});
|
|
639
|
-
}
|
|
639
|
+
} else {}
|
|
640
640
|
}
|
|
641
641
|
};
|
|
642
642
|
startBatch();
|
|
@@ -1301,7 +1301,7 @@ class RefImpl {
|
|
|
1301
1301
|
type: "get",
|
|
1302
1302
|
key: "value"
|
|
1303
1303
|
});
|
|
1304
|
-
}
|
|
1304
|
+
} else {}
|
|
1305
1305
|
return this._value;
|
|
1306
1306
|
}
|
|
1307
1307
|
set value(newValue) {
|
|
@@ -1319,7 +1319,7 @@ class RefImpl {
|
|
|
1319
1319
|
newValue,
|
|
1320
1320
|
oldValue
|
|
1321
1321
|
});
|
|
1322
|
-
}
|
|
1322
|
+
} else {}
|
|
1323
1323
|
}
|
|
1324
1324
|
}
|
|
1325
1325
|
}
|
|
@@ -1921,6 +1921,12 @@ var SCHEMA_KEYWORDS = new Set([
|
|
|
1921
1921
|
function isMappedArray(value) {
|
|
1922
1922
|
return isJsonObject(value) && value.$prototype === "Array";
|
|
1923
1923
|
}
|
|
1924
|
+
function isTemplateString(value) {
|
|
1925
|
+
return typeof value === "string" && value.includes("${");
|
|
1926
|
+
}
|
|
1927
|
+
function bodyReturnsValue(body) {
|
|
1928
|
+
return /\breturn\b/.test(body);
|
|
1929
|
+
}
|
|
1924
1930
|
function paramNames(parameters) {
|
|
1925
1931
|
if (!parameters) {
|
|
1926
1932
|
return [];
|
|
@@ -1997,9 +2003,22 @@ async function runStatements(statements, state, event, opts = {}) {
|
|
|
1997
2003
|
}
|
|
1998
2004
|
|
|
1999
2005
|
// src/runtime.ts
|
|
2006
|
+
var SUPPORTED_SCHEMA_VERSION = 1;
|
|
2007
|
+
var _schemaVersionWarned = false;
|
|
2008
|
+
function checkSchemaVersion($schema) {
|
|
2009
|
+
if (_schemaVersionWarned || typeof $schema !== "string") {
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
2012
|
+
const match = $schema.match(/\/schema\/v(\d+)\b/);
|
|
2013
|
+
if (match && Number(match[1]) !== SUPPORTED_SCHEMA_VERSION) {
|
|
2014
|
+
_schemaVersionWarned = true;
|
|
2015
|
+
console.warn(`Jx: document $schema is version v${match[1]} but this runtime supports ` + `v${SUPPORTED_SCHEMA_VERSION}. Behavior may be undefined; there is no format migrator yet.`);
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2000
2018
|
async function Jx(source, target = document.body, options) {
|
|
2001
2019
|
const base = typeof source === "string" ? new URL(source, location.href).href : location.href;
|
|
2002
2020
|
const doc = await resolve(source);
|
|
2021
|
+
checkSchemaVersion(doc.$schema);
|
|
2003
2022
|
if (doc.$elements) {
|
|
2004
2023
|
await registerElements(doc.$elements, base);
|
|
2005
2024
|
}
|
|
@@ -2331,9 +2350,9 @@ async function resolveFunction(def2, state, key, base) {
|
|
|
2331
2350
|
let isComputed = false;
|
|
2332
2351
|
if (!hasParams) {
|
|
2333
2352
|
if (typeof def2.body === "string") {
|
|
2334
|
-
isComputed =
|
|
2353
|
+
isComputed = bodyReturnsValue(def2.body);
|
|
2335
2354
|
} else if (fn) {
|
|
2336
|
-
isComputed = fn.length <= 1 &&
|
|
2355
|
+
isComputed = fn.length <= 1 && bodyReturnsValue(fn.toString());
|
|
2337
2356
|
}
|
|
2338
2357
|
}
|
|
2339
2358
|
if (isComputed) {
|
|
@@ -2379,6 +2398,7 @@ var RESERVED_KEYS = new Set([
|
|
|
2379
2398
|
"cases",
|
|
2380
2399
|
"observedAttributes"
|
|
2381
2400
|
]);
|
|
2401
|
+
var warnedRefChildren = new Set;
|
|
2382
2402
|
function renderNode(def2, state, options) {
|
|
2383
2403
|
const path = options?._path ?? [];
|
|
2384
2404
|
if (typeof def2 === "string" || typeof def2 === "number" || typeof def2 === "boolean") {
|
|
@@ -2399,6 +2419,13 @@ function renderNode(def2, state, options) {
|
|
|
2399
2419
|
localState[key] = isRefObj(val) ? resolveRef(val.$ref, state) : val;
|
|
2400
2420
|
}
|
|
2401
2421
|
}
|
|
2422
|
+
if ("$ref" in def2 && !def2.tagName) {
|
|
2423
|
+
const refTarget = String(def2.$ref ?? "");
|
|
2424
|
+
if (!warnedRefChildren.has(refTarget)) {
|
|
2425
|
+
warnedRefChildren.add(refTarget);
|
|
2426
|
+
console.warn(`Jx: a $ref child ("${refTarget}") is not a supported component instance; register the ` + `component in $elements and use its custom-element tag instead (spec §13).`);
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2402
2429
|
const tagName = def2.tagName ?? "div";
|
|
2403
2430
|
const isCustomEl = tagName.includes("-") && customElements.get(tagName);
|
|
2404
2431
|
if (def2.$props && isCustomEl) {
|
|
@@ -2435,9 +2462,6 @@ function renderNode(def2, state, options) {
|
|
|
2435
2462
|
}
|
|
2436
2463
|
return el;
|
|
2437
2464
|
}
|
|
2438
|
-
function isTemplateString(val) {
|
|
2439
|
-
return typeof val === "string" && val.includes("${");
|
|
2440
|
-
}
|
|
2441
2465
|
function applyProperties(el, def2, state) {
|
|
2442
2466
|
for (const [key, val] of Object.entries(def2)) {
|
|
2443
2467
|
if (RESERVED_KEYS.has(key)) {
|
|
@@ -2610,11 +2634,21 @@ function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
|
|
|
2610
2634
|
if (key === "@--") {
|
|
2611
2635
|
continue;
|
|
2612
2636
|
}
|
|
2613
|
-
const
|
|
2637
|
+
const query = key.startsWith("@--") ? mediaQueries[key.slice(1)] ?? key.slice(1) : key.startsWith("@(") ? key.slice(1) : null;
|
|
2638
|
+
const atRule = query === null ? key : `@media ${query}`;
|
|
2614
2639
|
const scope = `[data-jx="${uid}"]`;
|
|
2615
|
-
|
|
2640
|
+
const scheme = query === null ? null : pureSchemeOf(query);
|
|
2641
|
+
if (scheme) {
|
|
2642
|
+
const { auto, forced } = schemeSelectors(scope, scheme);
|
|
2643
|
+
css += `${atRule} { ${auto} { ${toCSSText(rules)} } }
|
|
2644
|
+
`;
|
|
2645
|
+
emitMediaNested(atRule, auto, rules);
|
|
2646
|
+
emitNested(forced, rules);
|
|
2647
|
+
} else {
|
|
2648
|
+
css += `${atRule} { ${scope} { ${toCSSText(rules)} } }
|
|
2616
2649
|
`;
|
|
2617
|
-
|
|
2650
|
+
emitMediaNested(atRule, scope, rules);
|
|
2651
|
+
}
|
|
2618
2652
|
}
|
|
2619
2653
|
const tag = document.createElement("style");
|
|
2620
2654
|
tag.textContent = css;
|
|
@@ -3305,6 +3339,24 @@ function camelToKebab(s) {
|
|
|
3305
3339
|
function toCSSText(rules) {
|
|
3306
3340
|
return Object.entries(rules).filter(([k, v]) => !isNestedSelector(k) && (v === null || typeof v !== "object")).map(([p, v]) => `${camelToKebab(p)}: ${transposeCanvasUnits(String(v))}`).join("; ");
|
|
3307
3341
|
}
|
|
3342
|
+
var COLOR_SCHEME_ATTR = "data-color-scheme";
|
|
3343
|
+
var COLOR_SCHEME_STORAGE_KEY = "jx-color-scheme";
|
|
3344
|
+
function pureSchemeOf(query) {
|
|
3345
|
+
const m = /^\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)$/.exec(query.trim());
|
|
3346
|
+
return m?.[1] ?? null;
|
|
3347
|
+
}
|
|
3348
|
+
function schemeSelectors(selector, scheme) {
|
|
3349
|
+
if (selector === ":root" || selector === "html") {
|
|
3350
|
+
return {
|
|
3351
|
+
auto: `${selector}:where(:not([${COLOR_SCHEME_ATTR}]))`,
|
|
3352
|
+
forced: `${selector}:where([${COLOR_SCHEME_ATTR}="${scheme}"])`
|
|
3353
|
+
};
|
|
3354
|
+
}
|
|
3355
|
+
return {
|
|
3356
|
+
auto: `:where(:root:not([${COLOR_SCHEME_ATTR}])) ${selector}`,
|
|
3357
|
+
forced: `:where(:root[${COLOR_SCHEME_ATTR}="${scheme}"]) ${selector}`
|
|
3358
|
+
};
|
|
3359
|
+
}
|
|
3308
3360
|
var _rootMedia = {};
|
|
3309
3361
|
var _elementDefs = new Map;
|
|
3310
3362
|
function setRootMedia(map) {
|
|
@@ -3560,12 +3612,14 @@ export {
|
|
|
3560
3612
|
setResolveToken,
|
|
3561
3613
|
setCanvasViewportTranspose,
|
|
3562
3614
|
setCanvasDelinkAnchors,
|
|
3615
|
+
schemeSelectors,
|
|
3563
3616
|
runScoped,
|
|
3564
3617
|
resolveRef,
|
|
3565
3618
|
resolvePrototype,
|
|
3566
3619
|
resolve,
|
|
3567
3620
|
renderNode,
|
|
3568
3621
|
reapplyStyle,
|
|
3622
|
+
pureSchemeOf,
|
|
3569
3623
|
observeScope,
|
|
3570
3624
|
isSignal,
|
|
3571
3625
|
hasSchemaKeywords,
|
|
@@ -3574,9 +3628,12 @@ export {
|
|
|
3574
3628
|
camelToKebab,
|
|
3575
3629
|
buildScope,
|
|
3576
3630
|
applyStyle,
|
|
3631
|
+
SUPPORTED_SCHEMA_VERSION,
|
|
3577
3632
|
RESERVED_KEYS,
|
|
3578
|
-
Jx
|
|
3633
|
+
Jx,
|
|
3634
|
+
COLOR_SCHEME_STORAGE_KEY,
|
|
3635
|
+
COLOR_SCHEME_ATTR
|
|
3579
3636
|
};
|
|
3580
3637
|
|
|
3581
|
-
//# debugId=
|
|
3638
|
+
//# debugId=B1869F964FD5CCA664756E2164756E21
|
|
3582
3639
|
//# sourceMappingURL=runtime.js.map
|