rip-lang 3.13.121 → 3.13.123

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/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.121-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.13.123-blue.svg" alt="Version"></a>
13
13
  <a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
14
14
  <a href="#"><img src="https://img.shields.io/badge/tests-1%2C436%2F1%2C436-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
@@ -482,6 +482,25 @@ bun run build # Build browser bundle
482
482
 
483
483
  ---
484
484
 
485
+ ## Release
486
+
487
+ ```bash
488
+ # rip-lang + changed @rip-lang/* packages + @rip-lang/all
489
+ bun run bump
490
+
491
+ # Explicit version level
492
+ bun run bump patch
493
+ bun run bump minor
494
+ bun run bump major
495
+ ```
496
+
497
+ - `bun run bump` is the standard release flow for the npm ecosystem in this repo.
498
+ - It bumps `rip-lang`, bumps any changed publishable `@rip-lang/*` packages, updates `@rip-lang/all`, runs the build and test steps, then commits, pushes, and publishes.
499
+ - `@rip-lang/all` is released automatically as part of that flow; there is no separate manual release step for it.
500
+ - `packages/vscode` is intentionally excluded and must be versioned and published separately.
501
+
502
+ ---
503
+
485
504
  ## Documentation
486
505
 
487
506
  | Guide | Description |
package/bin/rip CHANGED
@@ -21,6 +21,25 @@ const SUMMARY = packageJson.description;
21
21
 
22
22
  const isFile = (path) => existsSync(path) && statSync(path).isFile();
23
23
 
24
+ function getRepoRoot() {
25
+ try {
26
+ return execSync('git rev-parse --show-toplevel', {
27
+ encoding: 'utf-8',
28
+ stdio: ['pipe', 'pipe', 'pipe']
29
+ }).trim();
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+
35
+ function getWorkspaceServerPath() {
36
+ const repoRoot = getRepoRoot();
37
+ if (!repoRoot) return null;
38
+
39
+ const workspaceServerPath = join(repoRoot, 'packages', 'server', 'server.rip');
40
+ return isFile(workspaceServerPath) ? workspaceServerPath : null;
41
+ }
42
+
24
43
  function printHelp() {
25
44
  console.log(`
26
45
  Rip ${VERSION} - ${SUMMARY}
@@ -136,11 +155,14 @@ async function main() {
136
155
 
137
156
  if (args[0] === 'server') {
138
157
  let serverPath;
139
- try {
140
- serverPath = fileURLToPath(import.meta.resolve('@rip-lang/server/server'));
141
- } catch {
142
- console.error('Error: @rip-lang/server is not installed.\n\n bun add @rip-lang/server\n');
143
- process.exit(1);
158
+ serverPath = getWorkspaceServerPath();
159
+ if (!serverPath) {
160
+ try {
161
+ serverPath = fileURLToPath(import.meta.resolve('@rip-lang/server/server'));
162
+ } catch {
163
+ console.error('Error: @rip-lang/server is not installed.\n\n bun add @rip-lang/server\n');
164
+ process.exit(1);
165
+ }
144
166
  }
145
167
  const result = spawnSync('bun', ['--preload', loaderPath, serverPath, ...args.slice(1)], {
146
168
  stdio: 'inherit',
@@ -238,10 +260,8 @@ async function main() {
238
260
  // Allows `rip migrate --status` to find and run {repo}/bin/migrate
239
261
  if (inputFile && !inputFile.startsWith('-') && !isFile(inputFile)) {
240
262
  try {
241
- const repoRoot = execSync('git rev-parse --show-toplevel', {
242
- encoding: 'utf-8',
243
- stdio: ['pipe', 'pipe', 'pipe']
244
- }).trim();
263
+ const repoRoot = getRepoRoot();
264
+ if (!repoRoot) throw new Error('No git repo root');
245
265
  const binScript = join(repoRoot, 'bin', inputFile);
246
266
  if (existsSync(binScript)) {
247
267
  const r = spawnSync(binScript, scriptArgs, { stdio: 'inherit', env: process.env });
package/docs/dist/rip.js CHANGED
@@ -1039,9 +1039,30 @@
1039
1039
  if (usesRipIntrinsicProps) {
1040
1040
  preamble.push("type __RipElementMap = HTMLElementTagNameMap & Omit<SVGElementTagNameMap, keyof HTMLElementTagNameMap>;");
1041
1041
  preamble.push("type __RipTag = keyof __RipElementMap;");
1042
+ preamble.push("type __RipBrowserElement = Omit<HTMLElement, 'querySelector' | 'querySelectorAll' | 'closest' | 'setAttribute' | 'hidden'> & { hidden: boolean | 'until-found'; setAttribute(qualifiedName: string, value: any): void; querySelector(selectors: string): __RipBrowserElement | null; querySelectorAll(selectors: string): NodeListOf<__RipBrowserElement>; closest(selectors: string): __RipBrowserElement | null; };");
1043
+ preamble.push("type __RipDomEl<K extends __RipTag> = Omit<__RipElementMap[K], 'querySelector' | 'querySelectorAll' | 'closest' | 'setAttribute' | 'hidden'> & __RipBrowserElement;");
1042
1044
  preamble.push("type __RipAttrKeys<T> = { [K in keyof T]-?: K extends 'style' ? never : T[K] extends (...args: any[]) => any ? never : K }[keyof T] & string;");
1043
1045
  preamble.push("type __RipEvents = { [K in keyof HTMLElementEventMap as `@${K}`]?: ((event: HTMLElementEventMap[K]) => void) | null };");
1044
- preamble.push("type __RipProps<K extends __RipTag> = { [P in __RipAttrKeys<__RipElementMap[K]>]?: __RipElementMap[K][P] } & __RipEvents & { class?: string; style?: string; [k: `data-${string}`]: any; [k: `aria-${string}`]: any };");
1046
+ preamble.push("type __RipProps<K extends __RipTag> = { [P in __RipAttrKeys<__RipElementMap[K]>]?: __RipElementMap[K][P] } & __RipEvents & { ref?: string; class?: string; style?: string; [k: `data-${string}`]: any; [k: `aria-${string}`]: any };");
1047
+ }
1048
+ if (/\bARIA\./.test(source)) {
1049
+ preamble.push("type __RipAriaNavHandlers = { next?: () => void; prev?: () => void; first?: () => void; last?: () => void; select?: () => void; dismiss?: () => void; tab?: () => void; char?: () => void; };");
1050
+ preamble.push("declare const ARIA: {");
1051
+ preamble.push(" bindPopover(open: boolean, popover: () => Element | null | undefined, setOpen: (isOpen: boolean) => void, source?: (() => Element | null | undefined) | null): void;");
1052
+ preamble.push(" bindDialog(open: boolean, dialog: () => Element | null | undefined, setOpen: (isOpen: boolean) => void, dismissable?: boolean): void;");
1053
+ preamble.push(" popupDismiss(open: boolean, popup: () => Element | null | undefined, close: () => void, els?: Array<() => Element | null | undefined>, repos?: (() => void) | null): void;");
1054
+ preamble.push(" popupGuard(delay?: number): any;");
1055
+ preamble.push(" listNav(event: KeyboardEvent, handlers: __RipAriaNavHandlers): void;");
1056
+ preamble.push(" rovingNav(event: KeyboardEvent, handlers: __RipAriaNavHandlers, orientation?: 'vertical' | 'horizontal' | 'both'): void;");
1057
+ preamble.push(" positionBelow(trigger: Element | null | undefined, popup: Element | null | undefined, gap?: number, setVisible?: boolean): void;");
1058
+ preamble.push(" position(trigger: Element | null | undefined, floating: Element | null | undefined, opts?: any): void;");
1059
+ preamble.push(" trapFocus(panel: Element | null | undefined): void;");
1060
+ preamble.push(" wireAria(panel: Element, id: string): void;");
1061
+ preamble.push(" lockScroll(instance: any): void;");
1062
+ preamble.push(" unlockScroll(instance: any): void;");
1063
+ preamble.push(" hasAnchor: boolean;");
1064
+ preamble.push(" [key: string]: any;");
1065
+ preamble.push("};");
1045
1066
  }
1046
1067
  if (usesSignal) {
1047
1068
  preamble.push("interface Signal<T> { value: T; read(): T; lock(): Signal<T>; free(): Signal<T>; kill(): T; }");
@@ -1075,6 +1096,41 @@
1075
1096
  return false;
1076
1097
  let head = sexpr[0]?.valueOf?.() ?? sexpr[0];
1077
1098
  let usesIntrinsicProps = false;
1099
+ const refMembers = new Map;
1100
+ const isIntrinsicTag = (name2) => typeof name2 === "string" && /^[a-z]/.test(name2);
1101
+ const collectRefMembers = (node) => {
1102
+ if (!Array.isArray(node))
1103
+ return;
1104
+ let nodeHead = node[0]?.valueOf?.() ?? node[0];
1105
+ if (isIntrinsicTag(nodeHead)) {
1106
+ for (let i = 1;i < node.length; i++) {
1107
+ let child = node[i];
1108
+ if (!Array.isArray(child))
1109
+ continue;
1110
+ let childHead = child[0]?.valueOf?.() ?? child[0];
1111
+ if (childHead !== "object")
1112
+ continue;
1113
+ for (let j = 1;j < child.length; j++) {
1114
+ let entry = child[j];
1115
+ if (!Array.isArray(entry))
1116
+ continue;
1117
+ let key = entry[0]?.valueOf?.() ?? entry[0];
1118
+ if (key !== "ref")
1119
+ continue;
1120
+ let refName = entry[1]?.valueOf?.() ?? entry[1];
1121
+ if (typeof refName === "string")
1122
+ refName = refName.replace(/^["']|["']$/g, "");
1123
+ if (typeof refName === "string" && !refMembers.has(refName)) {
1124
+ refMembers.set(refName, `__RipDomEl<'${nodeHead}'> | null`);
1125
+ }
1126
+ }
1127
+ }
1128
+ }
1129
+ for (let i = 1;i < node.length; i++) {
1130
+ if (Array.isArray(node[i]))
1131
+ collectRefMembers(node[i]);
1132
+ }
1133
+ };
1078
1134
  let exported = false;
1079
1135
  let name = null;
1080
1136
  let compNode = null;
@@ -1165,6 +1221,10 @@
1165
1221
  bodyMembers.push(` ${methName}(${paramStrs.join(", ")}): void;`);
1166
1222
  }
1167
1223
  continue;
1224
+ } else if (mHead === "render") {
1225
+ usesIntrinsicProps = true;
1226
+ collectRefMembers(member[1]);
1227
+ continue;
1168
1228
  } else {
1169
1229
  continue;
1170
1230
  }
@@ -1191,6 +1251,9 @@
1191
1251
  lines.push(` constructor(props${propsOpt}: ${inheritedPropsType});`);
1192
1252
  }
1193
1253
  }
1254
+ for (let [refName, refType] of refMembers) {
1255
+ bodyMembers.push(` ${refName}: ${refType};`);
1256
+ }
1194
1257
  for (let m of bodyMembers)
1195
1258
  lines.push(m);
1196
1259
  lines.push(`}`);
@@ -3669,147 +3732,242 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3669
3732
  };
3670
3733
  var parser = /* @__PURE__ */ createParser();
3671
3734
  var parse = parser.parse.bind(parser);
3672
- // src/components.js
3673
- var HTML_TAGS = new Set([
3674
- "html",
3675
- "head",
3676
- "title",
3677
- "base",
3678
- "link",
3679
- "meta",
3680
- "style",
3681
- "body",
3735
+ // src/generated/dom-events.js
3736
+ var DOM_EVENT_NAMES = [
3737
+ "abort",
3738
+ "animationcancel",
3739
+ "animationend",
3740
+ "animationiteration",
3741
+ "animationstart",
3742
+ "auxclick",
3743
+ "beforeinput",
3744
+ "beforematch",
3745
+ "beforetoggle",
3746
+ "blur",
3747
+ "cancel",
3748
+ "canplay",
3749
+ "canplaythrough",
3750
+ "change",
3751
+ "click",
3752
+ "close",
3753
+ "compositionend",
3754
+ "compositionstart",
3755
+ "compositionupdate",
3756
+ "contextlost",
3757
+ "contextmenu",
3758
+ "contextrestored",
3759
+ "copy",
3760
+ "cuechange",
3761
+ "cut",
3762
+ "dblclick",
3763
+ "drag",
3764
+ "dragend",
3765
+ "dragenter",
3766
+ "dragleave",
3767
+ "dragover",
3768
+ "dragstart",
3769
+ "drop",
3770
+ "durationchange",
3771
+ "emptied",
3772
+ "ended",
3773
+ "error",
3774
+ "focus",
3775
+ "focusin",
3776
+ "focusout",
3777
+ "formdata",
3778
+ "fullscreenchange",
3779
+ "fullscreenerror",
3780
+ "gotpointercapture",
3781
+ "input",
3782
+ "invalid",
3783
+ "keydown",
3784
+ "keypress",
3785
+ "keyup",
3786
+ "load",
3787
+ "loadeddata",
3788
+ "loadedmetadata",
3789
+ "loadstart",
3790
+ "lostpointercapture",
3791
+ "mousedown",
3792
+ "mouseenter",
3793
+ "mouseleave",
3794
+ "mousemove",
3795
+ "mouseout",
3796
+ "mouseover",
3797
+ "mouseup",
3798
+ "paste",
3799
+ "pause",
3800
+ "play",
3801
+ "playing",
3802
+ "pointercancel",
3803
+ "pointerdown",
3804
+ "pointerenter",
3805
+ "pointerleave",
3806
+ "pointermove",
3807
+ "pointerout",
3808
+ "pointerover",
3809
+ "pointerrawupdate",
3810
+ "pointerup",
3811
+ "progress",
3812
+ "ratechange",
3813
+ "reset",
3814
+ "resize",
3815
+ "scroll",
3816
+ "scrollend",
3817
+ "securitypolicyviolation",
3818
+ "seeked",
3819
+ "seeking",
3820
+ "select",
3821
+ "selectionchange",
3822
+ "selectstart",
3823
+ "slotchange",
3824
+ "stalled",
3825
+ "submit",
3826
+ "suspend",
3827
+ "timeupdate",
3828
+ "toggle",
3829
+ "touchcancel",
3830
+ "touchend",
3831
+ "touchmove",
3832
+ "touchstart",
3833
+ "transitioncancel",
3834
+ "transitionend",
3835
+ "transitionrun",
3836
+ "transitionstart",
3837
+ "volumechange",
3838
+ "waiting",
3839
+ "webkitanimationend",
3840
+ "webkitanimationiteration",
3841
+ "webkitanimationstart",
3842
+ "webkittransitionend",
3843
+ "wheel"
3844
+ ];
3845
+ var DOM_EVENTS = new Set(DOM_EVENT_NAMES);
3846
+
3847
+ // src/generated/dom-tags.js
3848
+ var HTML_TAG_NAMES = [
3849
+ "a",
3850
+ "abbr",
3682
3851
  "address",
3852
+ "area",
3683
3853
  "article",
3684
3854
  "aside",
3685
- "footer",
3686
- "header",
3687
- "h1",
3688
- "h2",
3689
- "h3",
3690
- "h4",
3691
- "h5",
3692
- "h6",
3693
- "main",
3694
- "nav",
3695
- "section",
3696
- "blockquote",
3697
- "dd",
3698
- "div",
3699
- "dl",
3700
- "dt",
3701
- "figcaption",
3702
- "figure",
3703
- "hr",
3704
- "li",
3705
- "ol",
3706
- "p",
3707
- "pre",
3708
- "ul",
3709
- "a",
3710
- "abbr",
3855
+ "audio",
3711
3856
  "b",
3857
+ "base",
3712
3858
  "bdi",
3713
3859
  "bdo",
3860
+ "blockquote",
3861
+ "body",
3714
3862
  "br",
3863
+ "button",
3864
+ "canvas",
3865
+ "caption",
3715
3866
  "cite",
3716
3867
  "code",
3868
+ "col",
3869
+ "colgroup",
3717
3870
  "data",
3871
+ "datalist",
3872
+ "dd",
3873
+ "del",
3874
+ "details",
3718
3875
  "dfn",
3876
+ "dialog",
3877
+ "div",
3878
+ "dl",
3879
+ "dt",
3719
3880
  "em",
3881
+ "embed",
3882
+ "fieldset",
3883
+ "figcaption",
3884
+ "figure",
3885
+ "footer",
3886
+ "form",
3887
+ "h1",
3888
+ "h2",
3889
+ "h3",
3890
+ "h4",
3891
+ "h5",
3892
+ "h6",
3893
+ "head",
3894
+ "header",
3895
+ "hgroup",
3896
+ "hr",
3897
+ "html",
3720
3898
  "i",
3899
+ "iframe",
3900
+ "img",
3901
+ "input",
3902
+ "ins",
3721
3903
  "kbd",
3904
+ "label",
3905
+ "legend",
3906
+ "li",
3907
+ "link",
3908
+ "main",
3909
+ "map",
3722
3910
  "mark",
3911
+ "menu",
3912
+ "meta",
3913
+ "meter",
3914
+ "nav",
3915
+ "noscript",
3916
+ "object",
3917
+ "ol",
3918
+ "optgroup",
3919
+ "option",
3920
+ "output",
3921
+ "p",
3922
+ "picture",
3923
+ "pre",
3924
+ "progress",
3723
3925
  "q",
3724
3926
  "rp",
3725
3927
  "rt",
3726
3928
  "ruby",
3727
3929
  "s",
3728
3930
  "samp",
3931
+ "script",
3932
+ "search",
3933
+ "section",
3934
+ "select",
3935
+ "slot",
3729
3936
  "small",
3937
+ "source",
3730
3938
  "span",
3731
3939
  "strong",
3940
+ "style",
3732
3941
  "sub",
3942
+ "summary",
3733
3943
  "sup",
3734
- "time",
3735
- "u",
3736
- "var",
3737
- "wbr",
3738
- "area",
3739
- "audio",
3740
- "img",
3741
- "map",
3742
- "track",
3743
- "video",
3744
- "embed",
3745
- "iframe",
3746
- "object",
3747
- "param",
3748
- "picture",
3749
- "portal",
3750
- "source",
3751
- "svg",
3752
- "math",
3753
- "canvas",
3754
- "noscript",
3755
- "script",
3756
- "del",
3757
- "ins",
3758
- "caption",
3759
- "col",
3760
- "colgroup",
3761
3944
  "table",
3762
3945
  "tbody",
3763
3946
  "td",
3947
+ "template",
3948
+ "textarea",
3764
3949
  "tfoot",
3765
3950
  "th",
3766
3951
  "thead",
3952
+ "time",
3953
+ "title",
3767
3954
  "tr",
3768
- "button",
3769
- "datalist",
3770
- "fieldset",
3771
- "form",
3772
- "input",
3773
- "label",
3774
- "legend",
3775
- "meter",
3776
- "optgroup",
3777
- "option",
3778
- "output",
3779
- "progress",
3780
- "select",
3781
- "textarea",
3782
- "details",
3783
- "dialog",
3784
- "menu",
3785
- "summary",
3786
- "slot",
3787
- "template"
3788
- ]);
3789
- var SVG_TAGS = new Set([
3790
- "svg",
3791
- "g",
3792
- "defs",
3793
- "symbol",
3794
- "use",
3795
- "marker",
3796
- "clipPath",
3797
- "mask",
3798
- "pattern",
3955
+ "track",
3956
+ "u",
3957
+ "ul",
3958
+ "var",
3959
+ "video",
3960
+ "wbr"
3961
+ ];
3962
+ var SVG_NAMESPACE_TAG_NAMES = [
3963
+ "animate",
3964
+ "animateMotion",
3965
+ "animateTransform",
3799
3966
  "circle",
3967
+ "clipPath",
3968
+ "defs",
3969
+ "desc",
3800
3970
  "ellipse",
3801
- "line",
3802
- "path",
3803
- "polygon",
3804
- "polyline",
3805
- "rect",
3806
- "text",
3807
- "textPath",
3808
- "tspan",
3809
- "linearGradient",
3810
- "radialGradient",
3811
- "stop",
3812
- "filter",
3813
3971
  "feBlend",
3814
3972
  "feColorMatrix",
3815
3973
  "feComponentTransfer",
@@ -3835,20 +3993,43 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
3835
3993
  "feSpotLight",
3836
3994
  "feTile",
3837
3995
  "feTurbulence",
3838
- "animate",
3839
- "animateMotion",
3840
- "animateTransform",
3841
- "set",
3842
- "mpath",
3843
- "desc",
3996
+ "filter",
3844
3997
  "foreignObject",
3998
+ "g",
3845
3999
  "image",
4000
+ "line",
4001
+ "linearGradient",
4002
+ "marker",
4003
+ "mask",
3846
4004
  "metadata",
4005
+ "mpath",
4006
+ "path",
4007
+ "pattern",
4008
+ "polygon",
4009
+ "polyline",
4010
+ "radialGradient",
4011
+ "rect",
4012
+ "set",
4013
+ "stop",
4014
+ "svg",
3847
4015
  "switch",
3848
- "title",
4016
+ "symbol",
4017
+ "text",
4018
+ "textPath",
4019
+ "tspan",
4020
+ "use",
3849
4021
  "view"
3850
- ]);
4022
+ ];
4023
+ var HTML_COMPAT_EXTRA_TAG_NAMES = [
4024
+ "math",
4025
+ "param",
4026
+ "portal"
4027
+ ];
4028
+ var HTML_TAGS = new Set([...HTML_TAG_NAMES, ...HTML_COMPAT_EXTRA_TAG_NAMES]);
4029
+ var SVG_TAGS = new Set(SVG_NAMESPACE_TAG_NAMES);
3851
4030
  var TEMPLATE_TAGS = new Set([...HTML_TAGS, ...SVG_TAGS]);
4031
+
4032
+ // src/components.js
3852
4033
  var BIND_PREFIX = "__bind_";
3853
4034
  var BIND_SUFFIX = "__";
3854
4035
  var LIFECYCLE_HOOKS = new Set(["beforeMount", "mounted", "updated", "beforeUnmount", "unmounted", "onError"]);
@@ -4274,10 +4455,12 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4274
4455
  s.await = true;
4275
4456
  return s.predicate || s.await ? s : to;
4276
4457
  };
4277
- proto.transformComponentMembers = function(sexpr) {
4458
+ proto.transformComponentMembers = function(sexpr, localScope = new Set) {
4278
4459
  const self = this._self;
4279
4460
  if (!Array.isArray(sexpr)) {
4280
4461
  const sv = _str(sexpr);
4462
+ if (sv && localScope.has(sv))
4463
+ return sexpr;
4281
4464
  if (sv && this.reactiveMembers && this.reactiveMembers.has(sv)) {
4282
4465
  return [".", [".", self, sv], _transferMeta(sexpr, "value")];
4283
4466
  }
@@ -4298,20 +4481,46 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4298
4481
  return [sexpr[0], this.transformComponentMembers(sexpr[1]), sexpr[2]];
4299
4482
  }
4300
4483
  if (sexpr[0] === "->") {
4301
- return ["=>", ...sexpr.slice(1).map((item) => this.transformComponentMembers(item))];
4484
+ const params = sexpr[1];
4485
+ const childScope = new Set(localScope);
4486
+ if (Array.isArray(params)) {
4487
+ for (const p of params) {
4488
+ const name = _str(Array.isArray(p) && p[0] === "default" ? p[1] : p);
4489
+ if (name)
4490
+ childScope.add(name);
4491
+ }
4492
+ }
4493
+ return ["=>", sexpr[1], this.transformComponentMembers(sexpr[2], childScope)];
4302
4494
  }
4303
4495
  if (sexpr[0] === "object") {
4304
4496
  return ["object", ...sexpr.slice(1).map((pair) => {
4305
4497
  if (Array.isArray(pair) && pair.length >= 2) {
4306
4498
  let key = pair[0];
4307
- let newKey = Array.isArray(key) ? this.transformComponentMembers(key) : key;
4308
- let newValue = this.transformComponentMembers(pair[1]);
4499
+ let newKey = Array.isArray(key) ? this.transformComponentMembers(key, localScope) : key;
4500
+ let newValue = this.transformComponentMembers(pair[1], localScope);
4309
4501
  return [newKey, newValue, pair[2]];
4310
4502
  }
4311
- return this.transformComponentMembers(pair);
4503
+ return this.transformComponentMembers(pair, localScope);
4312
4504
  })];
4313
4505
  }
4314
- return sexpr.map((item) => this.transformComponentMembers(item));
4506
+ if (sexpr[0] === "block" || sexpr[0] === "program") {
4507
+ const scope = new Set(localScope);
4508
+ const items = [sexpr[0]];
4509
+ for (let i = 1;i < sexpr.length; i++) {
4510
+ const item = sexpr[i];
4511
+ if (Array.isArray(item) && item[0] === "=") {
4512
+ const targetName = _str(item[1]);
4513
+ if (targetName && !(this.reactiveMembers && this.reactiveMembers.has(targetName))) {
4514
+ items.push(["=", item[1], this.transformComponentMembers(item[2], scope)]);
4515
+ scope.add(targetName);
4516
+ continue;
4517
+ }
4518
+ }
4519
+ items.push(this.transformComponentMembers(item, scope));
4520
+ }
4521
+ return items;
4522
+ }
4523
+ return sexpr.map((item) => this.transformComponentMembers(item, localScope));
4315
4524
  };
4316
4525
  proto.generateComponent = function(head, rest, context, sexpr) {
4317
4526
  const [, body] = rest;
@@ -4413,7 +4622,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4413
4622
  const autoEventHandlers = new Map;
4414
4623
  for (const { name } of methods) {
4415
4624
  if (/^on[A-Z]/.test(name) && !LIFECYCLE_HOOKS.has(name)) {
4416
- autoEventHandlers.set(name[2].toLowerCase() + name.slice(3), name);
4625
+ const eventName = name[2].toLowerCase() + name.slice(3);
4626
+ if (DOM_EVENTS.has(eventName))
4627
+ autoEventHandlers.set(eventName, name);
4417
4628
  }
4418
4629
  }
4419
4630
  const inheritsTag = rest[0]?.valueOf?.() ?? null;
@@ -9734,8 +9945,8 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
9734
9945
  return new CodeGenerator({}).getComponentRuntime();
9735
9946
  }
9736
9947
  // src/browser.js
9737
- var VERSION = "3.13.121";
9738
- var BUILD_DATE = "2026-03-17@16:10:50GMT";
9948
+ var VERSION = "3.13.123";
9949
+ var BUILD_DATE = "2026-03-18@04:49:31GMT";
9739
9950
  if (typeof globalThis !== "undefined") {
9740
9951
  if (!globalThis.__rip)
9741
9952
  new Function(getReactiveRuntime())();