marko 6.2.5 → 6.3.1

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.
@@ -48,6 +48,15 @@ function assertNoSpreadAttrs(tag) {
48
48
  throw attr.buildCodeFrameError(`The [\`<${tagName}>\`](https://markojs.com/docs/reference/core-tag#${tagName}) tag does not support \`...spread\` attributes.`);
49
49
  }
50
50
  }
51
+ function assertNoTagVarMutation(tag) {
52
+ const tagVar = tag.node.var;
53
+ if (tagVar?.type === "Identifier") {
54
+ const constantViolations = tag.scope.getBinding(tagVar.name)?.constantViolations;
55
+ if (constantViolations?.length) {
56
+ for (const assignment of constantViolations) if (assignment.type !== "MarkoTag") throw assignment.buildCodeFrameError(`${tagVar.name} is readonly and cannot be mutated.`);
57
+ }
58
+ }
59
+ }
51
60
  function assertNoBodyContent(tag) {
52
61
  if (tag.node.body.body.length) {
53
62
  const tagName = tag.get("name");
@@ -1919,15 +1928,12 @@ function nonVoidAttr(name, value) {
1919
1928
  case "string": return " " + name + attrAssignment(value);
1920
1929
  case "boolean": return " " + name;
1921
1930
  case "number": return " " + name + "=" + value;
1922
- case "object":
1923
- if (value instanceof RegExp) return " " + name + attrAssignment(value.source);
1924
- break;
1925
1931
  }
1926
1932
  return " " + name + attrAssignment(value + "");
1927
1933
  }
1928
- const singleQuoteAttrReplacements = /'|&(?=#?\w+;)/g;
1929
- const doubleQuoteAttrReplacements = /"|&(?=#?\w+;)/g;
1930
- const needsQuotedAttr = /["'>\s]|&#?\w+;|\/$/g;
1934
+ const singleQuoteAttrReplacements = /'|&(?=[#a-zA-Z])/g;
1935
+ const doubleQuoteAttrReplacements = /"|&(?=[#a-zA-Z])/g;
1936
+ const needsQuotedAttr = /["'>\s]|&[#a-zA-Z]|\/$/g;
1931
1937
  function attrAssignment(value) {
1932
1938
  return value ? needsQuotedAttr.test(value) ? value[needsQuotedAttr.lastIndex - 1] === (needsQuotedAttr.lastIndex = 0, "\"") ? "='" + escapeSingleQuotedAttrValue(value) + "'" : "=\"" + escapeDoubleQuotedAttrValue(value) + "\"" : "=" + value : "";
1933
1939
  }
@@ -2128,6 +2134,9 @@ function sectionHasSetupStatements(section) {
2128
2134
  }
2129
2135
  //#endregion
2130
2136
  //#region src/translator/util/binding-has-prop.ts
2137
+ function isSectionRendererElided(section) {
2138
+ return !!section.downstreamBinding && !bindingHasProperty(section.downstreamBinding.binding, section.downstreamBinding.properties);
2139
+ }
2131
2140
  function bindingHasProperty(binding, properties) {
2132
2141
  if (binding.pruned) return false;
2133
2142
  else if (binding.pruned === void 0) throw new Error("Binding must be pruned before checking properties");
@@ -2821,7 +2830,7 @@ function setSectionSerializedValue(section, prop, expression) {
2821
2830
  }
2822
2831
  function setBindingSerializedValue(section, binding, expression, prefix) {
2823
2832
  const reason = getSerializeReason(section, binding, prefix);
2824
- if (reason) getSerializedAccessors(section).set((prefix || "") + getScopeAccessor(binding), {
2833
+ if (reason) getSerializedAccessors(section).set(prefix === void 0 ? getScopeAccessor(binding) : getPrefixedScopeAccessor(binding, prefix), {
2825
2834
  expression,
2826
2835
  reason
2827
2836
  });
@@ -2905,7 +2914,7 @@ function getSignal(section, referencedBindings, name) {
2905
2914
  const render = getSignalFn(signal);
2906
2915
  const closureSignalBuilder = getClosureSignalBuilder(section);
2907
2916
  if (closureSignalBuilder && !isDynamicClosure(section, closure)) return closureSignalBuilder(closure, render);
2908
- return callRuntime("_closure_get", getScopeAccessorLiteral(closure, true), render, isImmediateOwner(section, closure) ? void 0 : _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], getScopeExpression(section, closure.section)), some(closure.closureSections, underTryPlaceholder) ? _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")) : void 0);
2917
+ return callRuntime("_closure_get", isOptimize() ? _marko_compiler.types.numericLiteral(getClosureAccessorId(closure)) : getScopeAccessorLiteral(closure, true), render, isImmediateOwner(section, closure) ? void 0 : _marko_compiler.types.arrowFunctionExpression([scopeIdentifier], getScopeExpression(section, closure.section)), some(closure.closureSections, underTryPlaceholder) ? _marko_compiler.types.stringLiteral(getResumeRegisterId(section, closure, "pending")) : void 0);
2909
2918
  };
2910
2919
  }
2911
2920
  return signal;
@@ -3507,7 +3516,7 @@ var dom_default = { translate: {
3507
3516
  const setup = getSetup(childSection);
3508
3517
  const written = writeSignals(childSection);
3509
3518
  const setupIdentifier = setup && written.has(setup) ? setup.identifier : void 0;
3510
- if (!childSection.downstreamBinding || bindingHasProperty(childSection.downstreamBinding.binding, childSection.downstreamBinding.properties)) if (getSectionParentIsOwner(childSection)) setBranchRendererArgs(childSection, [
3519
+ if (!isSectionRendererElided(childSection)) if (getSectionParentIsOwner(childSection)) setBranchRendererArgs(childSection, [
3511
3520
  writes,
3512
3521
  walks,
3513
3522
  setupIdentifier,
@@ -4263,9 +4272,12 @@ function buildContent(body) {
4263
4272
  if (dynamicSerializeReason) body.node.body.unshift(getScopeReasonDeclaration(bodySection));
4264
4273
  else body.node.body.unshift(_marko_compiler.types.expressionStatement(callRuntime("_scope_reason")));
4265
4274
  return callRuntime(serialized ? "_content_resume" : "_content", _marko_compiler.types.stringLiteral(getResumeRegisterId(bodySection, "content")), _marko_compiler.types.arrowFunctionExpression(body.node.params, _marko_compiler.types.blockStatement(body.node.body)), serialized ? getScopeIdIdentifier(getSection(getAttributeTagParent(body.parentPath))) : void 0);
4266
- } else return _marko_compiler.types.callExpression(_marko_compiler.types.identifier(bodySection.name), bodySection.referencedLocalClosures ? [scopeIdentifier, _marko_compiler.types.objectExpression(toArray(bodySection.referencedLocalClosures, (ref) => {
4267
- return toObjectProperty(getScopeAccessor(ref, true), getDeclaredBindingExpression(ref));
4268
- }))] : [scopeIdentifier]);
4275
+ } else {
4276
+ if (isSectionRendererElided(bodySection)) return;
4277
+ return _marko_compiler.types.callExpression(_marko_compiler.types.identifier(bodySection.name), bodySection.referencedLocalClosures ? [scopeIdentifier, _marko_compiler.types.objectExpression(toArray(bodySection.referencedLocalClosures, (ref) => {
4278
+ return toObjectProperty(getScopeAccessor(ref, true), getDeclaredBindingExpression(ref));
4279
+ }))] : [scopeIdentifier]);
4280
+ }
4269
4281
  }
4270
4282
  //#endregion
4271
4283
  //#region src/translator/visitors/tag/native-tag.ts
@@ -5243,7 +5255,11 @@ function preAnalyze$1(tag) {
5243
5255
  for (const child of tag.node.body.body) if (child.type === "MarkoText" || child.type === "MarkoPlaceholder" && child.escape) parts.push(child.value);
5244
5256
  else throw tag.hub.file.hub.buildError(child, "Unexpected content in textarea, only text and placeholders are supported.", SyntaxError);
5245
5257
  const textValue = normalizeStringExpression(parts);
5246
- if (textValue) tag.node.attributes.push(_marko_compiler.types.markoAttribute("value", textValue));
5258
+ if (textValue) {
5259
+ const valueAttr = tag.node.attributes.find((attr) => _marko_compiler.types.isMarkoAttribute(attr) && attr.name === "value");
5260
+ if (valueAttr) throw tag.hub.file.hub.buildError(valueAttr, "A textarea cannot have both a value attribute and body content.", SyntaxError);
5261
+ tag.node.attributes.push(_marko_compiler.types.markoAttribute("value", textValue));
5262
+ }
5247
5263
  tag.node.body.body = [];
5248
5264
  }
5249
5265
  }
@@ -6292,7 +6308,8 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6292
6308
  nullable: !sameSection || excludeProperties === void 0,
6293
6309
  pruned: void 0,
6294
6310
  exposed: false,
6295
- forcePersist: false
6311
+ forcePersist: false,
6312
+ reserveSize: 0
6296
6313
  };
6297
6314
  if (property) {
6298
6315
  if (declared) upstreamAlias.nullable = false;
@@ -6436,6 +6453,7 @@ function trackAssignment(assignment, binding) {
6436
6453
  fnExtra.section = idExtra.section = section;
6437
6454
  }
6438
6455
  if (binding.upstreamAlias && binding.property !== void 0) {
6456
+ if (binding.upstreamAlias === binding.section.params) throw assignment.buildCodeFrameError(`\`${binding.name}\` is a tag parameter and cannot be assigned to.`);
6439
6457
  const changePropName = binding.property + "Change";
6440
6458
  const changeBinding = binding.upstreamAlias.propertyAliases.get(changePropName) || createBinding(generateUid(changePropName), binding.type, binding.section, binding.upstreamAlias, changePropName, void 0, id.node.loc, true);
6441
6459
  idExtra.assignmentTo = changeBinding;
@@ -6758,22 +6776,30 @@ function finalizeReferences() {
6758
6776
  });
6759
6777
  }
6760
6778
  let intersectionIndex = 0;
6761
- let lastBindingIndex = 0;
6779
+ let nextId = 0;
6762
6780
  let intersection;
6763
- forEach(filter(bindings, isOwnedBinding), (binding, bindingIndex) => {
6764
- binding.id = (lastBindingIndex = bindingIndex) + intersectionIndex;
6765
- while (intersectionIndex < intersections.length && (intersection = intersections[intersectionIndex]).filter(isOwnedBinding).at(-1) === binding) intersectionMeta.set(intersection, {
6766
- id: bindingIndex + ++intersectionIndex,
6767
- scopeOffset: getMaxOwnSourceOffset(intersection, section)
6768
- });
6781
+ forEach(filter(bindings, isOwnedBinding), (binding) => {
6782
+ binding.id = nextId++;
6783
+ nextId += binding.reserveSize;
6784
+ while (intersectionIndex < intersections.length && (intersection = intersections[intersectionIndex]).filter(isOwnedBinding).at(-1) === binding) {
6785
+ intersectionIndex++;
6786
+ intersectionMeta.set(intersection, {
6787
+ id: nextId++,
6788
+ scopeOffset: getMaxOwnSourceOffset(intersection, section)
6789
+ });
6790
+ }
6769
6791
  });
6770
6792
  while (intersectionIndex < intersections.length) {
6771
6793
  intersection = intersections[intersectionIndex];
6794
+ intersectionIndex++;
6772
6795
  intersectionMeta.set(intersection, {
6773
- id: lastBindingIndex + ++intersectionIndex,
6796
+ id: nextId++,
6774
6797
  scopeOffset: getMaxOwnSourceOffset(intersection, section)
6775
6798
  });
6776
6799
  }
6800
+ forEach(filter(bindings, isOwnedBinding), (binding) => {
6801
+ if (binding.closureSections) closureAccessorIds.set(binding, nextId++);
6802
+ });
6777
6803
  });
6778
6804
  const programSection = (0, _marko_compiler_babel_utils.getProgram)().node.extra.section;
6779
6805
  if (programSection.returnValueExpr) programSection.returnSerializeReason = getSerializeSourcesForExpr(programSection.returnValueExpr);
@@ -6793,6 +6819,7 @@ function getMaxOwnSourceOffset(intersection, section) {
6793
6819
  return scopeOffset;
6794
6820
  }
6795
6821
  const intersectionMeta = /* @__PURE__ */ new WeakMap();
6822
+ const closureAccessorIds = /* @__PURE__ */ new WeakMap();
6796
6823
  const collapsedIntersectionSource = /* @__PURE__ */ new WeakMap();
6797
6824
  function getCollapsibleIntersectionSource(intersection, section) {
6798
6825
  let sources;
@@ -7009,6 +7036,20 @@ function getScopeAccessor(binding, encoded, includeId) {
7009
7036
  else if (includeId || canonicalBinding.type === 0) return `${canonicalBinding.name}/${canonicalBinding.id}`;
7010
7037
  return canonicalBinding.scopeAccessor ?? canonicalBinding.name;
7011
7038
  }
7039
+ function getPrefixedScopeAccessor(binding, prefix) {
7040
+ const canonicalBinding = getCanonicalBinding(binding);
7041
+ if (isOptimize()) switch (prefix) {
7042
+ case getAccessorPrefix().TagVariableChange: return decodeAccessor(canonicalBinding.id + 1);
7043
+ case getAccessorPrefix().ClosureScopes: return decodeAccessor(getClosureAccessorId(canonicalBinding));
7044
+ case getAccessorPrefix().ClosureSignalIndex: return prefix + decodeAccessor(getClosureAccessorId(canonicalBinding));
7045
+ }
7046
+ return prefix + getScopeAccessor(binding);
7047
+ }
7048
+ function getClosureAccessorId(binding) {
7049
+ const id = closureAccessorIds.get(getCanonicalBinding(binding));
7050
+ if (id === void 0) throw new Error(`No closure accessor id was reserved for "${binding.name}".`);
7051
+ return id;
7052
+ }
7012
7053
  function getDebugScopeAccess(binding) {
7013
7054
  let root = binding;
7014
7055
  let access = "";
@@ -7540,12 +7581,7 @@ var const_default = {
7540
7581
  if (upstreamAlias) dropNodes(valueAttr.value);
7541
7582
  const binding = trackVarReferences(tag, 5, upstreamAlias);
7542
7583
  if (binding) {
7543
- if (node.var.type === "Identifier") {
7544
- const constantViolations = tag.scope.getBinding(node.var.name)?.constantViolations;
7545
- if (constantViolations?.length) {
7546
- for (const assignment of constantViolations) if (assignment.type !== "MarkoTag") throw assignment.buildCodeFrameError(`${node.var.name} is readonly and cannot be mutated.`);
7547
- }
7548
- }
7584
+ assertNoTagVarMutation(tag);
7549
7585
  if (!valueExtra.nullable) binding.nullable = false;
7550
7586
  if (!upstreamAlias) {
7551
7587
  setBindingDownstream(binding, valueExtra);
@@ -7617,6 +7653,7 @@ var define_default = {
7617
7653
  dropNodes(getAllTagReferenceNodes(tag.node));
7618
7654
  return;
7619
7655
  }
7656
+ assertNoTagVarMutation(tag);
7620
7657
  const paramsBinding = trackParamsReferences(tagBody, 3);
7621
7658
  setTagDownstream(tag, varBinding);
7622
7659
  if (bodySection) {
@@ -7834,7 +7871,10 @@ var id_default = {
7834
7871
  if (!_marko_compiler.types.isIdentifier(node.var)) throw tag.get("var").buildCodeFrameError("The [`<id>` tag](https://markojs.com/docs/reference/core-tag#id) cannot be destructured.");
7835
7872
  if (tag.node.attributes.length > 1 || tag.node.attributes.length === 1 && (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value")) throw tag.get("name").buildCodeFrameError("The [`<id>` tag](https://markojs.com/docs/reference/core-tag#id) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
7836
7873
  const binding = trackVarReferences(tag, 5);
7837
- if (binding) setBindingDownstream(binding, !!valueAttr && evaluate(valueAttr.value));
7874
+ if (binding) {
7875
+ assertNoTagVarMutation(tag);
7876
+ setBindingDownstream(binding, !!valueAttr && evaluate(valueAttr.value));
7877
+ }
7838
7878
  addSetupExpr(getOrCreateSection(tag), valueAttr?.value);
7839
7879
  },
7840
7880
  translate: { exit(tag) {
@@ -7888,9 +7928,13 @@ var let_default = {
7888
7928
  const tagVar = node.var;
7889
7929
  let valueAttr;
7890
7930
  let valueChangeAttr;
7891
- for (const attr of node.attributes) if (_marko_compiler.types.isMarkoAttribute(attr)) if (attr.name === "value") valueAttr = attr;
7892
- else if (attr.name === "valueChange") valueChangeAttr = attr;
7893
- else {
7931
+ for (const attr of node.attributes) if (_marko_compiler.types.isMarkoAttribute(attr)) if (attr.name === "value") {
7932
+ if (valueAttr) throw tag.hub.buildError(attr, "Invalid duplicate value attribute.");
7933
+ valueAttr = attr;
7934
+ } else if (attr.name === "valueChange") {
7935
+ if (valueChangeAttr) throw tag.hub.buildError(attr, "Invalid duplicate valueChange attribute.");
7936
+ valueChangeAttr = attr;
7937
+ } else {
7894
7938
  const start = attr.loc?.start;
7895
7939
  const end = attr.loc?.end;
7896
7940
  const msg = "The [`<let>` tag](https://markojs.com/docs/reference/core-tag#let) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value) and its change handler.";
@@ -7911,6 +7955,7 @@ var let_default = {
7911
7955
  const binding = trackVarReferences(tag, 1);
7912
7956
  const tagExtra = mergeReferences(tagSection, tag.node, [valueAttr?.value, valueChangeAttr?.value]);
7913
7957
  if (valueChangeAttr) {
7958
+ binding.reserveSize = 1;
7914
7959
  setBindingDownstream(binding, tagExtra);
7915
7960
  if (binding.assignmentSections) addSerializeReason(tagSection, true, binding, getAccessorPrefix().TagVariableChange);
7916
7961
  } else setBindingDownstream(binding, false);
@@ -8914,12 +8959,13 @@ var placeholder_default = {
8914
8959
  const siblingText = extra[kSiblingText];
8915
8960
  const markerSerializeReason = nodeBinding && getSerializeReason(section, nodeBinding);
8916
8961
  if (siblingText === 1) {
8917
- if (isHTML && markerSerializeReason) if (markerSerializeReason === true || markerSerializeReason.state) write`<!>`;
8918
- else write`${callRuntime("_sep", getSerializeGuard(section, markerSerializeReason, true))}`;
8962
+ if (isHTML && markerSerializeReason) writeSeparator(write, section, markerSerializeReason);
8919
8963
  visit(placeholder, 37);
8920
8964
  } else if (siblingText === 2) visit(placeholder, 37);
8921
8965
  else {
8922
- if (!isHTML) write` `;
8966
+ if (isHTML) {
8967
+ if (siblingText === 3 && markerSerializeReason) writeSeparator(write, section, markerSerializeReason);
8968
+ } else write` `;
8923
8969
  visit(placeholder, 32);
8924
8970
  }
8925
8971
  if (isHTML) {
@@ -8951,8 +8997,13 @@ function buildEscapedTextExpression(value) {
8951
8997
  default: return callRuntime("_escape", value);
8952
8998
  }
8953
8999
  }
9000
+ function writeSeparator(write, section, reason) {
9001
+ if (reason === true || reason.state) write`<!>`;
9002
+ else write`${callRuntime("_sep", getSerializeGuard(section, reason, true))}`;
9003
+ }
8954
9004
  function analyzeSiblingText(placeholder) {
8955
9005
  const placeholderExtra = placeholder.node.extra;
9006
+ let hasNodeBefore = false;
8956
9007
  let prev = placeholder.getPrevSibling();
8957
9008
  let prevParent = placeholder.parentPath;
8958
9009
  for (;;) {
@@ -8968,7 +9019,10 @@ function analyzeSiblingText(placeholder) {
8968
9019
  const contentType = getNodeContentType(prev, "endType");
8969
9020
  if (contentType === null) prev = prev.getPrevSibling();
8970
9021
  else if (contentType === 4 || contentType === 1 || contentType === 2) return placeholderExtra[kSiblingText] = 1;
8971
- else break;
9022
+ else {
9023
+ hasNodeBefore = true;
9024
+ break;
9025
+ }
8972
9026
  }
8973
9027
  if (!prev.node && prevParent.isProgram()) return placeholderExtra[kSiblingText] = 1;
8974
9028
  let next = placeholder.getNextSibling();
@@ -8989,7 +9043,7 @@ function analyzeSiblingText(placeholder) {
8989
9043
  else break;
8990
9044
  }
8991
9045
  if (!next.node && nextParent.isProgram()) return placeholderExtra[kSiblingText] = 2;
8992
- return placeholderExtra[kSiblingText] = 0;
9046
+ return placeholderExtra[kSiblingText] = hasNodeBefore ? 3 : 0;
8993
9047
  }
8994
9048
  function getInlinedBodyTag(parent) {
8995
9049
  if (parent.isMarkoTagBody()) {
@@ -1,3 +1,4 @@
1
1
  import type { types as t } from "@marko/compiler";
2
2
  export declare function assertNoSpreadAttrs(tag: t.NodePath<t.MarkoTag>): void;
3
+ export declare function assertNoTagVarMutation(tag: t.NodePath<t.MarkoTag>): void;
3
4
  export declare function assertNoBodyContent(tag: t.NodePath<t.MarkoTag>): void;
@@ -1,3 +1,5 @@
1
1
  import type { Opt } from "./optional";
2
2
  import type { Binding } from "./references";
3
+ import type { Section } from "./sections";
4
+ export declare function isSectionRendererElided(section: Section): boolean;
3
5
  export declare function bindingHasProperty(binding: Binding, properties: Opt<string>): boolean;
@@ -1,4 +1,5 @@
1
1
  import { types as t } from "@marko/compiler";
2
+ import type { AccessorPrefix } from "../../common/accessor.debug";
2
3
  import { type Many, type Opt, Sorted } from "./optional";
3
4
  import { type Section } from "./sections";
4
5
  import { type SerializeReason } from "./serialize-reasons";
@@ -50,6 +51,7 @@ export interface Binding {
50
51
  pruned: boolean | undefined;
51
52
  exposed: boolean;
52
53
  forcePersist: boolean;
54
+ reserveSize: number;
53
55
  }
54
56
  export interface InputBinding extends Binding {
55
57
  type: BindingType.input;
@@ -142,6 +144,8 @@ export declare function getCanonicalBinding(binding: Binding): Binding;
142
144
  export declare function getAllTagReferenceNodes(tag: t.MarkoTag, referenceNodes?: t.Node[]): t.Node[];
143
145
  export declare function getScopeAccessorLiteral(binding: Binding, encoded?: boolean, includeId?: boolean): t.NumericLiteral | t.StringLiteral;
144
146
  export declare function getScopeAccessor(binding: Binding, encoded?: boolean, includeId?: boolean): string;
147
+ export declare function getPrefixedScopeAccessor(binding: Binding, prefix: AccessorPrefix): string;
148
+ export declare function getClosureAccessorId(binding: Binding): number;
145
149
  export declare function getDebugScopeAccess(binding: Binding): {
146
150
  root: Binding;
147
151
  access: string;
@@ -6,7 +6,8 @@ declare const kSharedText: unique symbol;
6
6
  declare enum SiblingText {
7
7
  None = 0,
8
8
  Before = 1,
9
- After = 2
9
+ After = 2,
10
+ NodeBefore = 3
10
11
  }
11
12
  declare module "@marko/compiler/dist/types" {
12
13
  interface MarkoPlaceholderExtra {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.2.5",
3
+ "version": "6.3.1",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",
@@ -1,7 +1,10 @@
1
1
  /** File for types only, not actual implementation **/
2
2
 
3
- export type Input<T extends object> = T & {
4
- onMount?(): unknown;
5
- onUpdate?(): unknown;
6
- onDestroy?(): unknown;
3
+ export type Input<
4
+ T extends object,
5
+ R extends object = {},
6
+ > = T & ThisType<T & R> & {
7
+ onMount?: () => R | void;
8
+ onUpdate?: () => void;
9
+ onDestroy?: () => void;
7
10
  };