@lwc/engine-core 8.7.0 → 8.9.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.
@@ -19,7 +19,7 @@ export { shouldBeFormAssociated } from './utils';
19
19
  export { getComponentConstructor } from './get-component-constructor';
20
20
  export type { RendererAPI, LifecycleCallback } from './renderer';
21
21
  export type { Template } from './template';
22
- export type { ConfigValue as WireConfigValue, ContextConsumer as WireContextConsumer, ContextProvider as WireContextProvider, ContextValue as WireContextValue, DataCallback as WireDataCallback, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, WireContextSubscriptionPayload, WireContextSubscriptionCallback, } from './wiring';
22
+ export type { ConfigValue as WireConfigValue, ContextConsumer as WireContextConsumer, ContextProvider as WireContextProvider, ContextProviderOptions as WireContextProviderOptions, ContextValue as WireContextValue, DataCallback as WireDataCallback, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, WireContextSubscriptionPayload, WireContextSubscriptionCallback, } from './wiring';
23
23
  export type { FormRestoreState, FormRestoreReason } from './vm';
24
24
  export { LightningElement } from './base-lightning-element';
25
25
  export { default as api } from './decorators/api';
@@ -1,3 +1,3 @@
1
1
  export { createContextProviderWithRegister, createContextWatcher } from './context';
2
- export { ConfigCallback, ConfigValue, ContextConsumer, ContextProvider, ContextValue, DataCallback, ReplaceReactiveValues, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, WireContextSubscriptionPayload, WireContextSubscriptionCallback, } from './types';
2
+ export { ConfigCallback, ConfigValue, ContextConsumer, ContextProvider, ContextProviderOptions, ContextValue, DataCallback, ReplaceReactiveValues, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, WireContextSubscriptionPayload, WireContextSubscriptionCallback, } from './types';
3
3
  export { connectWireAdapters, disconnectWireAdapters, installWireAdapters, storeWiredFieldMeta, storeWiredMethodMeta, } from './wiring';
package/dist/index.cjs.js CHANGED
@@ -685,6 +685,129 @@ for (const [propName, attrName] of shared.entries(shared.AriaPropNameToAttrNameM
685
685
  }
686
686
  }
687
687
 
688
+ /*
689
+ * Copyright (c) 2024, Salesforce, Inc.
690
+ * All rights reserved.
691
+ * SPDX-License-Identifier: MIT
692
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
693
+ */
694
+ /**
695
+ * Descriptor for IDL attribute reflections that merely reflect the string, e.g. `title`.
696
+ */
697
+ const stringDescriptor = (attrName) => ({
698
+ configurable: true,
699
+ enumerable: true,
700
+ get() {
701
+ return this.getAttribute(attrName);
702
+ },
703
+ set(newValue) {
704
+ const currentValue = this.getAttribute(attrName);
705
+ const normalizedValue = String(newValue);
706
+ if (normalizedValue !== currentValue) {
707
+ this.setAttribute(attrName, normalizedValue);
708
+ }
709
+ },
710
+ });
711
+ /** Descriptor for a boolean that checks for `attr="true"` or `attr="false"`, e.g. `spellcheck` and `draggable`. */
712
+ const explicitBooleanDescriptor = (attrName, defaultValue) => ({
713
+ configurable: true,
714
+ enumerable: true,
715
+ get() {
716
+ const value = this.getAttribute(attrName);
717
+ if (value === null)
718
+ return defaultValue;
719
+ // spellcheck=false => false, everything else => true
720
+ // draggable=true => true, everything else => false
721
+ return value.toLowerCase() === String(defaultValue) ? defaultValue : !defaultValue;
722
+ },
723
+ set(newValue) {
724
+ const currentValue = this.getAttribute(attrName);
725
+ const normalizedValue = String(Boolean(newValue));
726
+ if (normalizedValue !== currentValue) {
727
+ this.setAttribute(attrName, normalizedValue);
728
+ }
729
+ },
730
+ });
731
+ /**
732
+ * Descriptor for a "true" boolean attribute that checks solely for presence, e.g. `hidden`.
733
+ */
734
+ const booleanAttributeDescriptor = (attrName) => ({
735
+ configurable: true,
736
+ enumerable: true,
737
+ get() {
738
+ return this.hasAttribute(attrName);
739
+ },
740
+ set(newValue) {
741
+ const hasAttribute = this.hasAttribute(attrName);
742
+ if (newValue) {
743
+ if (!hasAttribute) {
744
+ this.setAttribute(attrName, '');
745
+ }
746
+ }
747
+ else {
748
+ if (hasAttribute) {
749
+ this.removeAttribute(attrName);
750
+ }
751
+ }
752
+ },
753
+ });
754
+ /**
755
+ * Descriptor for ARIA reflections, e.g. `ariaLabel` and `role`.
756
+ */
757
+ const ariaDescriptor = (attrName) => ({
758
+ configurable: true,
759
+ enumerable: true,
760
+ get() {
761
+ return this.getAttribute(attrName);
762
+ },
763
+ set(newValue) {
764
+ const currentValue = this.getAttribute(attrName);
765
+ if (newValue !== currentValue) {
766
+ // TODO [#3284]: According to the spec, IDL nullable type values
767
+ // (null and undefined) should remove the attribute; however, we
768
+ // only do so in the case of null for historical reasons.
769
+ if (shared.isNull(newValue)) {
770
+ this.removeAttribute(attrName);
771
+ }
772
+ else {
773
+ this.setAttribute(attrName, shared.toString(newValue));
774
+ }
775
+ }
776
+ },
777
+ });
778
+ const tabIndexDescriptor = () => ({
779
+ configurable: true,
780
+ enumerable: true,
781
+ get() {
782
+ const str = this.getAttribute('tabindex');
783
+ const num = Number(str);
784
+ return isFinite(num) ? Math.trunc(num) : -1;
785
+ },
786
+ set(newValue) {
787
+ const currentValue = this.getAttribute('tabindex');
788
+ const num = Number(newValue);
789
+ const normalizedValue = isFinite(num) ? String(Math.trunc(num)) : '0';
790
+ if (normalizedValue !== currentValue) {
791
+ this.setAttribute('tabindex', shared.toString(newValue));
792
+ }
793
+ },
794
+ });
795
+ const descriptors = {
796
+ accessKey: stringDescriptor('accesskey'),
797
+ dir: stringDescriptor('dir'),
798
+ draggable: explicitBooleanDescriptor('draggable', true),
799
+ hidden: booleanAttributeDescriptor('hidden'),
800
+ id: stringDescriptor('id'),
801
+ lang: stringDescriptor('lang'),
802
+ spellcheck: explicitBooleanDescriptor('spellcheck', false),
803
+ tabIndex: tabIndexDescriptor(),
804
+ title: stringDescriptor('title'),
805
+ };
806
+ // Add descriptors for ARIA attributes
807
+ for (const [attrName, propName] of shared.entries(shared.AriaAttrNameToPropNameMap)) {
808
+ descriptors[propName] = ariaDescriptor(attrName);
809
+ }
810
+
688
811
  /*
689
812
  * Copyright (c) 2018, salesforce.com, inc.
690
813
  * All rights reserved.
@@ -2088,7 +2211,7 @@ if (process.env.IS_BROWSER) {
2088
2211
  else {
2089
2212
  // On the server, we cannot use createBridgeToElementDescriptor because getAttribute/setAttribute are
2090
2213
  // not supported on HTMLElement. So apply the polyfill directly on top of LightningElement
2091
- shared.defineProperties(LightningElement.prototype, ariaReflectionPolyfillDescriptors);
2214
+ shared.defineProperties(LightningElement.prototype, descriptors);
2092
2215
  }
2093
2216
  shared.defineProperties(LightningElement.prototype, lightningBasedDescriptors);
2094
2217
  shared.defineProperty(LightningElement, 'CustomElementConstructor', {
@@ -3163,7 +3286,13 @@ function updateStylesheetToken(vm, template, legacy) {
3163
3286
  // Set the new styling token on the host element
3164
3287
  if (!shared.isUndefined(newToken)) {
3165
3288
  if (hasScopedStyles) {
3166
- getClassList(elm).add(makeHostToken(newToken));
3289
+ const hostScopeTokenClass = makeHostToken(newToken);
3290
+ getClassList(elm).add(hostScopeTokenClass);
3291
+ if (!process.env.IS_BROWSER) {
3292
+ // This is only used in SSR to communicate to hydration that
3293
+ // this class should be treated specially for purposes of hydration mismatches.
3294
+ setAttribute(elm, 'data-lwc-host-scope-token', hostScopeTokenClass);
3295
+ }
3167
3296
  newHasTokenInClass = true;
3168
3297
  }
3169
3298
  if (isSyntheticShadow) {
@@ -3300,21 +3429,6 @@ function getScopeTokenClass(owner, legacy) {
3300
3429
  (legacy ? cmpTemplate?.legacyStylesheetToken : cmpTemplate?.stylesheetToken)) ||
3301
3430
  null);
3302
3431
  }
3303
- /**
3304
- * This function returns the host style token for a custom element if it
3305
- * exists. Otherwise it returns null.
3306
- *
3307
- * A host style token is applied to the component if scoped styles are used.
3308
- * @param vnode
3309
- */
3310
- function getStylesheetTokenHost(vnode) {
3311
- const { template } = getComponentInternalDef(vnode.ctor);
3312
- const { vm } = vnode;
3313
- const { stylesheetToken } = template;
3314
- return !shared.isUndefined(stylesheetToken) && computeHasScopedStyles(template, vm)
3315
- ? makeHostToken(stylesheetToken)
3316
- : null;
3317
- }
3318
3432
  function getNearestNativeShadowComponent(vm) {
3319
3433
  const owner = getNearestShadowComponent(vm);
3320
3434
  if (!shared.isNull(owner) && owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
@@ -3852,7 +3966,6 @@ function getComponentHtmlPrototype(Ctor) {
3852
3966
  return def.bridge;
3853
3967
  }
3854
3968
  const lightingElementDef = {
3855
- ctor: LightningElement,
3856
3969
  name: LightningElement.name,
3857
3970
  props: lightningBasedDescriptors,
3858
3971
  propsConfig: EmptyObject,
@@ -5762,7 +5875,7 @@ function dc(Ctor, data, children = EmptyArray) {
5762
5875
  return null;
5763
5876
  }
5764
5877
  if (!isComponentConstructor(Ctor)) {
5765
- throw new Error(`Invalid constructor ${shared.toString(Ctor)} is not a LightningElement constructor.`);
5878
+ throw new Error(`Invalid constructor: "${shared.toString(Ctor)}" is not a LightningElement constructor.`);
5766
5879
  }
5767
5880
  // Look up the dynamic component's name at runtime once the constructor is available.
5768
5881
  // This information is only known at runtime and is stored as part of registerComponent.
@@ -7598,7 +7711,7 @@ function hydrateRoot(vm) {
7598
7711
  runConnectedCallback(vm);
7599
7712
  hydrateVM(vm);
7600
7713
  if (hasMismatch && process.env.NODE_ENV !== 'production') {
7601
- logError('Hydration completed with errors.', vm);
7714
+ logWarn('Hydration completed with errors.', vm);
7602
7715
  }
7603
7716
  }
7604
7717
  function hydrateVM(vm) {
@@ -7853,7 +7966,7 @@ expectAddlSiblings) {
7853
7966
  if (process.env.NODE_ENV !== 'production') {
7854
7967
  if (!hasWarned) {
7855
7968
  hasWarned = true;
7856
- logError(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
7969
+ logWarn(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
7857
7970
  }
7858
7971
  }
7859
7972
  mount(childVnode, parentNode, renderer, nextNode);
@@ -7875,7 +7988,7 @@ expectAddlSiblings) {
7875
7988
  hasMismatch = true;
7876
7989
  if (process.env.NODE_ENV !== 'production') {
7877
7990
  if (!hasWarned) {
7878
- logError(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
7991
+ logWarn(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
7879
7992
  }
7880
7993
  }
7881
7994
  // nextSibling is mostly harmless, and since we don't have
@@ -7908,7 +8021,7 @@ function hasCorrectNodeType(vnode, node, nodeType, renderer) {
7908
8021
  const { getProperty } = renderer;
7909
8022
  if (getProperty(node, 'nodeType') !== nodeType) {
7910
8023
  if (process.env.NODE_ENV !== 'production') {
7911
- logError('Hydration mismatch: incorrect node type received', vnode.owner);
8024
+ logWarn('Hydration mismatch: incorrect node type received', vnode.owner);
7912
8025
  }
7913
8026
  return false;
7914
8027
  }
@@ -7918,7 +8031,7 @@ function isMatchingElement(vnode, elm, renderer, shouldValidateAttr = () => true
7918
8031
  const { getProperty } = renderer;
7919
8032
  if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
7920
8033
  if (process.env.NODE_ENV !== 'production') {
7921
- logError(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
8034
+ logWarn(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
7922
8035
  }
7923
8036
  return false;
7924
8037
  }
@@ -7959,7 +8072,7 @@ function validateAttrs(vnode, elm, data, renderer, shouldValidateAttr) {
7959
8072
  if (!attributeValuesAreEqual(attrValue, elmAttrValue)) {
7960
8073
  if (process.env.NODE_ENV !== 'production') {
7961
8074
  const { getProperty } = renderer;
7962
- logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found ${shared.isNull(elmAttrValue) ? 'null' : `"${elmAttrValue}"`}`, vnode.owner);
8075
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found ${shared.isNull(elmAttrValue) ? 'null' : `"${elmAttrValue}"`}`, vnode.owner);
7963
8076
  }
7964
8077
  nodesAreCompatible = false;
7965
8078
  }
@@ -7970,78 +8083,63 @@ function validateClassAttr(vnode, elm, data, renderer) {
7970
8083
  const { owner } = vnode;
7971
8084
  // classMap is never available on VStaticPartData so it can default to undefined
7972
8085
  // casting to prevent TS error.
7973
- let { className, classMap } = data;
7974
- const { getProperty, getClassList, getAttribute } = renderer;
8086
+ const { className, classMap } = data;
8087
+ const { getProperty } = renderer;
8088
+ // ---------- Step 1: get the classes from the element and the vnode
8089
+ // Use a Set because we don't care to validate mismatches for 1) different ordering in SSR vs CSR, or 2)
8090
+ // duplicated class names. These don't have an effect on rendered styles.
8091
+ const elmClasses = new Set(shared.ArrayFrom(elm.classList));
8092
+ let vnodeClasses;
8093
+ if (!shared.isUndefined(className)) {
8094
+ // ignore empty spaces entirely, filter them out using `filter(..., Boolean)`
8095
+ vnodeClasses = new Set(shared.ArrayFilter.call(shared.StringSplit.call(className, /\s+/), Boolean));
8096
+ }
8097
+ else if (!shared.isUndefined(classMap)) {
8098
+ vnodeClasses = new Set(shared.keys(classMap));
8099
+ }
8100
+ else {
8101
+ vnodeClasses = new Set();
8102
+ }
8103
+ // ---------- Step 2: handle the scope tokens
7975
8104
  // we don't care about legacy for hydration. it's a new use case
7976
- const scopedToken = getScopeTokenClass(owner, /* legacy */ false);
7977
- const stylesheetTokenHost = isVCustomElement(vnode) ? getStylesheetTokenHost(vnode) : null;
8105
+ const scopeToken = getScopeTokenClass(owner, /* legacy */ false);
7978
8106
  // Classnames for scoped CSS are added directly to the DOM during rendering,
7979
8107
  // or to the VDOM on the server in the case of SSR. As such, these classnames
7980
8108
  // are never present in VDOM nodes in the browser.
7981
8109
  //
7982
8110
  // Consequently, hydration mismatches will occur if scoped CSS token classnames
7983
8111
  // are rendered during SSR. This needs to be accounted for when validating.
7984
- if (!shared.isNull(scopedToken) || !shared.isNull(stylesheetTokenHost)) {
7985
- if (!shared.isUndefined(className)) {
7986
- // The order of the className should be scopedToken className stylesheetTokenHost
7987
- const classTokens = [scopedToken, className, stylesheetTokenHost];
7988
- const classNames = shared.ArrayFilter.call(classTokens, (token) => !shared.isNull(token));
7989
- className = shared.ArrayJoin.call(classNames, ' ');
7990
- }
7991
- else if (!shared.isUndefined(classMap)) {
7992
- classMap = {
7993
- ...classMap,
7994
- ...(!shared.isNull(scopedToken) ? { [scopedToken]: true } : {}),
7995
- ...(!shared.isNull(stylesheetTokenHost) ? { [stylesheetTokenHost]: true } : {}),
7996
- };
7997
- }
7998
- else {
7999
- // The order of the className should be scopedToken stylesheetTokenHost
8000
- const classTokens = [scopedToken, stylesheetTokenHost];
8001
- const classNames = shared.ArrayFilter.call(classTokens, (token) => !shared.isNull(token));
8002
- if (classNames.length) {
8003
- className = shared.ArrayJoin.call(classNames, ' ');
8004
- }
8005
- }
8112
+ if (!shared.isNull(scopeToken)) {
8113
+ vnodeClasses.add(scopeToken);
8114
+ }
8115
+ // This tells us which `*-host` scope token was rendered to the element's class.
8116
+ // For now we just ignore any mismatches involving this class.
8117
+ // TODO [#4866]: correctly validate the host scope token class
8118
+ const elmHostScopeToken = renderer.getAttribute(elm, 'data-lwc-host-scope-token');
8119
+ if (!shared.isNull(elmHostScopeToken)) {
8120
+ elmClasses.delete(elmHostScopeToken);
8121
+ vnodeClasses.delete(elmHostScopeToken);
8006
8122
  }
8123
+ // ---------- Step 3: check for compatibility
8007
8124
  let nodesAreCompatible = true;
8008
- let readableVnodeClassname;
8009
- const elmClassName = getAttribute(elm, 'class');
8010
- if (!shared.isUndefined(className) &&
8011
- String(className) !== elmClassName &&
8012
- // No mismatch if SSR `class` attribute is missing and CSR `class` is the empty string
8013
- !(className === '' && shared.isNull(elmClassName))) {
8014
- // className is used when class is bound to an expr.
8125
+ if (vnodeClasses.size !== elmClasses.size) {
8015
8126
  nodesAreCompatible = false;
8016
- // stringify for pretty-printing
8017
- readableVnodeClassname = JSON.stringify(className);
8018
8127
  }
8019
- else if (!shared.isUndefined(classMap)) {
8020
- // classMap is used when class is set to static value.
8021
- const classList = getClassList(elm);
8022
- let computedClassName = '';
8023
- // all classes from the vnode should be in the element.classList
8024
- for (const name in classMap) {
8025
- computedClassName += ' ' + name;
8026
- if (!classList.contains(name)) {
8128
+ else {
8129
+ for (const vnodeClass of vnodeClasses) {
8130
+ if (!elmClasses.has(vnodeClass)) {
8027
8131
  nodesAreCompatible = false;
8028
8132
  }
8029
8133
  }
8030
- // stringify for pretty-printing
8031
- readableVnodeClassname = JSON.stringify(computedClassName.trim());
8032
- if (classList.length > shared.keys(classMap).length) {
8033
- nodesAreCompatible = false;
8134
+ for (const elmClass of elmClasses) {
8135
+ if (!vnodeClasses.has(elmClass)) {
8136
+ nodesAreCompatible = false;
8137
+ }
8034
8138
  }
8035
8139
  }
8036
- else if (shared.isUndefined(className) && !shared.isNull(elmClassName)) {
8037
- // SSR contains a className but client-side VDOM does not
8038
- nodesAreCompatible = false;
8039
- readableVnodeClassname = '""';
8040
- }
8041
- if (!nodesAreCompatible) {
8042
- if (process.env.NODE_ENV !== 'production') {
8043
- logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected ${readableVnodeClassname} but found ${JSON.stringify(elmClassName)}`, vnode.owner);
8044
- }
8140
+ if (process.env.NODE_ENV !== 'production' && !nodesAreCompatible) {
8141
+ const prettyPrint = (set) => JSON.stringify(shared.ArrayJoin.call(shared.ArraySort.call(shared.ArrayFrom(set)), ' '));
8142
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected ${prettyPrint(vnodeClasses)} but found ${prettyPrint(elmClasses)}`, vnode.owner);
8045
8143
  }
8046
8144
  return nodesAreCompatible;
8047
8145
  }
@@ -8082,7 +8180,7 @@ function validateStyleAttr(vnode, elm, data, renderer) {
8082
8180
  if (!nodesAreCompatible) {
8083
8181
  if (process.env.NODE_ENV !== 'production') {
8084
8182
  const { getProperty } = renderer;
8085
- logError(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
8183
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
8086
8184
  }
8087
8185
  }
8088
8186
  return nodesAreCompatible;
@@ -8108,7 +8206,7 @@ function areCompatibleStaticNodes(client, ssr, vnode, renderer) {
8108
8206
  let isCompatibleElements = true;
8109
8207
  if (getProperty(client, 'tagName') !== getProperty(ssr, 'tagName')) {
8110
8208
  if (process.env.NODE_ENV !== 'production') {
8111
- logError(`Hydration mismatch: expecting element with tag "${getProperty(client, 'tagName').toLowerCase()}" but found "${getProperty(ssr, 'tagName').toLowerCase()}".`, owner);
8209
+ logWarn(`Hydration mismatch: expecting element with tag "${getProperty(client, 'tagName').toLowerCase()}" but found "${getProperty(ssr, 'tagName').toLowerCase()}".`, owner);
8112
8210
  }
8113
8211
  return false;
8114
8212
  }
@@ -8121,7 +8219,7 @@ function areCompatibleStaticNodes(client, ssr, vnode, renderer) {
8121
8219
  // partId === 0 will always refer to the root element, this is guaranteed by the compiler.
8122
8220
  if (parts?.[0].partId !== 0) {
8123
8221
  if (process.env.NODE_ENV !== 'production') {
8124
- logError(`Mismatch hydrating element <${getProperty(client, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${getAttribute(client, attrName)}" but found "${getAttribute(ssr, attrName)}"`, owner);
8222
+ logWarn(`Mismatch hydrating element <${getProperty(client, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${getAttribute(client, attrName)}" but found "${getAttribute(ssr, attrName)}"`, owner);
8125
8223
  }
8126
8224
  isCompatibleElements = false;
8127
8225
  }
@@ -8482,5 +8580,5 @@ exports.swapTemplate = swapTemplate;
8482
8580
  exports.track = track;
8483
8581
  exports.unwrap = unwrap;
8484
8582
  exports.wire = wire;
8485
- /** version: 8.7.0 */
8583
+ /** version: 8.9.0 */
8486
8584
  //# sourceMappingURL=index.cjs.js.map