@barefootjs/perl 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present BarefootJS Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,5 +1,5 @@
1
1
  package BarefootJS::DevReload;
2
- our $VERSION = "0.01";
2
+ our $VERSION = "0.8.0";
3
3
  use strict;
4
4
  use warnings;
5
5
  use feature 'signatures';
package/lib/BarefootJS.pm CHANGED
@@ -1,5 +1,5 @@
1
1
  package BarefootJS;
2
- our $VERSION = "0.01";
2
+ our $VERSION = "0.8.0";
3
3
  use strict;
4
4
  use warnings;
5
5
  use utf8;
@@ -504,6 +504,84 @@ sub includes ($self, $recv, $elem) {
504
504
  return index($recv // '', $elem // '') != -1 ? 1 : 0;
505
505
  }
506
506
 
507
+ # `Array.prototype.filter(fn)` / `.every(fn)` / `.some(fn)`. The Xslate adapter
508
+ # lowers a JS arrow predicate to a Kolon lambda (`-> $x { ... }`), which is
509
+ # callable from Perl as a code ref, and emits `$bf.filter($arr, <lambda>)`.
510
+ # `filter` returns a new arrayref; `every` / `some` return 1/0. Non-array /
511
+ # empty receivers follow JS (`filter` → [], `every` → true, `some` → false).
512
+ # (The Mojo adapter lowers these shapes inline and never reaches these methods.)
513
+ sub filter ($self, $recv, $pred) {
514
+ return [] unless ref($recv) eq 'ARRAY';
515
+ return [ grep { $pred->($_) } @$recv ];
516
+ }
517
+
518
+ sub every ($self, $recv, $pred) {
519
+ return 1 unless ref($recv) eq 'ARRAY';
520
+ for my $item (@$recv) { return 0 unless $pred->($item) }
521
+ return 1;
522
+ }
523
+
524
+ sub some ($self, $recv, $pred) {
525
+ return 0 unless ref($recv) eq 'ARRAY';
526
+ for my $item (@$recv) { return 1 if $pred->($item) }
527
+ return 0;
528
+ }
529
+
530
+ # `Array.prototype.find(fn)` / `.findIndex(fn)` / `.findLast(fn)` /
531
+ # `.findLastIndex(fn)` — same Kolon-lambda predicate mechanism as filter. The
532
+ # camelCase JS names lower to these snake_case methods (like index_of /
533
+ # last_index_of). `find` / `find_last` return the matching element (or undef →
534
+ # JS `undefined`); the index forms return the 0-based position (or -1).
535
+ sub find ($self, $recv, $pred) {
536
+ return undef unless ref($recv) eq 'ARRAY';
537
+ for my $item (@$recv) { return $item if $pred->($item) }
538
+ return undef;
539
+ }
540
+
541
+ sub find_index ($self, $recv, $pred) {
542
+ return -1 unless ref($recv) eq 'ARRAY';
543
+ for my $i (0 .. $#$recv) { return $i if $pred->($recv->[$i]) }
544
+ return -1;
545
+ }
546
+
547
+ sub find_last ($self, $recv, $pred) {
548
+ return undef unless ref($recv) eq 'ARRAY';
549
+ for my $i (reverse 0 .. $#$recv) { return $recv->[$i] if $pred->($recv->[$i]) }
550
+ return undef;
551
+ }
552
+
553
+ sub find_last_index ($self, $recv, $pred) {
554
+ return -1 unless ref($recv) eq 'ARRAY';
555
+ for my $i (reverse 0 .. $#$recv) { return $i if $pred->($recv->[$i]) }
556
+ return -1;
557
+ }
558
+
559
+ # `String.prototype.toLowerCase()` / `.toUpperCase()`. Kolon has a builtin
560
+ # `.join` array method (so the adapter uses that directly) but no builtin
561
+ # `lc` / `uc`, so these live on the runtime object. `CORE::` avoids recursing
562
+ # into these methods.
563
+ sub lc ($self, $s) { return defined $s ? CORE::lc($s) : '' }
564
+ sub uc ($self, $s) { return defined $s ? CORE::uc($s) : '' }
565
+
566
+ # `Array.prototype.join(sep)` with JS semantics: separator defaults to ",",
567
+ # and undefined / null elements render as empty (`[1,,2].join(",")` → "1,,2").
568
+ # Kolon has a builtin `.join`, but routing through the runtime keeps the
569
+ # JS-compat element handling in one place. `CORE::join` avoids recursing.
570
+ sub join ($self, $recv, $sep = undef) {
571
+ return '' unless ref($recv) eq 'ARRAY';
572
+ $sep //= ',';
573
+ return CORE::join($sep, map { defined $_ ? $_ : '' } @$recv);
574
+ }
575
+
576
+ # `.length` — JS works on BOTH arrays (element count) and strings (character
577
+ # count); Kolon's builtin `.size()` is array-only and faults on a string. So
578
+ # dispatch on ref type here. `CORE::length` avoids recursing into this method.
579
+ sub length ($self, $recv) {
580
+ return scalar @$recv if ref($recv) eq 'ARRAY';
581
+ return 0 if ref($recv);
582
+ return CORE::length($recv // '');
583
+ }
584
+
507
585
  # `Array.prototype.indexOf(x)` / `Array.prototype.lastIndexOf(x)`
508
586
  # value-equality search (#1448 Tier A). Returns the 0-based position
509
587
  # of the first / last matching element, or -1 if not found.
@@ -762,10 +840,10 @@ sub starts_with ($self, $recv, $prefix, $position = undef) {
762
840
  if (defined $position) {
763
841
  my $n = int($position);
764
842
  $n = 0 if $n < 0;
765
- $n = length($s) if $n > length($s);
843
+ $n = CORE::length($s) if $n > CORE::length($s);
766
844
  $s = substr($s, $n);
767
845
  }
768
- return substr($s, 0, length $p) eq $p ? 1 : 0;
846
+ return substr($s, 0, CORE::length $p) eq $p ? 1 : 0;
769
847
  }
770
848
 
771
849
  # `String.prototype.endsWith(suffix, endPosition?)` (#1448 Tier B) —
@@ -782,12 +860,12 @@ sub ends_with ($self, $recv, $suffix, $end_position = undef) {
782
860
  if (defined $end_position) {
783
861
  my $e = int($end_position);
784
862
  $e = 0 if $e < 0;
785
- $e = length($s) if $e > length($s);
863
+ $e = CORE::length($s) if $e > CORE::length($s);
786
864
  $s = substr($s, 0, $e);
787
865
  }
788
866
  return 1 if $x eq '';
789
- return 0 if length($s) < length($x);
790
- return substr($s, -length $x) eq $x ? 1 : 0;
867
+ return 0 if CORE::length($s) < CORE::length($x);
868
+ return substr($s, -CORE::length $x) eq $x ? 1 : 0;
791
869
  }
792
870
 
793
871
  # `String.prototype.replace(pattern, replacement)` — string-pattern
@@ -808,7 +886,7 @@ sub replace ($self, $recv, $pattern, $replacement) {
808
886
  return $n . $s if $o eq '';
809
887
  my $i = index($s, $o);
810
888
  return $s if $i < 0;
811
- return substr($s, 0, $i) . $n . substr($s, $i + length($o));
889
+ return substr($s, 0, $i) . $n . substr($s, $i + CORE::length($o));
812
890
  }
813
891
 
814
892
  # `String.prototype.repeat(n)` — the receiver concatenated n times
@@ -837,12 +915,12 @@ sub _pad ($s, $target, $pad, $at_start) {
837
915
  $pad = ' ' unless defined $pad;
838
916
  $pad = "$pad";
839
917
  return $s if $pad eq '';
840
- my $len = length $s;
918
+ my $len = CORE::length $s;
841
919
  my $t = int($target // 0);
842
920
  return $s if $len >= $t;
843
921
  my $need = $t - $len;
844
922
  # Repeat enough copies to cover $need, then trim to exactly $need.
845
- my $fill = substr($pad x (int($need / length($pad)) + 1), 0, $need);
923
+ my $fill = substr($pad x (int($need / CORE::length($pad)) + 1), 0, $need);
846
924
  return $at_start ? $fill . $s : $s . $fill;
847
925
  }
848
926
 
@@ -1097,7 +1175,7 @@ sub _style_to_css ($value) {
1097
1175
  # `typeof value !== 'object'` branch in `styleToCss`.
1098
1176
  if (ref($value) ne 'HASH') {
1099
1177
  my $s = "$value";
1100
- return length $s ? $s : undef;
1178
+ return CORE::length $s ? $s : undef;
1101
1179
  }
1102
1180
  my @parts;
1103
1181
  for my $key (sort keys %$value) {
@@ -1107,7 +1185,7 @@ sub _style_to_css ($value) {
1107
1185
  $prop =~ s/([A-Z])/-\L$1/g;
1108
1186
  push @parts, "$prop:$v";
1109
1187
  }
1110
- return @parts ? join(';', @parts) : undef;
1188
+ return @parts ? CORE::join(';', @parts) : undef;
1111
1189
  }
1112
1190
 
1113
1191
  sub spread_attrs ($self, $bag) {
@@ -1117,9 +1195,9 @@ sub spread_attrs ($self, $bag) {
1117
1195
  # Event handlers: skip when key starts `on` and the third
1118
1196
  # character is its own uppercase form (uppercase letter,
1119
1197
  # digit, underscore, …). Mirrors the JS predicate.
1120
- if (length($key) > 2 && substr($key, 0, 2) eq 'on') {
1198
+ if (CORE::length($key) > 2 && substr($key, 0, 2) eq 'on') {
1121
1199
  my $c = substr($key, 2, 1);
1122
- next if uc($c) eq $c;
1200
+ next if CORE::uc($c) eq $c;
1123
1201
  }
1124
1202
  next if $key eq 'children';
1125
1203
  my $val = $bag->{$key};
@@ -1143,7 +1221,7 @@ sub spread_attrs ($self, $bag) {
1143
1221
  # serialise to a real CSS string.
1144
1222
  if ($key eq 'style') {
1145
1223
  my $css = _style_to_css($val);
1146
- next unless defined $css && length $css;
1224
+ next unless defined $css && CORE::length $css;
1147
1225
  push @parts, qq{style="} . _html_escape($css) . qq{"};
1148
1226
  next;
1149
1227
  }
@@ -1154,7 +1232,7 @@ sub spread_attrs ($self, $bag) {
1154
1232
  # Mark the result raw so the calling template's `<%==` raw-emit
1155
1233
  # doesn't re-escape the already-escaped values (the Mojo backend
1156
1234
  # returns a Mojo::ByteStream).
1157
- return $self->backend->mark_raw(join(' ', @parts));
1235
+ return $self->backend->mark_raw(CORE::join(' ', @parts));
1158
1236
  }
1159
1237
 
1160
1238
  1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/perl",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "BarefootJS engine-agnostic Perl runtime (BarefootJS.pm) — pluggable rendering backend; the shared basis for Mojolicious and other Perl framework integrations",
5
5
  "type": "module",
6
6
  "files": [