@jxsuite/runtime 0.28.5 → 0.29.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 CHANGED
@@ -51,6 +51,128 @@ function warn(msg, ...args) {
51
51
  console.warn(`[Vue warn] ${msg}`, ...args);
52
52
  }
53
53
  var activeEffectScope;
54
+
55
+ class EffectScope {
56
+ constructor(detached = false) {
57
+ this.detached = detached;
58
+ this._active = true;
59
+ this._on = 0;
60
+ this.effects = [];
61
+ this.cleanups = [];
62
+ this._isPaused = false;
63
+ this._warnOnRun = true;
64
+ this.__v_skip = true;
65
+ if (!detached && activeEffectScope) {
66
+ if (activeEffectScope.active) {
67
+ this.parent = activeEffectScope;
68
+ this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
69
+ } else {
70
+ this._active = false;
71
+ this._warnOnRun = false;
72
+ }
73
+ }
74
+ }
75
+ get active() {
76
+ return this._active;
77
+ }
78
+ pause() {
79
+ if (this._active) {
80
+ this._isPaused = true;
81
+ let i, l;
82
+ if (this.scopes) {
83
+ for (i = 0, l = this.scopes.length;i < l; i++) {
84
+ this.scopes[i].pause();
85
+ }
86
+ }
87
+ for (i = 0, l = this.effects.length;i < l; i++) {
88
+ this.effects[i].pause();
89
+ }
90
+ }
91
+ }
92
+ resume() {
93
+ if (this._active) {
94
+ if (this._isPaused) {
95
+ this._isPaused = false;
96
+ let i, l;
97
+ if (this.scopes) {
98
+ for (i = 0, l = this.scopes.length;i < l; i++) {
99
+ this.scopes[i].resume();
100
+ }
101
+ }
102
+ for (i = 0, l = this.effects.length;i < l; i++) {
103
+ this.effects[i].resume();
104
+ }
105
+ }
106
+ }
107
+ }
108
+ run(fn) {
109
+ if (this._active) {
110
+ const currentEffectScope = activeEffectScope;
111
+ try {
112
+ activeEffectScope = this;
113
+ return fn();
114
+ } finally {
115
+ activeEffectScope = currentEffectScope;
116
+ }
117
+ } else if (this._warnOnRun) {
118
+ warn(`cannot run an inactive effect scope.`);
119
+ }
120
+ }
121
+ on() {
122
+ if (++this._on === 1) {
123
+ this.prevScope = activeEffectScope;
124
+ activeEffectScope = this;
125
+ }
126
+ }
127
+ off() {
128
+ if (this._on > 0 && --this._on === 0) {
129
+ if (activeEffectScope === this) {
130
+ activeEffectScope = this.prevScope;
131
+ } else {
132
+ let current = activeEffectScope;
133
+ while (current) {
134
+ if (current.prevScope === this) {
135
+ current.prevScope = this.prevScope;
136
+ break;
137
+ }
138
+ current = current.prevScope;
139
+ }
140
+ }
141
+ this.prevScope = undefined;
142
+ }
143
+ }
144
+ stop(fromParent) {
145
+ if (this._active) {
146
+ this._active = false;
147
+ let i, l;
148
+ for (i = 0, l = this.effects.length;i < l; i++) {
149
+ this.effects[i].stop();
150
+ }
151
+ this.effects.length = 0;
152
+ for (i = 0, l = this.cleanups.length;i < l; i++) {
153
+ this.cleanups[i]();
154
+ }
155
+ this.cleanups.length = 0;
156
+ if (this.scopes) {
157
+ for (i = 0, l = this.scopes.length;i < l; i++) {
158
+ this.scopes[i].stop(true);
159
+ }
160
+ this.scopes.length = 0;
161
+ }
162
+ if (!this.detached && this.parent && !fromParent) {
163
+ const last = this.parent.scopes.pop();
164
+ if (last && last !== this) {
165
+ this.parent.scopes[this.index] = last;
166
+ last.index = this.index;
167
+ }
168
+ }
169
+ this.parent = undefined;
170
+ }
171
+ }
172
+ }
173
+ function effectScope(detached) {
174
+ return new EffectScope(detached);
175
+ }
54
176
  var activeSub;
55
177
  var pausedQueueEffects = /* @__PURE__ */ new WeakSet;
56
178
 
@@ -1362,7 +1484,7 @@ function resolveExprRef(ref2, state, event, iterCtx) {
1362
1484
  }
1363
1485
  return state[ref2] ?? null;
1364
1486
  }
1365
- function resolveWritableRef(ref2, state, event, iterCtx) {
1487
+ function resolveWritableRef(ref2, state, _event, iterCtx) {
1366
1488
  if (ref2.startsWith("$map/")) {
1367
1489
  const parts = ref2.split("/");
1368
1490
  const [, key] = parts;
@@ -1812,10 +1934,11 @@ async function resolveFunction(def2, state, key, base) {
1812
1934
  }
1813
1935
  _moduleCache.set(src, mod);
1814
1936
  }
1815
- fn = mod[exportName] ?? mod.default?.[exportName];
1816
- if (typeof fn !== "function") {
1937
+ const candidate = mod[exportName] ?? mod.default?.[exportName];
1938
+ if (typeof candidate !== "function") {
1817
1939
  throw new TypeError(`Jx: export "${exportName}" not found or not a function in "${src}"`);
1818
1940
  }
1941
+ fn = candidate;
1819
1942
  }
1820
1943
  const hasParams = (def2.parameters ?? def2.arguments ?? []).length > 0;
1821
1944
  let isComputed = false;
@@ -1901,20 +2024,27 @@ function renderNode(def2, state, options) {
1901
2024
  if (def2.$switch) {
1902
2025
  return renderSwitch(def2, localState, options);
1903
2026
  }
1904
- if (isMappedArray(def2.children)) {
1905
- return renderMappedArray(def2, def2.children, localState, options);
1906
- }
1907
2027
  const el = document.createElement(tagName);
1908
2028
  if (options?.onNodeCreated) {
1909
- options.onNodeCreated(el, path, def2);
2029
+ options.onNodeCreated(el, path, def2, localState);
1910
2030
  }
1911
2031
  applyProperties(el, def2, localState);
1912
2032
  applyStyle(el, def2.style ?? {}, localState["$media"] ?? {}, localState);
1913
2033
  applyAttributes(el, def2.attributes ?? {}, localState);
1914
- const children = Array.isArray(def2.children) ? def2.children : [];
1915
- for (let i = 0;i < children.length; i++) {
1916
- const childOpts = options ? { ...options, _path: [...path, "children", i] } : undefined;
1917
- el.append(renderNode(children[i], localState, childOpts));
2034
+ const kids = def2.children;
2035
+ if (isMappedArray(kids)) {
2036
+ const arrOpts = options ? { ...options, _path: [...path, "children"] } : undefined;
2037
+ renderMappedArrayInto(el, kids, localState, arrOpts);
2038
+ } else if (Array.isArray(kids)) {
2039
+ for (let i = 0;i < kids.length; i++) {
2040
+ const child = kids[i];
2041
+ const childOpts = options ? { ...options, _path: [...path, "children", i] } : undefined;
2042
+ if (isMappedArray(child)) {
2043
+ renderMappedArrayInto(el, child, localState, childOpts);
2044
+ } else {
2045
+ el.append(renderNode(child, localState, childOpts));
2046
+ }
2047
+ }
1918
2048
  }
1919
2049
  return el;
1920
2050
  }
@@ -1934,7 +2064,8 @@ function applyProperties(el, def2, state) {
1934
2064
  const handler = resolveRef(val.$ref, state);
1935
2065
  if (typeof handler === "function") {
1936
2066
  const scope = state;
1937
- el.addEventListener(key.slice(2), (e) => handler(scope, e));
2067
+ const handlerFn = handler;
2068
+ el.addEventListener(key.slice(2), (e) => handlerFn(scope, e));
1938
2069
  }
1939
2070
  continue;
1940
2071
  }
@@ -2088,7 +2219,20 @@ function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2088
2219
  }
2089
2220
  const tag = document.createElement("style");
2090
2221
  tag.textContent = css;
2222
+ tag.dataset.jxOwner = uid;
2091
2223
  document.head.append(tag);
2224
+ elementStyleTags.set(el, tag);
2225
+ }
2226
+ var elementStyleTags = new WeakMap;
2227
+ function reapplyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2228
+ const prev = elementStyleTags.get(el);
2229
+ if (prev) {
2230
+ prev.remove();
2231
+ elementStyleTags.delete(el);
2232
+ }
2233
+ el.style.cssText = "";
2234
+ delete el.dataset.jx;
2235
+ applyStyle(el, styleDef ?? {}, mediaQueries, state);
2092
2236
  }
2093
2237
  function applyAttributes(el, attrs, state) {
2094
2238
  for (const [k, v] of Object.entries(attrs)) {
@@ -2101,53 +2245,55 @@ function applyAttributes(el, attrs, state) {
2101
2245
  }
2102
2246
  }
2103
2247
  }
2104
- function renderMappedArray(def2, arrayDef, state, options) {
2248
+ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
2105
2249
  const path = options?._path ?? [];
2106
- const container = document.createElement(def2.tagName ?? "div");
2107
- if (options?.onNodeCreated) {
2108
- options.onNodeCreated(container, path, def2);
2109
- }
2110
- applyProperties(container, def2, state);
2111
- applyStyle(container, def2.style ?? {}, state["$media"] ?? {}, state);
2112
- applyAttributes(container, def2.attributes ?? {}, state);
2250
+ const anchor = document.createComment("jx-array");
2251
+ parentEl.append(anchor);
2113
2252
  const { items: itemsSrc, map: mapDef, filter: filterRef, sort: sortRef } = arrayDef;
2114
2253
  effect(() => {
2115
- container.innerHTML = "";
2116
- let items;
2117
- items = isRefObj(itemsSrc) ? resolveRef(itemsSrc.$ref, state) : itemsSrc;
2118
- if (!Array.isArray(items)) {
2119
- return;
2120
- }
2121
- if (isRefObj(filterRef)) {
2254
+ let items = isRefObj(itemsSrc) ? resolveRef(itemsSrc.$ref, state) : itemsSrc;
2255
+ if (Array.isArray(items) && isRefObj(filterRef)) {
2122
2256
  const fn = resolveRef(filterRef.$ref, state);
2123
2257
  if (typeof fn === "function") {
2124
2258
  items = items.filter(fn);
2125
2259
  }
2126
2260
  }
2127
- if (isRefObj(sortRef)) {
2261
+ if (Array.isArray(items) && isRefObj(sortRef)) {
2128
2262
  const fn = resolveRef(sortRef.$ref, state);
2129
2263
  if (typeof fn === "function") {
2130
2264
  items = [...items].toSorted(fn);
2131
2265
  }
2132
2266
  }
2133
- for (const [index, item] of items.entries()) {
2134
- const child = Object.create(state);
2135
- child.$map = { index, item };
2136
- child["$map/item"] = item;
2137
- child["$map/index"] = index;
2138
- const childOpts = options ? { ...options, _path: [...path, "children", "map", index] } : undefined;
2139
- if (mapDef) {
2140
- container.append(renderNode(mapDef, child, childOpts));
2141
- }
2267
+ if (!Array.isArray(items) || !mapDef) {
2268
+ return;
2142
2269
  }
2270
+ const scope = effectScope(true);
2271
+ const nodes = [];
2272
+ scope.run(() => {
2273
+ for (const [index, item] of items.entries()) {
2274
+ const child = Object.create(state);
2275
+ child.$map = { index, item };
2276
+ child["$map/item"] = item;
2277
+ child["$map/index"] = index;
2278
+ const childOpts = options ? { ...options, _path: [...path, "map", index] } : undefined;
2279
+ const node = renderNode(mapDef, child, childOpts);
2280
+ anchor.before(node);
2281
+ nodes.push(node);
2282
+ }
2283
+ });
2284
+ onEffectCleanup(() => {
2285
+ scope.stop();
2286
+ for (const n of nodes) {
2287
+ n.remove();
2288
+ }
2289
+ });
2143
2290
  });
2144
- return container;
2145
2291
  }
2146
2292
  function renderSwitch(def2, state, options) {
2147
2293
  const path = options?._path ?? [];
2148
2294
  const container = document.createElement(def2.tagName ?? "div");
2149
2295
  if (options?.onNodeCreated) {
2150
- options.onNodeCreated(container, path, def2);
2296
+ options.onNodeCreated(container, path, def2, state);
2151
2297
  }
2152
2298
  applyProperties(container, def2, state);
2153
2299
  applyStyle(container, def2.style ?? {}, state["$media"] ?? {}, state);
@@ -2422,7 +2568,8 @@ async function importAndInstantiate(def2, src, exportName, base) {
2422
2568
  config[k] = v;
2423
2569
  }
2424
2570
  }
2425
- const instance = new ExportedClass(config);
2571
+ const Ctor = ExportedClass;
2572
+ const instance = new Ctor(config);
2426
2573
  let value;
2427
2574
  if (typeof instance.resolve === "function") {
2428
2575
  value = await instance.resolve();
@@ -2627,13 +2774,14 @@ async function resolveServerFunction(def2, state, key, base) {
2627
2774
  }
2628
2775
  _moduleCache.set(src, mod);
2629
2776
  }
2630
- const fn = mod[exportName] ?? mod.default?.[exportName];
2631
- if (!fn) {
2777
+ const candidate = mod[exportName] ?? mod.default?.[exportName];
2778
+ if (!candidate) {
2632
2779
  throw new Error(`Jx: export "${exportName}" not found in "${src}" for "${key}"`);
2633
2780
  }
2634
- if (typeof fn !== "function") {
2781
+ if (typeof candidate !== "function") {
2635
2782
  throw new TypeError(`Jx: "${exportName}" from "${src}" is not a function`);
2636
2783
  }
2784
+ const fn = candidate;
2637
2785
  const rawArgs = def2.arguments ?? {};
2638
2786
  const hasReactiveArg = Object.values(rawArgs).some((v) => isRefObj(v));
2639
2787
  const resolveArgs = () => {
@@ -2929,7 +3077,7 @@ async function defineElement(source, baseUrl) {
2929
3077
  function renderCustomElementWithProps(def2, state, options, path) {
2930
3078
  const el = document.createElement(def2.tagName ?? "div");
2931
3079
  if (options?.onNodeCreated) {
2932
- options.onNodeCreated(el, path ?? [], def2);
3080
+ options.onNodeCreated(el, path ?? [], def2, state);
2933
3081
  }
2934
3082
  for (const [key, val] of Object.entries(def2.$props ?? {})) {
2935
3083
  if (isRefObj(val)) {
@@ -2996,8 +3144,10 @@ export {
2996
3144
  resolvePrototype,
2997
3145
  resolve,
2998
3146
  renderNode,
3147
+ reapplyStyle,
2999
3148
  isSignal,
3000
3149
  hasSchemaKeywords,
3150
+ elementStyleTags,
3001
3151
  defineElement,
3002
3152
  camelToKebab,
3003
3153
  buildScope,
@@ -3006,5 +3156,5 @@ export {
3006
3156
  Jx
3007
3157
  };
3008
3158
 
3009
- //# debugId=32F6E02650EECC3864756E2164756E21
3159
+ //# debugId=3DB97313FD2BC32064756E2164756E21
3010
3160
  //# sourceMappingURL=runtime.js.map