rip-lang 3.13.26 → 3.13.28

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/docs/dist/rip.js CHANGED
@@ -1522,7 +1522,7 @@
1522
1522
  return 0;
1523
1523
  let m = /^#([a-zA-Z_][\w-]*)/.exec(this.chunk);
1524
1524
  if (m) {
1525
- this.emit("IDENTIFIER", "div#" + m[1]);
1525
+ this.emit("IDENTIFIER", m[1] === "content" ? "slot" : "div#" + m[1]);
1526
1526
  return m[0].length;
1527
1527
  }
1528
1528
  }
@@ -3445,7 +3445,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3445
3445
  var TEMPLATE_TAGS = new Set([...HTML_TAGS, ...SVG_TAGS]);
3446
3446
  var BIND_PREFIX = "__bind_";
3447
3447
  var BIND_SUFFIX = "__";
3448
- var LIFECYCLE_HOOKS = new Set(["beforeMount", "mounted", "updated", "beforeUnmount", "unmounted"]);
3448
+ var LIFECYCLE_HOOKS = new Set(["beforeMount", "mounted", "updated", "beforeUnmount", "unmounted", "onError"]);
3449
3449
  var BOOLEAN_ATTRS = new Set([
3450
3450
  "disabled",
3451
3451
  "hidden",
@@ -3492,19 +3492,6 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3492
3492
  function isPublicProp(target) {
3493
3493
  return Array.isArray(target) && target[0] === "." && target[1] === "this";
3494
3494
  }
3495
- function getFragChildren(rootVar, createLines, localizeVar) {
3496
- const root = localizeVar(rootVar);
3497
- if (!/_frag\d+$/.test(root))
3498
- return null;
3499
- const children = [];
3500
- const re = new RegExp(`^${root.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.appendChild\\(([^)]+)\\);`);
3501
- for (const line of createLines) {
3502
- const m = localizeVar(line).match(re);
3503
- if (m)
3504
- children.push(m[1]);
3505
- }
3506
- return children.length > 0 ? children : null;
3507
- }
3508
3495
  function installComponentSupport(CodeGenerator, Lexer2) {
3509
3496
  Lexer2.prototype.rewriteRender = function() {
3510
3497
  let gen2 = (tag, val, origin) => {
@@ -3608,6 +3595,14 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3608
3595
  }
3609
3596
  if (!inRender)
3610
3597
  return 1;
3598
+ if (tag === "UNARY_MATH" && token[1] === "~" && nextToken && nextToken[0] === "IDENTIFIER") {
3599
+ token[0] = "PROPERTY";
3600
+ token[1] = "__transition__";
3601
+ let colonToken = gen2(":", ":", token);
3602
+ let valueToken = gen2("STRING", `"${nextToken[1]}"`, nextToken);
3603
+ tokens.splice(i + 1, 1, colonToken, valueToken);
3604
+ return 1;
3605
+ }
3611
3606
  if (tag === "IDENTIFIER" && !token.spaced) {
3612
3607
  let parts = [token[1]];
3613
3608
  let j = i + 1;
@@ -3635,9 +3630,12 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3635
3630
  let prevTag = prevToken ? prevToken[0] : null;
3636
3631
  if (prevTag === "INDENT" || prevTag === "TERMINATOR") {
3637
3632
  if (nextToken && nextToken[0] === "PROPERTY") {
3638
- let divToken = gen2("IDENTIFIER", "div", token);
3639
- tokens.splice(i, 0, divToken);
3640
- return 2;
3633
+ let nextNext = i + 2 < tokens.length ? tokens[i + 2] : null;
3634
+ if (!nextNext || nextNext[0] !== ":") {
3635
+ let divToken = gen2("IDENTIFIER", "div", token);
3636
+ tokens.splice(i, 0, divToken);
3637
+ return 2;
3638
+ }
3641
3639
  }
3642
3640
  if (!nextToken || nextToken[0] !== "(") {
3643
3641
  token[0] = "IDENTIFIER";
@@ -3714,19 +3712,8 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3714
3712
  }
3715
3713
  }
3716
3714
  if (nextToken && nextToken[0] === "INDENT") {
3717
- if (nextToken.fromThen) {
3718
- let depth = 0;
3719
- for (let j = i;j >= 0; j--) {
3720
- let jt = tokens[j][0];
3721
- if (jt === "INTERPOLATION_END" || jt === "STRING_END")
3722
- depth++;
3723
- if (jt === "INTERPOLATION_START" || jt === "STRING_START")
3724
- depth--;
3725
- if (depth < 0) {
3726
- return 1;
3727
- }
3728
- }
3729
- }
3715
+ if (nextToken.fromThen)
3716
+ return 1;
3730
3717
  if (tag === "->" || tag === "=>" || tag === "CALL_START" || tag === "(") {
3731
3718
  return 1;
3732
3719
  }
@@ -3751,27 +3738,15 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3751
3738
  isTemplateElement = true;
3752
3739
  } else if (tag === "IDENTIFIER" && isTemplateTag(token[1]) && !isAfterControlFlow) {
3753
3740
  isTemplateElement = true;
3754
- } else if (tag === "PROPERTY" || tag === "STRING" || tag === "STRING_END" || tag === "IDENTIFIER" || tag === "NUMBER" || tag === "BOOL" || tag === "CALL_END" || tag === ")") {
3741
+ } else if (tag === "IDENTIFIER" && !isAfterControlFlow) {
3742
+ isTemplateElement = startsWithTag(tokens, i);
3743
+ } else if (tag === "PROPERTY" || tag === "STRING" || tag === "STRING_END" || tag === "NUMBER" || tag === "BOOL" || tag === "CALL_END" || tag === ")") {
3755
3744
  isTemplateElement = startsWithTag(tokens, i);
3756
- } else if (tag === "IDENTIFIER" && i > 1 && tokens[i - 1][0] === "...") {
3757
- if (startsWithTag(tokens, i)) {
3758
- let commaToken = gen2(",", ",", token);
3759
- let arrowToken = gen2("->", "->", token);
3760
- arrowToken.newLine = true;
3761
- tokens.splice(i + 1, 0, commaToken, arrowToken);
3762
- return 3;
3763
- }
3764
3745
  }
3765
3746
  if (isTemplateElement) {
3766
3747
  let isClassOrIdTail = tag === "PROPERTY" && i > 0 && (tokens[i - 1][0] === "." || tokens[i - 1][0] === "#");
3767
- if (isClsxCallEnd) {
3768
- let callStartToken = gen2("CALL_START", "(", token);
3769
- let arrowToken = gen2("->", "->", token);
3770
- arrowToken.newLine = true;
3771
- tokens.splice(i + 1, 0, callStartToken, arrowToken);
3772
- pendingCallEnds.push(currentIndent + 1);
3773
- return 3;
3774
- } else if (tag === "IDENTIFIER" && isTemplateTag(token[1]) || isClassOrIdTail) {
3748
+ let isBareTag = isClsxCallEnd || tag === "IDENTIFIER" && isTemplateTag(token[1]) || isClassOrIdTail;
3749
+ if (isBareTag) {
3775
3750
  let callStartToken = gen2("CALL_START", "(", token);
3776
3751
  let arrowToken = gen2("->", "->", token);
3777
3752
  arrowToken.newLine = true;
@@ -3795,11 +3770,6 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3795
3770
  });
3796
3771
  };
3797
3772
  const proto = CodeGenerator.prototype;
3798
- proto.localizeVar = function(line) {
3799
- let result = line.replace(/this\.(_el\d+|_t\d+|_anchor\d+|_frag\d+|_slot\d+|_c\d+|_inst\d+|_empty\d+)/g, "$1");
3800
- result = result.replace(/\bthis\b/g, "ctx");
3801
- return result;
3802
- };
3803
3773
  proto.isHtmlTag = function(name) {
3804
3774
  const tagPart = name.split("#")[0];
3805
3775
  return TEMPLATE_TAGS.has(tagPart.toLowerCase());
@@ -3828,21 +3798,22 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3828
3798
  return { tag, classes, id };
3829
3799
  };
3830
3800
  proto.transformComponentMembers = function(sexpr) {
3801
+ const self = this._self;
3831
3802
  if (!Array.isArray(sexpr)) {
3832
3803
  if (typeof sexpr === "string" && this.reactiveMembers && this.reactiveMembers.has(sexpr)) {
3833
- return [".", [".", "this", sexpr], "value"];
3804
+ return [".", [".", self, sexpr], "value"];
3834
3805
  }
3835
3806
  if (typeof sexpr === "string" && this.componentMembers && this.componentMembers.has(sexpr)) {
3836
- return [".", "this", sexpr];
3807
+ return [".", self, sexpr];
3837
3808
  }
3838
3809
  return sexpr;
3839
3810
  }
3840
3811
  if (sexpr[0] === "." && sexpr[1] === "this" && typeof sexpr[2] === "string") {
3841
3812
  const memberName = sexpr[2];
3842
3813
  if (this.reactiveMembers && this.reactiveMembers.has(memberName)) {
3843
- return [".", sexpr, "value"];
3814
+ return [".", [".", self, memberName], "value"];
3844
3815
  }
3845
- return sexpr;
3816
+ return this._factoryMode ? [".", self, sexpr[2]] : sexpr;
3846
3817
  }
3847
3818
  if (sexpr[0] === "." || sexpr[0] === "?.") {
3848
3819
  return [sexpr[0], this.transformComponentMembers(sexpr[1]), sexpr[2]];
@@ -3988,11 +3959,12 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3988
3959
  }
3989
3960
  for (const { name, value } of lifecycleHooks) {
3990
3961
  if (Array.isArray(value) && (value[0] === "->" || value[0] === "=>")) {
3991
- const [, , hookBody] = value;
3962
+ const [, params, hookBody] = value;
3963
+ const paramStr = Array.isArray(params) ? params.map((p) => this.formatParam(p)).join(", ") : "";
3992
3964
  const transformed = this.reactiveMembers ? this.transformComponentMembers(hookBody) : hookBody;
3993
3965
  const isAsync = this.containsAwait(hookBody);
3994
- const bodyCode = this.generateFunctionBody(transformed, []);
3995
- lines.push(` ${isAsync ? "async " : ""}${name}() ${bodyCode}`);
3966
+ const bodyCode = this.generateFunctionBody(transformed, params || []);
3967
+ lines.push(` ${isAsync ? "async " : ""}${name}(${paramStr}) ${bodyCode}`);
3996
3968
  }
3997
3969
  }
3998
3970
  if (renderBlock) {
@@ -4033,10 +4005,10 @@ ${blockFactoriesCode}return ${lines.join(`
4033
4005
  };
4034
4006
  proto.generateInComponent = function(sexpr, context) {
4035
4007
  if (typeof sexpr === "string" && this.reactiveMembers && this.reactiveMembers.has(sexpr)) {
4036
- return `this.${sexpr}.value`;
4008
+ return `${this._self}.${sexpr}.value`;
4037
4009
  }
4038
4010
  if (typeof sexpr === "string" && this.componentMembers && this.componentMembers.has(sexpr)) {
4039
- return `this.${sexpr}`;
4011
+ return `${this._self}.${sexpr}`;
4040
4012
  }
4041
4013
  if (Array.isArray(sexpr) && this.reactiveMembers) {
4042
4014
  const transformed = this.transformComponentMembers(sexpr);
@@ -4055,6 +4027,9 @@ ${blockFactoriesCode}return ${lines.join(`
4055
4027
  this._setupLines = [];
4056
4028
  this._blockFactories = [];
4057
4029
  this._loopVarStack = [];
4030
+ this._factoryMode = false;
4031
+ this._factoryVars = null;
4032
+ this._fragChildren = new Map;
4058
4033
  const statements = this.is(body, "block") ? body.slice(1) : [body];
4059
4034
  let rootVar;
4060
4035
  if (statements.length === 0) {
@@ -4064,10 +4039,13 @@ ${blockFactoriesCode}return ${lines.join(`
4064
4039
  } else {
4065
4040
  rootVar = this.newElementVar("frag");
4066
4041
  this._createLines.push(`${rootVar} = document.createDocumentFragment();`);
4042
+ const children = [];
4067
4043
  for (const stmt of statements) {
4068
4044
  const childVar = this.generateNode(stmt);
4069
4045
  this._createLines.push(`${rootVar}.appendChild(${childVar});`);
4046
+ children.push(childVar);
4070
4047
  }
4048
+ this._fragChildren.set(rootVar, children);
4071
4049
  }
4072
4050
  return {
4073
4051
  createLines: this._createLines,
@@ -4080,10 +4058,28 @@ ${blockFactoriesCode}return ${lines.join(`
4080
4058
  return `create_block_${this._blockCount++}`;
4081
4059
  };
4082
4060
  proto.newElementVar = function(hint = "el") {
4083
- return `this._${hint}${this._elementCount++}`;
4061
+ const name = `_${hint}${this._elementCount++}`;
4062
+ if (this._factoryVars)
4063
+ this._factoryVars.add(name);
4064
+ return this._factoryMode ? name : `this.${name}`;
4084
4065
  };
4085
4066
  proto.newTextVar = function() {
4086
- return `this._t${this._textCount++}`;
4067
+ const name = `_t${this._textCount++}`;
4068
+ if (this._factoryVars)
4069
+ this._factoryVars.add(name);
4070
+ return this._factoryMode ? name : `this.${name}`;
4071
+ };
4072
+ Object.defineProperty(proto, "_self", {
4073
+ get() {
4074
+ return this._factoryMode ? "ctx" : "this";
4075
+ }
4076
+ });
4077
+ proto._pushEffect = function(body) {
4078
+ if (this._factoryMode) {
4079
+ this._setupLines.push(`disposers.push(__effect(() => { ${body} }));`);
4080
+ } else {
4081
+ this._setupLines.push(`__effect(() => { ${body} });`);
4082
+ }
4087
4083
  };
4088
4084
  proto.generateNode = function(sexpr) {
4089
4085
  if (typeof sexpr === "string" || sexpr instanceof String) {
@@ -4096,7 +4092,7 @@ ${blockFactoriesCode}return ${lines.join(`
4096
4092
  if (this.reactiveMembers && this.reactiveMembers.has(str)) {
4097
4093
  const textVar2 = this.newTextVar();
4098
4094
  this._createLines.push(`${textVar2} = document.createTextNode('');`);
4099
- this._setupLines.push(`__effect(() => { ${textVar2}.data = this.${str}.value; });`);
4095
+ this._pushEffect(`${textVar2}.data = ${this._self}.${str}.value;`);
4100
4096
  return textVar2;
4101
4097
  }
4102
4098
  const [tagStr, idStr] = str.split("#");
@@ -4128,14 +4124,15 @@ ${blockFactoriesCode}return ${lines.join(`
4128
4124
  if (headStr === ".") {
4129
4125
  const [, obj, prop] = sexpr;
4130
4126
  if (obj === "this" && typeof prop === "string") {
4127
+ const s = this._self;
4131
4128
  if (this.reactiveMembers && this.reactiveMembers.has(prop)) {
4132
4129
  const textVar3 = this.newTextVar();
4133
4130
  this._createLines.push(`${textVar3} = document.createTextNode('');`);
4134
- this._setupLines.push(`__effect(() => { ${textVar3}.data = this.${prop}.value; });`);
4131
+ this._pushEffect(`${textVar3}.data = ${s}.${prop}.value;`);
4135
4132
  return textVar3;
4136
4133
  }
4137
4134
  const slotVar = this.newElementVar("slot");
4138
- this._createLines.push(`${slotVar} = this.${prop} instanceof Node ? this.${prop} : (this.${prop} != null ? document.createTextNode(String(this.${prop})) : document.createComment(''));`);
4135
+ this._createLines.push(`${slotVar} = ${s}.${prop} instanceof Node ? ${s}.${prop} : (${s}.${prop} != null ? document.createTextNode(String(${s}.${prop})) : document.createComment(''));`);
4139
4136
  return slotVar;
4140
4137
  }
4141
4138
  const { tag, classes, id } = this.collectTemplateClasses(sexpr);
@@ -4174,7 +4171,7 @@ ${blockFactoriesCode}return ${lines.join(`
4174
4171
  const exprCode = this.generateInComponent(sexpr, "value");
4175
4172
  if (this.hasReactiveDeps(sexpr)) {
4176
4173
  this._createLines.push(`${textVar} = document.createTextNode('');`);
4177
- this._setupLines.push(`__effect(() => { ${textVar}.data = ${exprCode}; });`);
4174
+ this._pushEffect(`${textVar}.data = ${exprCode};`);
4178
4175
  } else {
4179
4176
  this._createLines.push(`${textVar} = document.createTextNode(String(${exprCode}));`);
4180
4177
  }
@@ -4200,19 +4197,25 @@ ${blockFactoriesCode}return ${lines.join(`
4200
4197
  } else if (this.is(arg, "object")) {
4201
4198
  this.generateAttributes(elVar, arg);
4202
4199
  } else if (typeof arg === "string" || arg instanceof String) {
4203
- const textVar = this.newTextVar();
4204
4200
  const val = arg.valueOf();
4205
- if (val.startsWith('"') || val.startsWith("'") || val.startsWith("`")) {
4206
- this._createLines.push(`${textVar} = document.createTextNode(${val});`);
4207
- } else if (this.reactiveMembers && this.reactiveMembers.has(val)) {
4208
- this._createLines.push(`${textVar} = document.createTextNode('');`);
4209
- this._setupLines.push(`__effect(() => { ${textVar}.data = this.${val}.value; });`);
4210
- } else if (this.componentMembers && this.componentMembers.has(val)) {
4211
- this._createLines.push(`${textVar} = document.createTextNode(String(this.${val}));`);
4201
+ const [tagPart, idPart] = val.split("#");
4202
+ if (this.isHtmlTag(tagPart || "div") || this.isComponent(val)) {
4203
+ const childVar = this.generateNode(arg);
4204
+ this._createLines.push(`${elVar}.appendChild(${childVar});`);
4212
4205
  } else {
4213
- this._createLines.push(`${textVar} = document.createTextNode(${this.generateInComponent(arg, "value")});`);
4206
+ const textVar = this.newTextVar();
4207
+ if (val.startsWith('"') || val.startsWith("'") || val.startsWith("`")) {
4208
+ this._createLines.push(`${textVar} = document.createTextNode(${val});`);
4209
+ } else if (this.reactiveMembers && this.reactiveMembers.has(val)) {
4210
+ this._createLines.push(`${textVar} = document.createTextNode('');`);
4211
+ this._pushEffect(`${textVar}.data = ${this._self}.${val}.value;`);
4212
+ } else if (this.componentMembers && this.componentMembers.has(val)) {
4213
+ this._createLines.push(`${textVar} = document.createTextNode(String(${this._self}.${val}));`);
4214
+ } else {
4215
+ this._createLines.push(`${textVar} = document.createTextNode(${this.generateInComponent(arg, "value")});`);
4216
+ }
4217
+ this._createLines.push(`${elVar}.appendChild(${textVar});`);
4214
4218
  }
4215
- this._createLines.push(`${elVar}.appendChild(${textVar});`);
4216
4219
  } else if (arg) {
4217
4220
  const childVar = this.generateNode(arg);
4218
4221
  this._createLines.push(`${elVar}.appendChild(${childVar});`);
@@ -4251,9 +4254,9 @@ ${blockFactoriesCode}return ${lines.join(`
4251
4254
  } else {
4252
4255
  const combined = this._pendingClassArgs.join(", ");
4253
4256
  if (isSvg) {
4254
- this._setupLines.push(`__effect(() => { ${elVar}.setAttribute('class', __clsx(${combined})); });`);
4257
+ this._pushEffect(`${elVar}.setAttribute('class', __clsx(${combined}));`);
4255
4258
  } else {
4256
- this._setupLines.push(`__effect(() => { ${elVar}.className = __clsx(${combined}); });`);
4259
+ this._pushEffect(`${elVar}.className = __clsx(${combined});`);
4257
4260
  }
4258
4261
  }
4259
4262
  this._pendingClassArgs = prevClassArgs;
@@ -4282,9 +4285,9 @@ ${blockFactoriesCode}return ${lines.join(`
4282
4285
  const combined = this._pendingClassArgs.join(", ");
4283
4286
  const isSvg = SVG_TAGS.has(tag) || this._svgDepth > 0;
4284
4287
  if (isSvg) {
4285
- this._setupLines.push(`__effect(() => { ${elVar}.setAttribute('class', __clsx(${combined})); });`);
4288
+ this._pushEffect(`${elVar}.setAttribute('class', __clsx(${combined}));`);
4286
4289
  } else {
4287
- this._setupLines.push(`__effect(() => { ${elVar}.className = __clsx(${combined}); });`);
4290
+ this._pushEffect(`${elVar}.className = __clsx(${combined});`);
4288
4291
  }
4289
4292
  }
4290
4293
  this._pendingClassArgs = prevClassArgs;
@@ -4298,7 +4301,7 @@ ${blockFactoriesCode}return ${lines.join(`
4298
4301
  if (this.is(key, ".") && key[1] === "this") {
4299
4302
  const eventName = key[2];
4300
4303
  if (typeof value === "string" && this.componentMembers?.has(value)) {
4301
- this._createLines.push(`${elVar}.addEventListener('${eventName}', (e) => __batch(() => this.${value}(e)));`);
4304
+ this._createLines.push(`${elVar}.addEventListener('${eventName}', (e) => __batch(() => ${this._self}.${value}(e)));`);
4302
4305
  } else {
4303
4306
  const handlerCode = this.generateInComponent(value, "value");
4304
4307
  this._createLines.push(`${elVar}.addEventListener('${eventName}', (e) => __batch(() => (${handlerCode})(e)));`);
@@ -4315,9 +4318,9 @@ ${blockFactoriesCode}return ${lines.join(`
4315
4318
  this._pendingClassArgs.push(valueCode2);
4316
4319
  } else if (this.hasReactiveDeps(value)) {
4317
4320
  if (this._svgDepth > 0) {
4318
- this._setupLines.push(`__effect(() => { ${elVar}.setAttribute('class', __clsx(${valueCode2})); });`);
4321
+ this._pushEffect(`${elVar}.setAttribute('class', __clsx(${valueCode2}));`);
4319
4322
  } else {
4320
- this._setupLines.push(`__effect(() => { ${elVar}.className = __clsx(${valueCode2}); });`);
4323
+ this._pushEffect(`${elVar}.className = __clsx(${valueCode2});`);
4321
4324
  }
4322
4325
  } else {
4323
4326
  if (this._svgDepth > 0) {
@@ -4328,9 +4331,14 @@ ${blockFactoriesCode}return ${lines.join(`
4328
4331
  }
4329
4332
  continue;
4330
4333
  }
4334
+ if (key === "__transition__") {
4335
+ const transName = String(value).replace(/^["']|["']$/g, "");
4336
+ this._createLines.push(`this._t = "${transName}";`);
4337
+ continue;
4338
+ }
4331
4339
  if (key === "ref") {
4332
4340
  const refName = String(value).replace(/^["']|["']$/g, "");
4333
- this._createLines.push(`this.${refName} = ${elVar};`);
4341
+ this._createLines.push(`${this._self}.${refName} = ${elVar};`);
4334
4342
  continue;
4335
4343
  }
4336
4344
  if (key.startsWith(BIND_PREFIX) && key.endsWith(BIND_SUFFIX)) {
@@ -4344,25 +4352,25 @@ ${blockFactoriesCode}return ${lines.join(`
4344
4352
  event = "input";
4345
4353
  valueAccessor = inputType === "number" || inputType === "range" ? "e.target.valueAsNumber" : "e.target.value";
4346
4354
  }
4347
- this._setupLines.push(`__effect(() => { ${elVar}.${prop} = ${valueCode2}; });`);
4355
+ this._pushEffect(`${elVar}.${prop} = ${valueCode2};`);
4348
4356
  let assignCode = `${valueCode2} = ${valueAccessor}`;
4349
4357
  const rootMember = !this.isSimpleAssignable(value) && this.findRootReactiveMember(value);
4350
4358
  if (rootMember) {
4351
- assignCode += `; this.${rootMember}.touch?.()`;
4359
+ assignCode += `; ${this._self}.${rootMember}.touch?.()`;
4352
4360
  }
4353
4361
  this._createLines.push(`${elVar}.addEventListener('${event}', (e) => { ${assignCode}; });`);
4354
4362
  continue;
4355
4363
  }
4356
4364
  const valueCode = this.generateInComponent(value, "value");
4357
4365
  if ((key === "value" || key === "checked") && this.hasReactiveDeps(value)) {
4358
- this._setupLines.push(`__effect(() => { ${elVar}.${key} = ${valueCode}; });`);
4366
+ this._pushEffect(`${elVar}.${key} = ${valueCode};`);
4359
4367
  const rootMemberImplicit = !this.isSimpleAssignable(value) && this.findRootReactiveMember(value);
4360
4368
  if (this.isSimpleAssignable(value) || rootMemberImplicit) {
4361
4369
  const event = key === "checked" ? "change" : "input";
4362
4370
  const accessor = key === "checked" ? "e.target.checked" : inputType === "number" || inputType === "range" ? "e.target.valueAsNumber" : "e.target.value";
4363
4371
  let assignCode = `${valueCode} = ${accessor}`;
4364
4372
  if (rootMemberImplicit) {
4365
- assignCode += `; this.${rootMemberImplicit}.touch?.()`;
4373
+ assignCode += `; ${this._self}.${rootMemberImplicit}.touch?.()`;
4366
4374
  }
4367
4375
  this._createLines.push(`${elVar}.addEventListener('${event}', (e) => { ${assignCode}; });`);
4368
4376
  }
@@ -4370,18 +4378,18 @@ ${blockFactoriesCode}return ${lines.join(`
4370
4378
  }
4371
4379
  if (key === "innerHTML" || key === "textContent" || key === "innerText") {
4372
4380
  if (this.hasReactiveDeps(value)) {
4373
- this._setupLines.push(`__effect(() => { ${elVar}.${key} = ${valueCode}; });`);
4381
+ this._pushEffect(`${elVar}.${key} = ${valueCode};`);
4374
4382
  } else {
4375
4383
  this._createLines.push(`${elVar}.${key} = ${valueCode};`);
4376
4384
  }
4377
4385
  } else if (BOOLEAN_ATTRS.has(key)) {
4378
4386
  if (this.hasReactiveDeps(value)) {
4379
- this._setupLines.push(`__effect(() => { ${elVar}.toggleAttribute('${key}', !!${valueCode}); });`);
4387
+ this._pushEffect(`${elVar}.toggleAttribute('${key}', !!${valueCode});`);
4380
4388
  } else {
4381
4389
  this._createLines.push(`if (${valueCode}) ${elVar}.setAttribute('${key}', '');`);
4382
4390
  }
4383
4391
  } else if (this.hasReactiveDeps(value)) {
4384
- this._setupLines.push(`__effect(() => { ${elVar}.setAttribute('${key}', ${valueCode}); });`);
4392
+ this._pushEffect(`${elVar}.setAttribute('${key}', ${valueCode});`);
4385
4393
  } else {
4386
4394
  this._createLines.push(`${elVar}.setAttribute('${key}', ${valueCode});`);
4387
4395
  }
@@ -4403,10 +4411,13 @@ ${blockFactoriesCode}return ${lines.join(`
4403
4411
  }
4404
4412
  const fragVar = this.newElementVar("frag");
4405
4413
  this._createLines.push(`${fragVar} = document.createDocumentFragment();`);
4414
+ const children = [];
4406
4415
  for (const stmt of statements) {
4407
4416
  const childVar = this.generateNode(stmt);
4408
4417
  this._createLines.push(`${fragVar}.appendChild(${childVar});`);
4418
+ children.push(childVar);
4409
4419
  }
4420
+ this._fragChildren.set(fragVar, children);
4410
4421
  return fragVar;
4411
4422
  };
4412
4423
  proto.generateConditional = function(sexpr) {
@@ -4414,8 +4425,8 @@ ${blockFactoriesCode}return ${lines.join(`
4414
4425
  const anchorVar = this.newElementVar("anchor");
4415
4426
  this._createLines.push(`${anchorVar} = document.createComment('if');`);
4416
4427
  const condCode = this.generateInComponent(condition, "value");
4417
- const loopParams = this._loopVarStack.map((v) => `${v.itemVar}, ${v.indexVar}`).join(", ");
4418
- const extraArgs = loopParams ? `, ${loopParams}` : "";
4428
+ const outerParams = this._loopVarStack.map((v) => `${v.itemVar}, ${v.indexVar}`).join(", ");
4429
+ const outerExtra = outerParams ? `, ${outerParams}` : "";
4419
4430
  const thenBlockName = this.newBlockVar();
4420
4431
  this.generateConditionBranch(thenBlockName, thenBlock);
4421
4432
  let elseBlockName = null;
@@ -4429,82 +4440,95 @@ ${blockFactoriesCode}return ${lines.join(`
4429
4440
  setupLines.push(` const anchor = ${anchorVar};`);
4430
4441
  setupLines.push(` let currentBlock = null;`);
4431
4442
  setupLines.push(` let showing = null;`);
4432
- setupLines.push(` __effect(() => {`);
4443
+ const effOpen = this._factoryMode ? "disposers.push(__effect(() => {" : "__effect(() => {";
4444
+ const effClose = this._factoryMode ? "}));" : "});";
4445
+ setupLines.push(` ${effOpen}`);
4433
4446
  setupLines.push(` const show = !!(${condCode});`);
4434
4447
  setupLines.push(` const want = show ? 'then' : ${elseBlock ? "'else'" : "null"};`);
4435
4448
  setupLines.push(` if (want === showing) return;`);
4436
4449
  setupLines.push(``);
4437
4450
  setupLines.push(` if (currentBlock) {`);
4438
- setupLines.push(` currentBlock.d(true);`);
4451
+ setupLines.push(` const leaving = currentBlock;`);
4452
+ setupLines.push(` if (leaving._t) { __transition(leaving._first, leaving._t, 'leave', () => leaving.d(true)); }`);
4453
+ setupLines.push(` else { leaving.d(true); }`);
4439
4454
  setupLines.push(` currentBlock = null;`);
4440
4455
  setupLines.push(` }`);
4441
4456
  setupLines.push(` showing = want;`);
4442
4457
  setupLines.push(``);
4443
4458
  setupLines.push(` if (want === 'then') {`);
4444
- setupLines.push(` currentBlock = ${thenBlockName}(this${extraArgs});`);
4459
+ setupLines.push(` currentBlock = ${thenBlockName}(${this._self}${outerExtra});`);
4445
4460
  setupLines.push(` currentBlock.c();`);
4446
4461
  setupLines.push(` if (anchor.parentNode) currentBlock.m(anchor.parentNode, anchor.nextSibling);`);
4447
- setupLines.push(` currentBlock.p(this${extraArgs});`);
4462
+ setupLines.push(` currentBlock.p(${this._self}${outerExtra});`);
4463
+ setupLines.push(` if (currentBlock._t) __transition(currentBlock._first, currentBlock._t, 'enter');`);
4448
4464
  setupLines.push(` }`);
4449
4465
  if (elseBlock) {
4450
4466
  setupLines.push(` if (want === 'else') {`);
4451
- setupLines.push(` currentBlock = ${elseBlockName}(this${extraArgs});`);
4467
+ setupLines.push(` currentBlock = ${elseBlockName}(${this._self}${outerExtra});`);
4452
4468
  setupLines.push(` currentBlock.c();`);
4453
4469
  setupLines.push(` if (anchor.parentNode) currentBlock.m(anchor.parentNode, anchor.nextSibling);`);
4454
- setupLines.push(` currentBlock.p(this${extraArgs});`);
4470
+ setupLines.push(` currentBlock.p(${this._self}${outerExtra});`);
4471
+ setupLines.push(` if (currentBlock._t) __transition(currentBlock._first, currentBlock._t, 'enter');`);
4455
4472
  setupLines.push(` }`);
4456
4473
  }
4457
- setupLines.push(` });`);
4474
+ setupLines.push(` ${effClose}`);
4458
4475
  setupLines.push(`}`);
4459
4476
  this._setupLines.push(setupLines.join(`
4460
4477
  `));
4461
4478
  return anchorVar;
4462
4479
  };
4463
4480
  proto.generateConditionBranch = function(blockName, block) {
4464
- const savedCreateLines = this._createLines;
4465
- const savedSetupLines = this._setupLines;
4481
+ const saved = [this._createLines, this._setupLines, this._factoryMode, this._factoryVars];
4466
4482
  this._createLines = [];
4467
4483
  this._setupLines = [];
4484
+ this._factoryMode = true;
4485
+ this._factoryVars = new Set;
4468
4486
  const rootVar = this.generateTemplateBlock(block);
4469
4487
  const createLines = this._createLines;
4470
4488
  const setupLines = this._setupLines;
4471
- this._createLines = savedCreateLines;
4472
- this._setupLines = savedSetupLines;
4473
- const localizeVar = (line) => this.localizeVar(line);
4474
- const loopParams = this._loopVarStack.map((v) => `${v.itemVar}, ${v.indexVar}`).join(", ");
4475
- const extraParams = loopParams ? `, ${loopParams}` : "";
4489
+ const factoryVars = this._factoryVars;
4490
+ [this._createLines, this._setupLines, this._factoryMode, this._factoryVars] = saved;
4491
+ const outerParams = this._loopVarStack.map((v) => `${v.itemVar}, ${v.indexVar}`).join(", ");
4492
+ const extraParams = outerParams ? `, ${outerParams}` : "";
4493
+ this.emitBlockFactory(blockName, `ctx${extraParams}`, rootVar, createLines, setupLines, factoryVars);
4494
+ };
4495
+ proto.emitBlockFactory = function(blockName, params, rootVar, createLines, setupLines, factoryVars, isStatic) {
4476
4496
  const factoryLines = [];
4477
- factoryLines.push(`function ${blockName}(ctx${extraParams}) {`);
4478
- const localVars = new Set;
4479
- for (const line of createLines) {
4480
- const match = line.match(/^this\.(_(?:el|t|anchor|frag|slot|c|inst|empty)\d+)\s*=/);
4481
- if (match)
4482
- localVars.add(match[1]);
4483
- }
4484
- if (localVars.size > 0) {
4485
- factoryLines.push(` let ${[...localVars].join(", ")};`);
4497
+ factoryLines.push(`function ${blockName}(${params}) {`);
4498
+ if (factoryVars.size > 0) {
4499
+ factoryLines.push(` let ${[...factoryVars].join(", ")};`);
4486
4500
  }
4487
4501
  const hasEffects = setupLines.length > 0;
4488
4502
  if (hasEffects) {
4489
4503
  factoryLines.push(` let disposers = [];`);
4490
4504
  }
4491
4505
  factoryLines.push(` return {`);
4506
+ if (isStatic) {
4507
+ factoryLines.push(` _s: true,`);
4508
+ }
4509
+ const fragChildren = this._fragChildren.get(rootVar);
4510
+ const firstNode = fragChildren ? fragChildren[0] : rootVar;
4492
4511
  factoryLines.push(` c() {`);
4493
4512
  for (const line of createLines) {
4494
- factoryLines.push(` ${localizeVar(line)}`);
4513
+ factoryLines.push(` ${line}`);
4495
4514
  }
4515
+ factoryLines.push(` this._first = ${firstNode};`);
4496
4516
  factoryLines.push(` },`);
4497
4517
  factoryLines.push(` m(target, anchor) {`);
4498
- factoryLines.push(` target.insertBefore(${localizeVar(rootVar)}, anchor);`);
4518
+ if (fragChildren) {
4519
+ for (const child of fragChildren) {
4520
+ factoryLines.push(` if (target) target.insertBefore(${child}, anchor);`);
4521
+ }
4522
+ } else {
4523
+ factoryLines.push(` if (target) target.insertBefore(${rootVar}, anchor);`);
4524
+ }
4499
4525
  factoryLines.push(` },`);
4500
- factoryLines.push(` p(ctx${extraParams}) {`);
4526
+ factoryLines.push(` p(${params}) {`);
4501
4527
  if (hasEffects) {
4502
4528
  factoryLines.push(` disposers.forEach(d => d());`);
4503
4529
  factoryLines.push(` disposers = [];`);
4504
4530
  for (const line of setupLines) {
4505
- const localizedLine = localizeVar(line);
4506
- const wrappedLine = localizedLine.replace(/__effect\(\(\) => \{/g, "disposers.push(__effect(() => {").replace(/\}\);$/gm, "}));");
4507
- factoryLines.push(` ${wrappedLine}`);
4531
+ factoryLines.push(` ${line}`);
4508
4532
  }
4509
4533
  }
4510
4534
  factoryLines.push(` },`);
@@ -4512,13 +4536,12 @@ ${blockFactoriesCode}return ${lines.join(`
4512
4536
  if (hasEffects) {
4513
4537
  factoryLines.push(` disposers.forEach(d => d());`);
4514
4538
  }
4515
- const condFragChildren = getFragChildren(rootVar, createLines, localizeVar);
4516
- if (condFragChildren) {
4517
- for (const child of condFragChildren) {
4539
+ if (fragChildren) {
4540
+ for (const child of fragChildren) {
4518
4541
  factoryLines.push(` if (detaching && ${child}) ${child}.remove();`);
4519
4542
  }
4520
4543
  } else {
4521
- factoryLines.push(` if (detaching && ${localizeVar(rootVar)}) ${localizeVar(rootVar)}.remove();`);
4544
+ factoryLines.push(` if (detaching && ${rootVar}) ${rootVar}.remove();`);
4522
4545
  }
4523
4546
  factoryLines.push(` }`);
4524
4547
  factoryLines.push(` };`);
@@ -4554,108 +4577,35 @@ ${blockFactoriesCode}return ${lines.join(`
4554
4577
  }
4555
4578
  }
4556
4579
  }
4557
- const savedCreateLines = this._createLines;
4558
- const savedSetupLines = this._setupLines;
4580
+ const saved = [this._createLines, this._setupLines, this._factoryMode, this._factoryVars];
4559
4581
  this._createLines = [];
4560
4582
  this._setupLines = [];
4561
- const outerLoopParams = this._loopVarStack.map((v) => `${v.itemVar}, ${v.indexVar}`).join(", ");
4562
- const outerExtra = outerLoopParams ? `, ${outerLoopParams}` : "";
4583
+ this._factoryMode = true;
4584
+ this._factoryVars = new Set;
4585
+ const outerParams = this._loopVarStack.map((v) => `${v.itemVar}, ${v.indexVar}`).join(", ");
4586
+ const outerExtra = outerParams ? `, ${outerParams}` : "";
4563
4587
  this._loopVarStack.push({ itemVar, indexVar });
4564
4588
  const itemNode = this.generateTemplateBlock(body);
4565
4589
  this._loopVarStack.pop();
4566
4590
  const itemCreateLines = this._createLines;
4567
4591
  const itemSetupLines = this._setupLines;
4568
- this._createLines = savedCreateLines;
4569
- this._setupLines = savedSetupLines;
4570
- const localizeVar = (line) => this.localizeVar(line);
4571
- const factoryLines = [];
4572
- factoryLines.push(`function ${blockName}(ctx, ${itemVar}, ${indexVar}${outerExtra}) {`);
4573
- const localVars = new Set;
4574
- for (const line of itemCreateLines) {
4575
- const match = line.match(/^this\.(_(?:el|t|anchor|frag|slot|c|inst|empty)\d+)\s*=/);
4576
- if (match)
4577
- localVars.add(match[1]);
4578
- }
4579
- if (localVars.size > 0) {
4580
- factoryLines.push(` let ${[...localVars].join(", ")};`);
4581
- }
4582
- const hasEffects = itemSetupLines.length > 0;
4583
- if (hasEffects) {
4584
- factoryLines.push(` let disposers = [];`);
4585
- }
4586
- factoryLines.push(` return {`);
4587
- factoryLines.push(` c() {`);
4588
- for (const line of itemCreateLines) {
4589
- factoryLines.push(` ${localizeVar(line)}`);
4590
- }
4591
- factoryLines.push(` },`);
4592
- const loopFragChildren = getFragChildren(itemNode, itemCreateLines, localizeVar);
4593
- factoryLines.push(` m(target, anchor) {`);
4594
- if (loopFragChildren) {
4595
- for (const child of loopFragChildren) {
4596
- factoryLines.push(` if (target) target.insertBefore(${child}, anchor);`);
4597
- }
4598
- } else {
4599
- factoryLines.push(` if (target) target.insertBefore(${localizeVar(itemNode)}, anchor);`);
4600
- }
4601
- factoryLines.push(` },`);
4602
- factoryLines.push(` p(ctx, ${itemVar}, ${indexVar}${outerExtra}) {`);
4603
- if (hasEffects) {
4604
- factoryLines.push(` disposers.forEach(d => d());`);
4605
- factoryLines.push(` disposers = [];`);
4606
- for (const line of itemSetupLines) {
4607
- const localizedLine = localizeVar(line);
4608
- const wrappedLine = localizedLine.replace(/__effect\(\(\) => \{/g, "disposers.push(__effect(() => {").replace(/\}\);$/gm, "}));");
4609
- factoryLines.push(` ${wrappedLine}`);
4610
- }
4611
- }
4612
- factoryLines.push(` },`);
4613
- factoryLines.push(` d(detaching) {`);
4614
- if (hasEffects) {
4615
- factoryLines.push(` disposers.forEach(d => d());`);
4616
- }
4617
- if (loopFragChildren) {
4618
- for (const child of loopFragChildren) {
4619
- factoryLines.push(` if (detaching && ${child}) ${child}.remove();`);
4620
- }
4621
- } else {
4622
- factoryLines.push(` if (detaching && ${localizeVar(itemNode)}) ${localizeVar(itemNode)}.remove();`);
4623
- }
4624
- factoryLines.push(` }`);
4625
- factoryLines.push(` };`);
4626
- factoryLines.push(`}`);
4627
- this._blockFactories.push(factoryLines.join(`
4628
- `));
4592
+ const itemFactoryVars = this._factoryVars;
4593
+ [this._createLines, this._setupLines, this._factoryMode, this._factoryVars] = saved;
4594
+ const isStatic = itemSetupLines.length === 0;
4595
+ const loopParams = `ctx, ${itemVar}, ${indexVar}${outerExtra}`;
4596
+ this.emitBlockFactory(blockName, loopParams, itemNode, itemCreateLines, itemSetupLines, itemFactoryVars, isStatic);
4597
+ const hasCustomKey = keyExpr !== itemVar;
4598
+ const keyFnCode = hasCustomKey ? `(${itemVar}, ${indexVar}) => ${keyExpr}` : "null";
4599
+ const outerArgs = outerParams ? `, ${outerParams}` : "";
4629
4600
  const setupLines = [];
4630
4601
  setupLines.push(`// Loop: ${blockName}`);
4631
4602
  setupLines.push(`{`);
4632
- setupLines.push(` const __anchor = ${anchorVar};`);
4633
- setupLines.push(` const __map = new Map();`);
4634
- setupLines.push(` __effect(() => {`);
4635
- setupLines.push(` const __items = ${collectionCode};`);
4636
- setupLines.push(` const __parent = __anchor.parentNode;`);
4637
- setupLines.push(` const __newMap = new Map();`);
4638
- setupLines.push(``);
4639
- setupLines.push(` for (let ${indexVar} = 0; ${indexVar} < __items.length; ${indexVar}++) {`);
4640
- setupLines.push(` const ${itemVar} = __items[${indexVar}];`);
4641
- setupLines.push(` const __key = ${keyExpr};`);
4642
- setupLines.push(` let __block = __map.get(__key);`);
4643
- setupLines.push(` if (!__block) {`);
4644
- setupLines.push(` __block = ${blockName}(this, ${itemVar}, ${indexVar}${outerExtra});`);
4645
- setupLines.push(` __block.c();`);
4646
- setupLines.push(` }`);
4647
- setupLines.push(` __block.m(__parent, __anchor);`);
4648
- setupLines.push(` __block.p(this, ${itemVar}, ${indexVar}${outerExtra});`);
4649
- setupLines.push(` __newMap.set(__key, __block);`);
4650
- setupLines.push(` }`);
4651
- setupLines.push(``);
4652
- setupLines.push(` for (const [__k, __b] of __map) {`);
4653
- setupLines.push(` if (!__newMap.has(__k)) __b.d(true);`);
4654
- setupLines.push(` }`);
4655
- setupLines.push(``);
4656
- setupLines.push(` __map.clear();`);
4657
- setupLines.push(` for (const [__k, __v] of __newMap) __map.set(__k, __v);`);
4658
- setupLines.push(` });`);
4603
+ setupLines.push(` const __s = { blocks: [], keys: [] };`);
4604
+ const effOpen = this._factoryMode ? "disposers.push(__effect(() => {" : "__effect(() => {";
4605
+ const effClose = this._factoryMode ? "}));" : "});";
4606
+ setupLines.push(` ${effOpen}`);
4607
+ setupLines.push(` __reconcile(${anchorVar}, __s, ${collectionCode}, ${this._self}, ${blockName}, ${keyFnCode}${outerArgs});`);
4608
+ setupLines.push(` ${effClose}`);
4659
4609
  setupLines.push(`}`);
4660
4610
  this._setupLines.push(setupLines.join(`
4661
4611
  `));
@@ -4665,13 +4615,13 @@ ${blockFactoriesCode}return ${lines.join(`
4665
4615
  const instVar = this.newElementVar("inst");
4666
4616
  const elVar = this.newElementVar("el");
4667
4617
  const { propsCode, reactiveProps, childrenSetupLines } = this.buildComponentProps(args);
4618
+ const s = this._self;
4668
4619
  this._createLines.push(`${instVar} = new ${componentName}(${propsCode});`);
4669
4620
  this._createLines.push(`${elVar} = ${instVar}._create();`);
4670
- this._createLines.push(`(this._children || (this._children = [])).push(${instVar});`);
4671
- this._setupLines.push(`if (${instVar}._setup) ${instVar}._setup();`);
4672
- this._setupLines.push(`if (${instVar}.mounted) ${instVar}.mounted();`);
4621
+ this._createLines.push(`(${s}._children || (${s}._children = [])).push(${instVar});`);
4622
+ this._setupLines.push(`try { if (${instVar}._setup) ${instVar}._setup(); if (${instVar}.mounted) ${instVar}.mounted(); } catch (__e) { __handleComponentError(__e, ${instVar}); }`);
4673
4623
  for (const { key, valueCode } of reactiveProps) {
4674
- this._setupLines.push(`__effect(() => { if (${instVar}.${key}) ${instVar}.${key}.value = ${valueCode}; });`);
4624
+ this._pushEffect(`if (${instVar}.${key}) ${instVar}.${key}.value = ${valueCode};`);
4675
4625
  }
4676
4626
  for (const line of childrenSetupLines) {
4677
4627
  this._setupLines.push(line);
@@ -4683,24 +4633,29 @@ ${blockFactoriesCode}return ${lines.join(`
4683
4633
  const reactiveProps = [];
4684
4634
  let childrenVar = null;
4685
4635
  const childrenSetupLines = [];
4636
+ const addProp = (key, value) => {
4637
+ const isDirectSignal = this.reactiveMembers && (typeof value === "string" && this.reactiveMembers.has(value) || Array.isArray(value) && value[0] === "." && value[1] === "this" && typeof value[2] === "string" && this.reactiveMembers.has(value[2]));
4638
+ if (isDirectSignal) {
4639
+ const member = typeof value === "string" ? value : value[2];
4640
+ props.push(`${key}: ${this._self}.${member}`);
4641
+ } else {
4642
+ const valueCode = this.generateInComponent(value, "value");
4643
+ props.push(`${key}: ${valueCode}`);
4644
+ if (this.hasReactiveDeps(value)) {
4645
+ reactiveProps.push({ key, valueCode });
4646
+ }
4647
+ }
4648
+ };
4649
+ const addObjectProps = (objExpr) => {
4650
+ for (let i = 1;i < objExpr.length; i++) {
4651
+ const [key, value] = objExpr[i];
4652
+ if (typeof key === "string")
4653
+ addProp(key, value);
4654
+ }
4655
+ };
4686
4656
  for (const arg of args) {
4687
4657
  if (this.is(arg, "object")) {
4688
- for (let i = 1;i < arg.length; i++) {
4689
- const [key, value] = arg[i];
4690
- if (typeof key === "string") {
4691
- const isSimpleReactive = this.reactiveMembers && (typeof value === "string" && this.reactiveMembers.has(value) || Array.isArray(value) && value[0] === "." && value[1] === "this" && typeof value[2] === "string" && this.reactiveMembers.has(value[2]));
4692
- if (isSimpleReactive) {
4693
- const member = typeof value === "string" ? value : value[2];
4694
- props.push(`${key}: this.${member}`);
4695
- } else {
4696
- const valueCode = this.generateInComponent(value, "value");
4697
- props.push(`${key}: ${valueCode}`);
4698
- if (this.hasReactiveDeps(value)) {
4699
- reactiveProps.push({ key, valueCode });
4700
- }
4701
- }
4702
- }
4703
- }
4658
+ addObjectProps(arg);
4704
4659
  } else if (Array.isArray(arg) && (arg[0] === "->" || arg[0] === "=>")) {
4705
4660
  let block = arg[2];
4706
4661
  if (block) {
@@ -4708,22 +4663,7 @@ ${blockFactoriesCode}return ${lines.join(`
4708
4663
  const domChildren = [];
4709
4664
  for (const child of block.slice(1)) {
4710
4665
  if (this.is(child, "object")) {
4711
- for (let i = 1;i < child.length; i++) {
4712
- const [key, value] = child[i];
4713
- if (typeof key === "string") {
4714
- const isSimpleReactive = this.reactiveMembers && (typeof value === "string" && this.reactiveMembers.has(value) || Array.isArray(value) && value[0] === "." && value[1] === "this" && typeof value[2] === "string" && this.reactiveMembers.has(value[2]));
4715
- if (isSimpleReactive) {
4716
- const member = typeof value === "string" ? value : value[2];
4717
- props.push(`${key}: this.${member}`);
4718
- } else {
4719
- const valueCode = this.generateInComponent(value, "value");
4720
- props.push(`${key}: ${valueCode}`);
4721
- if (this.hasReactiveDeps(value)) {
4722
- reactiveProps.push({ key, valueCode });
4723
- }
4724
- }
4725
- }
4726
- }
4666
+ addObjectProps(child);
4727
4667
  } else {
4728
4668
  domChildren.push(child);
4729
4669
  }
@@ -4847,21 +4787,203 @@ function __clsx(...args) {
4847
4787
  return args.filter(Boolean).join(' ');
4848
4788
  }
4849
4789
 
4790
+ function __lis(arr) {
4791
+ const n = arr.length;
4792
+ if (n === 0) return [];
4793
+ const tails = [], indices = [], prev = new Array(n).fill(-1);
4794
+ for (let i = 0; i < n; i++) {
4795
+ if (arr[i] === -1) continue;
4796
+ let lo = 0, hi = tails.length;
4797
+ while (lo < hi) {
4798
+ const mid = (lo + hi) >> 1;
4799
+ if (tails[mid] < arr[i]) lo = mid + 1; else hi = mid;
4800
+ }
4801
+ tails[lo] = arr[i];
4802
+ indices[lo] = i;
4803
+ if (lo > 0) prev[i] = indices[lo - 1];
4804
+ }
4805
+ const result = [];
4806
+ let k = indices[tails.length - 1];
4807
+ for (let i = tails.length - 1; i >= 0; i--) { result.push(k); k = prev[k]; }
4808
+ result.reverse();
4809
+ return result;
4810
+ }
4811
+
4812
+ function __reconcile(anchor, state, items, ctx, factory, keyFn, ...outer) {
4813
+ const parent = anchor.parentNode;
4814
+ if (!parent) return;
4815
+
4816
+ const oldKeys = state.keys;
4817
+ const oldBlocks = state.blocks;
4818
+ const oldLen = oldKeys.length;
4819
+ const newLen = items.length;
4820
+ const newBlocks = new Array(newLen);
4821
+ const hasKeyFn = keyFn != null;
4822
+ const newKeys = hasKeyFn ? items.map((item, i) => keyFn(item, i)) : items;
4823
+
4824
+ // Phase 0: first render — batch create via DocumentFragment
4825
+ if (oldLen === 0) {
4826
+ if (newLen > 0) {
4827
+ const frag = document.createDocumentFragment();
4828
+ for (let i = 0; i < newLen; i++) {
4829
+ const block = factory(ctx, items[i], i, ...outer);
4830
+ block.c();
4831
+ block.m(frag, null);
4832
+ if (!block._s) block.p(ctx, items[i], i, ...outer);
4833
+ newBlocks[i] = block;
4834
+ }
4835
+ parent.insertBefore(frag, anchor);
4836
+ }
4837
+ state.keys = hasKeyFn ? newKeys : items.slice();
4838
+ state.blocks = newBlocks;
4839
+ return;
4840
+ }
4841
+
4842
+ // Phase 1: prefix scan — skip p() (item+index identical, effects already live)
4843
+ let start = 0;
4844
+ const minLen = oldLen < newLen ? oldLen : newLen;
4845
+ while (start < minLen && oldKeys[start] === newKeys[start]) {
4846
+ newBlocks[start] = oldBlocks[start];
4847
+ start++;
4848
+ }
4849
+
4850
+ // Phase 2: suffix scan — call p() (index may differ)
4851
+ let oldEnd = oldLen - 1;
4852
+ let newEnd = newLen - 1;
4853
+ while (oldEnd >= start && newEnd >= start && oldKeys[oldEnd] === newKeys[newEnd]) {
4854
+ const block = oldBlocks[oldEnd];
4855
+ if (!block._s) block.p(ctx, items[newEnd], newEnd, ...outer);
4856
+ newBlocks[newEnd] = block;
4857
+ oldEnd--;
4858
+ newEnd--;
4859
+ }
4860
+
4861
+ // Remove old blocks in the middle that aren't in the new set
4862
+ if (start > newEnd) {
4863
+ for (let i = start; i <= oldEnd; i++) oldBlocks[i].d(true);
4864
+ } else if (start > oldEnd) {
4865
+ // Phase 3a: pure insertion — batch via DocumentFragment
4866
+ const next = newEnd + 1 < newLen ? newBlocks[newEnd + 1]._first : anchor;
4867
+ const frag = document.createDocumentFragment();
4868
+ for (let i = start; i <= newEnd; i++) {
4869
+ const block = factory(ctx, items[i], i, ...outer);
4870
+ block.c();
4871
+ block.m(frag, null);
4872
+ if (!block._s) block.p(ctx, items[i], i, ...outer);
4873
+ newBlocks[i] = block;
4874
+ }
4875
+ parent.insertBefore(frag, next);
4876
+ } else {
4877
+ // Phase 4: general case — temp Map + LIS
4878
+ const oldKeyIdx = new Map();
4879
+ for (let i = start; i <= oldEnd; i++) oldKeyIdx.set(oldKeys[i], i);
4880
+
4881
+ const seq = new Array(newEnd - start + 1);
4882
+ for (let i = start; i <= newEnd; i++) {
4883
+ const key = newKeys[i];
4884
+ const oldIdx = oldKeyIdx.get(key);
4885
+ if (oldIdx !== undefined) {
4886
+ seq[i - start] = oldIdx - start;
4887
+ const block = oldBlocks[oldIdx];
4888
+ if (!block._s) block.p(ctx, items[i], i, ...outer);
4889
+ newBlocks[i] = block;
4890
+ oldKeyIdx.delete(key);
4891
+ } else {
4892
+ seq[i - start] = -1;
4893
+ const block = factory(ctx, items[i], i, ...outer);
4894
+ block.c();
4895
+ if (!block._s) block.p(ctx, items[i], i, ...outer);
4896
+ newBlocks[i] = block;
4897
+ }
4898
+ }
4899
+
4900
+ for (const idx of oldKeyIdx.values()) oldBlocks[idx].d(true);
4901
+
4902
+ const lis = __lis(seq);
4903
+ const lisSet = new Set(lis);
4904
+ let next = newEnd + 1 < newLen ? newBlocks[newEnd + 1]._first : anchor;
4905
+ for (let i = newEnd; i >= start; i--) {
4906
+ const block = newBlocks[i];
4907
+ if (!lisSet.has(i - start)) {
4908
+ block.m(parent, next);
4909
+ }
4910
+ next = block._first;
4911
+ }
4912
+ }
4913
+
4914
+ state.keys = hasKeyFn ? newKeys : items.slice();
4915
+ state.blocks = newBlocks;
4916
+ }
4917
+
4918
+ let __cssInjected = false;
4919
+ function __transitionCSS() {
4920
+ if (__cssInjected) return;
4921
+ __cssInjected = true;
4922
+ const s = document.createElement('style');
4923
+ s.textContent = [
4924
+ '.fade-enter-active,.fade-leave-active{transition:opacity .2s ease}',
4925
+ '.fade-enter-from,.fade-leave-to{opacity:0}',
4926
+ '.slide-enter-active,.slide-leave-active{transition:opacity .2s ease,transform .2s ease}',
4927
+ '.slide-enter-from{opacity:0;transform:translateY(-8px)}',
4928
+ '.slide-leave-to{opacity:0;transform:translateY(8px)}',
4929
+ '.scale-enter-active,.scale-leave-active{transition:opacity .2s ease,transform .2s ease}',
4930
+ '.scale-enter-from,.scale-leave-to{opacity:0;transform:scale(.95)}',
4931
+ '.blur-enter-active,.blur-leave-active{transition:opacity .2s ease,filter .2s ease}',
4932
+ '.blur-enter-from,.blur-leave-to{opacity:0;filter:blur(4px)}',
4933
+ '.fly-enter-active,.fly-leave-active{transition:opacity .2s ease,transform .2s ease}',
4934
+ '.fly-enter-from{opacity:0;transform:translateY(-20px)}',
4935
+ '.fly-leave-to{opacity:0;transform:translateY(20px)}',
4936
+ ].join('');
4937
+ document.head.appendChild(s);
4938
+ }
4939
+
4940
+ function __transition(el, name, dir, done) {
4941
+ __transitionCSS();
4942
+ const cl = el.classList;
4943
+ const from = name + '-' + dir + '-from';
4944
+ const active = name + '-' + dir + '-active';
4945
+ const to = name + '-' + dir + '-to';
4946
+ cl.add(from, active);
4947
+ requestAnimationFrame(() => {
4948
+ requestAnimationFrame(() => {
4949
+ cl.remove(from);
4950
+ cl.add(to);
4951
+ const end = () => { cl.remove(active, to); if (done) done(); };
4952
+ el.addEventListener('transitionend', end, { once: true });
4953
+ });
4954
+ });
4955
+ }
4956
+
4957
+ function __handleComponentError(error, component) {
4958
+ let current = component;
4959
+ while (current) {
4960
+ if (current.onError) {
4961
+ try { current.onError(error, component); return; } catch (_) {}
4962
+ }
4963
+ current = current._parent;
4964
+ }
4965
+ throw error;
4966
+ }
4967
+
4850
4968
  class __Component {
4851
4969
  constructor(props = {}) {
4852
4970
  Object.assign(this, props);
4853
4971
  const prev = __pushComponent(this);
4854
- this._init(props);
4972
+ try { this._init(props); } catch (e) { __popComponent(prev); __handleComponentError(e, this); return; }
4855
4973
  __popComponent(prev);
4856
4974
  }
4857
4975
  _init() {}
4858
4976
  mount(target) {
4859
4977
  if (typeof target === "string") target = document.querySelector(target);
4860
4978
  this._target = target;
4861
- this._root = this._create();
4862
- target.appendChild(this._root);
4863
- if (this._setup) this._setup();
4864
- if (this.mounted) this.mounted();
4979
+ try {
4980
+ this._root = this._create();
4981
+ target.appendChild(this._root);
4982
+ if (this._setup) this._setup();
4983
+ if (this.mounted) this.mounted();
4984
+ } catch (error) {
4985
+ __handleComponentError(error, this);
4986
+ }
4865
4987
  return this;
4866
4988
  }
4867
4989
  unmount() {
@@ -4882,7 +5004,7 @@ class __Component {
4882
5004
 
4883
5005
  // Register on globalThis for runtime deduplication
4884
5006
  if (typeof globalThis !== 'undefined') {
4885
- globalThis.__ripComponent = { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __Component };
5007
+ globalThis.__ripComponent = { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __Component };
4886
5008
  }
4887
5009
 
4888
5010
  `;
@@ -5671,10 +5793,10 @@ if (typeof globalThis !== 'undefined') {
5671
5793
  }
5672
5794
  if (this.usesTemplates && !skip) {
5673
5795
  if (skipRT) {
5674
- code += `var { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __Component } = globalThis.__ripComponent;
5796
+ code += `var { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __Component } = globalThis.__ripComponent;
5675
5797
  `;
5676
5798
  } else if (typeof globalThis !== "undefined" && globalThis.__ripComponent) {
5677
- code += `const { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __Component } = globalThis.__ripComponent;
5799
+ code += `const { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __Component } = globalThis.__ripComponent;
5678
5800
  `;
5679
5801
  } else {
5680
5802
  code += this.getComponentRuntime();
@@ -5899,13 +6021,36 @@ function _setDataSection() {
5899
6021
  let isIncl = index[0] === "..";
5900
6022
  let arrCode = this.generate(arr, "value");
5901
6023
  let [start, end] = index.slice(1);
6024
+ let numericLiteral = (node) => {
6025
+ if (node === null)
6026
+ return null;
6027
+ let v = str(node) ?? node;
6028
+ if (typeof v === "number")
6029
+ return v;
6030
+ if (typeof v === "string" && /^\d+$/.test(v))
6031
+ return +v;
6032
+ if (Array.isArray(node) && node[0] === "-" && node.length === 2) {
6033
+ let inner = str(node[1]) ?? node[1];
6034
+ if (typeof inner === "number")
6035
+ return -inner;
6036
+ if (typeof inner === "string" && /^\d+$/.test(inner))
6037
+ return -inner;
6038
+ }
6039
+ return null;
6040
+ };
6041
+ let inclEnd = (s2, e2, endNode) => {
6042
+ let n = numericLiteral(endNode);
6043
+ if (n !== null && n !== -1)
6044
+ return `${arrCode}.slice(${s2}, ${n + 1})`;
6045
+ return `${arrCode}.slice(${s2}, +${e2} + 1 || 9e9)`;
6046
+ };
5902
6047
  if (start === null && end === null)
5903
6048
  return `${arrCode}.slice()`;
5904
6049
  if (start === null) {
5905
6050
  if (isIncl && this.is(end, "-", 1) && (str(end[1]) ?? end[1]) == 1)
5906
6051
  return `${arrCode}.slice(0)`;
5907
6052
  let e2 = this.generate(end, "value");
5908
- return isIncl ? `${arrCode}.slice(0, +${e2} + 1 || 9e9)` : `${arrCode}.slice(0, ${e2})`;
6053
+ return isIncl ? inclEnd("0", e2, end) : `${arrCode}.slice(0, ${e2})`;
5909
6054
  }
5910
6055
  if (end === null)
5911
6056
  return `${arrCode}.slice(${this.generate(start, "value")})`;
@@ -5913,7 +6058,7 @@ function _setDataSection() {
5913
6058
  if (isIncl && this.is(end, "-", 1) && (str(end[1]) ?? end[1]) == 1)
5914
6059
  return `${arrCode}.slice(${s})`;
5915
6060
  let e = this.generate(end, "value");
5916
- return isIncl ? `${arrCode}.slice(${s}, +${e} + 1 || 9e9)` : `${arrCode}.slice(${s}, ${e})`;
6061
+ return isIncl ? inclEnd(s, e, end) : `${arrCode}.slice(${s}, ${e})`;
5917
6062
  }
5918
6063
  if (this.is(index, "-", 1)) {
5919
6064
  let n = str(index[1]) ?? index[1];
@@ -8374,8 +8519,8 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
8374
8519
  return new CodeGenerator({}).getComponentRuntime();
8375
8520
  }
8376
8521
  // src/browser.js
8377
- var VERSION = "3.13.23";
8378
- var BUILD_DATE = "2026-02-25@12:51:51GMT";
8522
+ var VERSION = "3.13.27";
8523
+ var BUILD_DATE = "2026-02-26@05:09:19GMT";
8379
8524
  if (typeof globalThis !== "undefined") {
8380
8525
  if (!globalThis.__rip)
8381
8526
  new Function(getReactiveRuntime())();
@@ -9450,7 +9595,7 @@ ${indented}`);
9450
9595
  mp.appendChild(wrapper);
9451
9596
  inst.mount(wrapper);
9452
9597
  layoutInstances.push(inst);
9453
- slot = wrapper.querySelector("#content") || wrapper;
9598
+ slot = wrapper.querySelector("slot") || wrapper;
9454
9599
  mp = slot;
9455
9600
  }
9456
9601
  currentLayouts = [...layoutFiles];