@barefootjs/client 0.23.0 → 0.25.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.
@@ -9,22 +9,29 @@
9
9
  *
10
10
  * ```tsx
11
11
  * <time>{formatDate(createdAt, 'YYYY/M/D', '+09:00')}</time>
12
+ * <time>{formatDate(createdAt, 'MMMM D, YYYY', 'UTC', names)}</time>
12
13
  * ```
13
14
  *
14
- * Pattern tokens (longest-match; any other character passes through
15
+ * Numeric tokens (longest-match; any other character passes through
15
16
  * literally): `YYYY` (4-digit zero-padded year, `-`-prefixed for negative
16
17
  * years), `MM` / `M` (zero-padded / bare month `01`–`12` / `1`–`12`), `DD` /
17
- * `D` (zero-padded / bare day of month). The v1 token set is date-only and
18
- * numeric — locale-dependent fields (month names, weekday names) are a
19
- * deliberate later stage of #2324, and per-locale *pattern selection* belongs
20
- * to the app's i18n layer, not to this function.
18
+ * `D` (zero-padded / bare day of month).
19
+ *
20
+ * Name tokens (#2334) read the explicit `names` table the caller owns the
21
+ * values (per-locale name selection is the i18n layer's or the compiler's
22
+ * job, never this function's): `MMMM` / `MMM` (wide / abbreviated month
23
+ * name), `dddd` / `ddd` (wide / abbreviated weekday name, Sunday-first).
24
+ * `names` is a flat array in fixed layout: `[0..11]` wide months, `[12..23]`
25
+ * abbreviated months, `[24..30]` wide weekdays, `[31..37]` abbreviated
26
+ * weekdays. A name token indexing a missing/short table renders `''` — the
27
+ * same normative zero-value discipline as an unparseable date, byte-identical
28
+ * on every backend.
21
29
  *
22
30
  * `timeZone` is `'UTC'` or a fixed offset `±HH:MM` (`'+09:00'`, `'-05:30'`).
23
31
  * The function is total: any other value — including IANA zone names, which
24
32
  * would drag host tzdata versions into the output — normalizes to `'UTC'`, so
25
33
  * every backend degrades identically instead of diverging. An unset or
26
- * unparseable `date` renders `''` (the same normative zero-value discipline as
27
- * the `date` helper, spec/template-helpers.md).
34
+ * unparseable `date` renders `''`.
28
35
  */
29
- export declare function formatDate(date: Date | string, pattern: string, timeZone?: string): string;
36
+ export declare function formatDate(date: Date | string, pattern: string, timeZone?: string, names?: readonly string[]): string;
30
37
  //# sourceMappingURL=format-date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-date.d.ts","sourceRoot":"","sources":["../src/format-date.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAQ,GAAG,MAAM,CAkCzF"}
1
+ {"version":3,"file":"format-date.d.ts","sourceRoot":"","sources":["../src/format-date.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAeH,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,GAAG,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,SAAQ,EAChB,KAAK,GAAE,SAAS,MAAM,EAAO,GAC5B,MAAM,CA4CR"}
package/dist/index.js CHANGED
@@ -164,11 +164,15 @@ function queryHref(base, params) {
164
164
  }
165
165
  // src/format-date.ts
166
166
  var OFFSET_RE = /^([+-])(\d{2}):(\d{2})$/;
167
- var TOKEN_RE = /YYYY|MM|DD|M|D/g;
167
+ var TOKEN_RE = /YYYY|MMMM|MMM|MM|DD|dddd|ddd|M|D/g;
168
+ var MONTHS_WIDE = 0;
169
+ var MONTHS_ABBR = 12;
170
+ var WEEKDAYS_WIDE = 24;
171
+ var WEEKDAYS_ABBR = 31;
168
172
  function pad2(n) {
169
173
  return String(n).padStart(2, "0");
170
174
  }
171
- function formatDate(date, pattern, timeZone = "UTC") {
175
+ function formatDate(date, pattern, timeZone = "UTC", names = []) {
172
176
  if (date === null || date === undefined)
173
177
  return "";
174
178
  const d = date instanceof Date ? date : new Date(date);
@@ -182,10 +186,16 @@ function formatDate(date, pattern, timeZone = "UTC") {
182
186
  const yyyy = (year < 0 ? "-" : "") + String(Math.abs(year)).padStart(4, "0");
183
187
  const month = s.getUTCMonth() + 1;
184
188
  const day = s.getUTCDate();
189
+ const weekday = s.getUTCDay();
190
+ const nameAt = (index) => names[index] ?? "";
185
191
  return pattern.replace(TOKEN_RE, (token) => {
186
192
  switch (token) {
187
193
  case "YYYY":
188
194
  return yyyy;
195
+ case "MMMM":
196
+ return nameAt(MONTHS_WIDE + month - 1);
197
+ case "MMM":
198
+ return nameAt(MONTHS_ABBR + month - 1);
189
199
  case "MM":
190
200
  return pad2(month);
191
201
  case "M":
@@ -194,6 +204,10 @@ function formatDate(date, pattern, timeZone = "UTC") {
194
204
  return pad2(day);
195
205
  case "D":
196
206
  return String(day);
207
+ case "dddd":
208
+ return nameAt(WEEKDAYS_WIDE + weekday);
209
+ case "ddd":
210
+ return nameAt(WEEKDAYS_ABBR + weekday);
197
211
  default:
198
212
  return token;
199
213
  }
@@ -164,11 +164,15 @@ function queryHref(base, params) {
164
164
  }
165
165
  // src/format-date.ts
166
166
  var OFFSET_RE = /^([+-])(\d{2}):(\d{2})$/;
167
- var TOKEN_RE = /YYYY|MM|DD|M|D/g;
167
+ var TOKEN_RE = /YYYY|MMMM|MMM|MM|DD|dddd|ddd|M|D/g;
168
+ var MONTHS_WIDE = 0;
169
+ var MONTHS_ABBR = 12;
170
+ var WEEKDAYS_WIDE = 24;
171
+ var WEEKDAYS_ABBR = 31;
168
172
  function pad2(n) {
169
173
  return String(n).padStart(2, "0");
170
174
  }
171
- function formatDate(date, pattern, timeZone = "UTC") {
175
+ function formatDate(date, pattern, timeZone = "UTC", names = []) {
172
176
  if (date === null || date === undefined)
173
177
  return "";
174
178
  const d = date instanceof Date ? date : new Date(date);
@@ -182,10 +186,16 @@ function formatDate(date, pattern, timeZone = "UTC") {
182
186
  const yyyy = (year < 0 ? "-" : "") + String(Math.abs(year)).padStart(4, "0");
183
187
  const month = s.getUTCMonth() + 1;
184
188
  const day = s.getUTCDate();
189
+ const weekday = s.getUTCDay();
190
+ const nameAt = (index) => names[index] ?? "";
185
191
  return pattern.replace(TOKEN_RE, (token) => {
186
192
  switch (token) {
187
193
  case "YYYY":
188
194
  return yyyy;
195
+ case "MMMM":
196
+ return nameAt(MONTHS_WIDE + month - 1);
197
+ case "MMM":
198
+ return nameAt(MONTHS_ABBR + month - 1);
189
199
  case "MM":
190
200
  return pad2(month);
191
201
  case "M":
@@ -194,6 +204,10 @@ function formatDate(date, pattern, timeZone = "UTC") {
194
204
  return pad2(day);
195
205
  case "D":
196
206
  return String(day);
207
+ case "dddd":
208
+ return nameAt(WEEKDAYS_WIDE + weekday);
209
+ case "ddd":
210
+ return nameAt(WEEKDAYS_ABBR + weekday);
197
211
  default:
198
212
  return token;
199
213
  }
@@ -817,11 +817,15 @@ function queryHref(base, params) {
817
817
  }
818
818
  // src/format-date.ts
819
819
  var OFFSET_RE = /^([+-])(\d{2}):(\d{2})$/;
820
- var TOKEN_RE = /YYYY|MM|DD|M|D/g;
820
+ var TOKEN_RE = /YYYY|MMMM|MMM|MM|DD|dddd|ddd|M|D/g;
821
+ var MONTHS_WIDE = 0;
822
+ var MONTHS_ABBR = 12;
823
+ var WEEKDAYS_WIDE = 24;
824
+ var WEEKDAYS_ABBR = 31;
821
825
  function pad2(n) {
822
826
  return String(n).padStart(2, "0");
823
827
  }
824
- function formatDate(date, pattern, timeZone = "UTC") {
828
+ function formatDate(date, pattern, timeZone = "UTC", names = []) {
825
829
  if (date === null || date === undefined)
826
830
  return "";
827
831
  const d = date instanceof Date ? date : new Date(date);
@@ -835,10 +839,16 @@ function formatDate(date, pattern, timeZone = "UTC") {
835
839
  const yyyy = (year < 0 ? "-" : "") + String(Math.abs(year)).padStart(4, "0");
836
840
  const month = s.getUTCMonth() + 1;
837
841
  const day = s.getUTCDate();
842
+ const weekday = s.getUTCDay();
843
+ const nameAt = (index) => names[index] ?? "";
838
844
  return pattern.replace(TOKEN_RE, (token) => {
839
845
  switch (token) {
840
846
  case "YYYY":
841
847
  return yyyy;
848
+ case "MMMM":
849
+ return nameAt(MONTHS_WIDE + month - 1);
850
+ case "MMM":
851
+ return nameAt(MONTHS_ABBR + month - 1);
842
852
  case "MM":
843
853
  return pad2(month);
844
854
  case "M":
@@ -847,6 +857,10 @@ function formatDate(date, pattern, timeZone = "UTC") {
847
857
  return pad2(day);
848
858
  case "D":
849
859
  return String(day);
860
+ case "dddd":
861
+ return nameAt(WEEKDAYS_WIDE + weekday);
862
+ case "ddd":
863
+ return nameAt(WEEKDAYS_ABBR + weekday);
850
864
  default:
851
865
  return token;
852
866
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/client",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "BarefootJS client package: reactive primitives (SSR-safe) plus browser runtime under the `/runtime` subpath (compiler target)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -55,7 +55,7 @@
55
55
  "directory": "packages/client"
56
56
  },
57
57
  "dependencies": {
58
- "@barefootjs/shared": "0.23.0"
58
+ "@barefootjs/shared": "0.25.0"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@barefootjs/jsx": ">=0.2.0"
@@ -9,32 +9,50 @@
9
9
  *
10
10
  * ```tsx
11
11
  * <time>{formatDate(createdAt, 'YYYY/M/D', '+09:00')}</time>
12
+ * <time>{formatDate(createdAt, 'MMMM D, YYYY', 'UTC', names)}</time>
12
13
  * ```
13
14
  *
14
- * Pattern tokens (longest-match; any other character passes through
15
+ * Numeric tokens (longest-match; any other character passes through
15
16
  * literally): `YYYY` (4-digit zero-padded year, `-`-prefixed for negative
16
17
  * years), `MM` / `M` (zero-padded / bare month `01`–`12` / `1`–`12`), `DD` /
17
- * `D` (zero-padded / bare day of month). The v1 token set is date-only and
18
- * numeric — locale-dependent fields (month names, weekday names) are a
19
- * deliberate later stage of #2324, and per-locale *pattern selection* belongs
20
- * to the app's i18n layer, not to this function.
18
+ * `D` (zero-padded / bare day of month).
19
+ *
20
+ * Name tokens (#2334) read the explicit `names` table the caller owns the
21
+ * values (per-locale name selection is the i18n layer's or the compiler's
22
+ * job, never this function's): `MMMM` / `MMM` (wide / abbreviated month
23
+ * name), `dddd` / `ddd` (wide / abbreviated weekday name, Sunday-first).
24
+ * `names` is a flat array in fixed layout: `[0..11]` wide months, `[12..23]`
25
+ * abbreviated months, `[24..30]` wide weekdays, `[31..37]` abbreviated
26
+ * weekdays. A name token indexing a missing/short table renders `''` — the
27
+ * same normative zero-value discipline as an unparseable date, byte-identical
28
+ * on every backend.
21
29
  *
22
30
  * `timeZone` is `'UTC'` or a fixed offset `±HH:MM` (`'+09:00'`, `'-05:30'`).
23
31
  * The function is total: any other value — including IANA zone names, which
24
32
  * would drag host tzdata versions into the output — normalizes to `'UTC'`, so
25
33
  * every backend degrades identically instead of diverging. An unset or
26
- * unparseable `date` renders `''` (the same normative zero-value discipline as
27
- * the `date` helper, spec/template-helpers.md).
34
+ * unparseable `date` renders `''`.
28
35
  */
29
36
 
30
37
  const OFFSET_RE = /^([+-])(\d{2}):(\d{2})$/
31
- const TOKEN_RE = /YYYY|MM|DD|M|D/g
38
+ const TOKEN_RE = /YYYY|MMMM|MMM|MM|DD|dddd|ddd|M|D/g
39
+
40
+ /** `names`-table section offsets (spec/template-helpers.md "format_date"). */
41
+ const MONTHS_WIDE = 0
42
+ const MONTHS_ABBR = 12
43
+ const WEEKDAYS_WIDE = 24
44
+ const WEEKDAYS_ABBR = 31
32
45
 
33
46
  function pad2(n: number): string {
34
47
  return String(n).padStart(2, '0')
35
48
  }
36
49
 
37
- export function formatDate(date: Date | string, pattern: string, timeZone = 'UTC'): string {
50
+ export function formatDate(
51
+ date: Date | string,
52
+ pattern: string,
53
+ timeZone = 'UTC',
54
+ names: readonly string[] = [],
55
+ ): string {
38
56
  // Explicit nullish guard: `new Date(null)` is epoch 0, not Invalid Date,
39
57
  // so without this a nil receiver would format 1970-01-01 instead of the
40
58
  // contract's '' (spec/template-helpers.md "format_date", golden vector
@@ -52,10 +70,16 @@ export function formatDate(date: Date | string, pattern: string, timeZone = 'UTC
52
70
  const yyyy = (year < 0 ? '-' : '') + String(Math.abs(year)).padStart(4, '0')
53
71
  const month = s.getUTCMonth() + 1
54
72
  const day = s.getUTCDate()
73
+ const weekday = s.getUTCDay() // 0 = Sunday, matching the table's Sunday-first layout
74
+ const nameAt = (index: number): string => names[index] ?? ''
55
75
  return pattern.replace(TOKEN_RE, (token) => {
56
76
  switch (token) {
57
77
  case 'YYYY':
58
78
  return yyyy
79
+ case 'MMMM':
80
+ return nameAt(MONTHS_WIDE + month - 1)
81
+ case 'MMM':
82
+ return nameAt(MONTHS_ABBR + month - 1)
59
83
  case 'MM':
60
84
  return pad2(month)
61
85
  case 'M':
@@ -64,6 +88,10 @@ export function formatDate(date: Date | string, pattern: string, timeZone = 'UTC
64
88
  return pad2(day)
65
89
  case 'D':
66
90
  return String(day)
91
+ case 'dddd':
92
+ return nameAt(WEEKDAYS_WIDE + weekday)
93
+ case 'ddd':
94
+ return nameAt(WEEKDAYS_ABBR + weekday)
67
95
  default:
68
96
  return token
69
97
  }