@jxsuite/runtime 6.0.2 → 6.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 CHANGED
@@ -2790,11 +2790,22 @@ async function resolve(source, ctx) {
2790
2790
  if (contentType.includes("text/html")) {
2791
2791
  throw new Error(`Jx: ${source} returned HTML, not a document — the host answered a missing file with its ` + `app shell (a single-page fallback), so this path is not served.`);
2792
2792
  }
2793
+ if (JXN_URL.test(source) && !contentType.includes("json")) {
2794
+ if (!_documentParser) {
2795
+ throw new Error(`Jx: ${source} is a .jxn file and this page has no parser for it. Serve it from a Jx ` + `site, which answers JSON, or call setDocumentParser(parseJxn) with parseJxn from ` + `@jxsuite/schema/jxn.`);
2796
+ }
2797
+ return _documentParser(await res.text(), source);
2798
+ }
2793
2799
  return await res.json();
2794
2800
  });
2795
2801
  _resolveCache.set(source, p);
2796
2802
  return p;
2797
2803
  }
2804
+ var JXN_URL = /\.jxn(?:[?#]|$)/iu;
2805
+ var _documentParser = null;
2806
+ function setDocumentParser(parser) {
2807
+ _documentParser = parser;
2808
+ }
2798
2809
  var SCHEMA_KEYWORDS2 = new Set([
2799
2810
  "type",
2800
2811
  "properties",
@@ -3143,16 +3154,51 @@ var _templateErrorHandler = null;
3143
3154
  function setTemplateErrorHandler(handler) {
3144
3155
  _templateErrorHandler = handler;
3145
3156
  }
3157
+ function warnTemplateError(source, error) {
3158
+ if (!reportedTemplates.has(source)) {
3159
+ reportedTemplates.add(source);
3160
+ console.warn(`jx: template ${JSON.stringify(source)} threw:`, error);
3161
+ }
3162
+ }
3163
+ var pendingLookups = 0;
3164
+ var heldTemplateErrors = new Map;
3165
+ var lookupWaiters = [];
3166
+ function holdTemplateErrorsFor(lookup) {
3167
+ pendingLookups += 1;
3168
+ lookup.finally(() => {
3169
+ pendingLookups -= 1;
3170
+ if (pendingLookups === 0) {
3171
+ for (const { error, source } of heldTemplateErrors.values()) {
3172
+ warnTemplateError(source, error);
3173
+ }
3174
+ heldTemplateErrors.clear();
3175
+ for (const wake of lookupWaiters.splice(0)) {
3176
+ wake();
3177
+ }
3178
+ }
3179
+ });
3180
+ }
3181
+ function lookupsSettled() {
3182
+ if (pendingLookups === 0) {
3183
+ return Promise.resolve();
3184
+ }
3185
+ return new Promise((wake) => {
3186
+ lookupWaiters.push(wake);
3187
+ });
3188
+ }
3146
3189
  function bindTemplate(source, run, fallback) {
3147
3190
  effect(() => {
3148
3191
  try {
3149
3192
  run();
3193
+ heldTemplateErrors.delete(run);
3150
3194
  } catch (error) {
3195
+ const thrown = error instanceof Error ? error : new Error(String(error));
3151
3196
  if (_templateErrorHandler) {
3152
- _templateErrorHandler(error instanceof Error ? error : new Error(String(error)), source);
3153
- } else if (!reportedTemplates.has(source)) {
3154
- reportedTemplates.add(source);
3155
- console.warn(`jx: template ${JSON.stringify(source)} threw:`, error);
3197
+ _templateErrorHandler(thrown, source);
3198
+ } else if (pendingLookups > 0) {
3199
+ heldTemplateErrors.set(run, { error: thrown, source });
3200
+ } else {
3201
+ warnTemplateError(source, thrown);
3156
3202
  }
3157
3203
  fallback?.();
3158
3204
  }
@@ -3344,7 +3390,27 @@ var RESERVED_KEYS = new Set([
3344
3390
  "observedAttributes"
3345
3391
  ]);
3346
3392
  function inheritScope(parent) {
3347
- return Object.create(parent);
3393
+ const local = Object.create(parent);
3394
+ return new Proxy(local, {
3395
+ set(target, key, value) {
3396
+ if (Object.hasOwn(target, key)) {
3397
+ return Reflect.set(target, key, value);
3398
+ }
3399
+ if (key in parent) {
3400
+ return Reflect.set(parent, key, value);
3401
+ }
3402
+ bindLocal(target, key, value);
3403
+ return true;
3404
+ }
3405
+ });
3406
+ }
3407
+ function bindLocal(scope, key, value) {
3408
+ Object.defineProperty(scope, key, {
3409
+ configurable: true,
3410
+ enumerable: true,
3411
+ value,
3412
+ writable: true
3413
+ });
3348
3414
  }
3349
3415
  function scopeMedia(state) {
3350
3416
  return state["$media"] ?? {};
@@ -3390,7 +3456,7 @@ function renderNode(def, state, options) {
3390
3456
  if (localState === state) {
3391
3457
  localState = inheritScope(state);
3392
3458
  }
3393
- localState[key] = isRef2(val) ? resolveRef(val.$ref, state) : val;
3459
+ bindLocal(localState, key, isRef2(val) ? resolveRef(val.$ref, state) : val);
3394
3460
  }
3395
3461
  }
3396
3462
  if ("$ref" in def && !def.tagName) {
@@ -3441,9 +3507,44 @@ function renderNode(def, state, options) {
3441
3507
  el.append(renderNode(child, localState, childOpts));
3442
3508
  }
3443
3509
  }
3510
+ } else if (isTemplateString(kids)) {
3511
+ renderComputedChildren(el, kids, localState, {
3512
+ ...options,
3513
+ _ns: childNs,
3514
+ _path: [...path, "children"]
3515
+ });
3444
3516
  }
3445
3517
  return el;
3446
3518
  }
3519
+ function renderComputedChildren(el, template, state, options) {
3520
+ const path = options._path ?? [];
3521
+ let live = null;
3522
+ const retire = () => {
3523
+ el.replaceChildren();
3524
+ live?.stop();
3525
+ live = null;
3526
+ };
3527
+ bindTemplate(template, () => {
3528
+ const nodes = evaluateValueTemplate(template, state);
3529
+ retire();
3530
+ if (!Array.isArray(nodes)) {
3531
+ return;
3532
+ }
3533
+ const scope = effectScope(true);
3534
+ live = scope;
3535
+ pauseTracking();
3536
+ try {
3537
+ scope.run(() => {
3538
+ for (const [i, child] of nodes.entries()) {
3539
+ el.append(renderNode(child, state, { ...options, _path: [...path, i] }));
3540
+ }
3541
+ });
3542
+ } finally {
3543
+ resetTracking();
3544
+ }
3545
+ }, retire);
3546
+ onScopeDispose(() => live?.stop(), true);
3547
+ }
3447
3548
  function applyProperties(el, def, state) {
3448
3549
  for (const [key, val] of Object.entries(def)) {
3449
3550
  if (RESERVED_KEYS.has(key)) {
@@ -3886,7 +3987,7 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
3886
3987
  const createRow = (key, item, index) => {
3887
3988
  const map = shallowReactive({ index, item });
3888
3989
  const child = inheritScope(state);
3889
- child.$map = map;
3990
+ bindLocal(child, "$map", map);
3890
3991
  Object.defineProperty(child, "$map/item", { enumerable: true, get: () => map.item });
3891
3992
  Object.defineProperty(child, "$map/index", { enumerable: true, get: () => map.index });
3892
3993
  const scope = effectScope(true);
@@ -4114,20 +4215,22 @@ async function resolvePrototype(def, state, key, base, ctx) {
4114
4215
  clearTimeout(debounceTimer);
4115
4216
  }
4116
4217
  });
4117
- const doFetch = () => fetch(url, {
4118
- method: def.method ?? "GET",
4119
- signal: controller.signal,
4120
- ...def.headers && { headers: def.headers },
4121
- ...def.body && {
4122
- body: isNonNullObject(def.body) ? JSON.stringify(def.body) : def.body
4123
- }
4124
- }).then((r) => r.ok ? r.json() : Promise.reject(r.statusText)).then((d) => {
4125
- s.value = d;
4126
- }).catch((error) => {
4127
- if (!(error instanceof Error && error.name === "AbortError")) {
4128
- s.value = { error: String(error) };
4129
- }
4130
- });
4218
+ const doFetch = () => {
4219
+ holdTemplateErrorsFor(fetch(url, {
4220
+ method: def.method ?? "GET",
4221
+ signal: controller.signal,
4222
+ ...def.headers && { headers: def.headers },
4223
+ ...def.body && {
4224
+ body: isNonNullObject(def.body) ? JSON.stringify(def.body) : def.body
4225
+ }
4226
+ }).then((r) => r.ok ? r.json() : Promise.reject(r.statusText)).then((d) => {
4227
+ s.value = d;
4228
+ }).catch((error) => {
4229
+ if (!(error instanceof Error && error.name === "AbortError")) {
4230
+ s.value = { error: String(error) };
4231
+ }
4232
+ }));
4233
+ };
4131
4234
  if (debounceMs > 0) {
4132
4235
  debounceTimer = setTimeout(doFetch, debounceMs);
4133
4236
  } else {
@@ -4454,20 +4557,21 @@ async function resolveViaDevProxy(def, state, key, base) {
4454
4557
  return r.json();
4455
4558
  });
4456
4559
  const s = ref(null);
4560
+ const resolveInto = (resolvedConfig) => {
4561
+ holdTemplateErrorsFor(doResolve(resolvedConfig).then((value) => {
4562
+ s.value = value;
4563
+ }).catch((error) => console.error("Jx dev proxy:", error)));
4564
+ };
4457
4565
  if (hasTemplates) {
4458
4566
  effect(() => {
4459
4567
  const resolvedConfig = {};
4460
4568
  for (const [k, v] of Object.entries(config)) {
4461
4569
  resolvedConfig[k] = isTemplateString(v) ? evaluateTemplate(v, state) : v;
4462
4570
  }
4463
- doResolve(resolvedConfig).then((value) => {
4464
- s.value = value;
4465
- }).catch((error) => console.error("Jx dev proxy:", error));
4571
+ resolveInto(resolvedConfig);
4466
4572
  });
4467
4573
  } else {
4468
- doResolve(config).then((value) => {
4469
- s.value = value;
4470
- }).catch((error) => console.error("Jx dev proxy:", error));
4574
+ resolveInto(config);
4471
4575
  }
4472
4576
  return s;
4473
4577
  }
@@ -4476,7 +4580,7 @@ function latestServerCall(s, invoke, label) {
4476
4580
  return (args) => {
4477
4581
  seq += 1;
4478
4582
  const n = seq;
4479
- new Promise((settle) => {
4583
+ holdTemplateErrorsFor(new Promise((settle) => {
4480
4584
  settle(invoke(args));
4481
4585
  }).then((result) => {
4482
4586
  if (n === seq) {
@@ -4486,7 +4590,7 @@ function latestServerCall(s, invoke, label) {
4486
4590
  if (n === seq) {
4487
4591
  console.error(label, error);
4488
4592
  }
4489
- });
4593
+ }));
4490
4594
  };
4491
4595
  }
4492
4596
  async function resolveServerFunction(def, state, key, base) {
@@ -4664,7 +4768,7 @@ function mergeProps(def, parentState) {
4664
4768
  if (refusePrivateProp(k, "$props")) {
4665
4769
  continue;
4666
4770
  }
4667
- child[k] = isRef2(v) ? resolveRef(v.$ref, parentState) : v;
4771
+ bindLocal(child, k, isRef2(v) ? resolveRef(v.$ref, parentState) : v);
4668
4772
  }
4669
4773
  return child;
4670
4774
  }
@@ -5223,6 +5327,7 @@ export {
5223
5327
  isNestedSelectorKey,
5224
5328
  isSignal,
5225
5329
  isSingleExpression,
5330
+ lookupsSettled,
5226
5331
  mount,
5227
5332
  observeScope,
5228
5333
  preloadDocument,
@@ -5246,6 +5351,7 @@ export {
5246
5351
  setCanvasDelinkCommands,
5247
5352
  setCanvasDelinkPopovers,
5248
5353
  setCanvasViewportTranspose,
5354
+ setDocumentParser,
5249
5355
  setNpmModuleResolver,
5250
5356
  setResolveToken,
5251
5357
  setRootMedia,
@@ -5261,5 +5367,5 @@ export {
5261
5367
  transposeCanvasUnits
5262
5368
  };
5263
5369
 
5264
- //# debugId=938A15203F1CC52664756E2164756E21
5370
+ //# debugId=16998FE20281F1D164756E2164756E21
5265
5371
  //# sourceMappingURL=runtime.js.map