@atproto/lex-data 0.0.10 → 0.0.12

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.
@@ -3,24 +3,116 @@ export type { Base64Alphabet };
3
3
  /**
4
4
  * Encodes a Uint8Array into a base64 string.
5
5
  *
6
+ * Uses native Uint8Array.prototype.toBase64 when available (Node.js 24+, modern browsers),
7
+ * falling back to Node.js Buffer or a ponyfill implementation.
8
+ *
9
+ * @param bytes - The binary data to encode
10
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
6
11
  * @returns The base64 encoded string
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { toBase64 } from '@atproto/lex-data'
16
+ *
17
+ * const bytes = new Uint8Array([72, 101, 108, 108, 111])
18
+ * toBase64(bytes) // 'SGVsbG8='
19
+ * toBase64(bytes, 'base64url') // 'SGVsbG8' (URL-safe, no padding)
20
+ * ```
7
21
  */
8
22
  export declare const toBase64: (bytes: Uint8Array, alphabet?: Base64Alphabet) => string;
9
23
  /**
10
- * Decodes a base64 string into a Uint8Array. This function supports both padded
11
- * and unpadded base64 strings.
24
+ * Decodes a base64 string into a Uint8Array.
25
+ *
26
+ * Supports both padded and unpadded base64 strings. Uses native
27
+ * Uint8Array.fromBase64 when available, falling back to Node.js Buffer
28
+ * or a ponyfill implementation.
12
29
  *
13
- * @returns The decoded {@link Uint8Array}
30
+ * @param b64 - The base64 string to decode
31
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
32
+ * @returns The decoded binary data
14
33
  * @throws If the input is not a valid base64 string
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * import { fromBase64 } from '@atproto/lex-data'
38
+ *
39
+ * fromBase64('SGVsbG8=') // Uint8Array([72, 101, 108, 108, 111])
40
+ * fromBase64('SGVsbG8', 'base64url') // Same, URL-safe alphabet
41
+ * ```
15
42
  */
16
43
  export declare const fromBase64: (b64: string, alphabet?: Base64Alphabet) => Uint8Array;
44
+ /**
45
+ * Returns the input if it is a Uint8Array, otherwise returns undefined.
46
+ *
47
+ * @param input - The value to check
48
+ * @returns The input if it's a Uint8Array, otherwise undefined
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { ifUint8Array } from '@atproto/lex-data'
53
+ *
54
+ * ifUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
55
+ * ifUint8Array('not binary') // undefined
56
+ * ifUint8Array(new ArrayBuffer(4)) // undefined
57
+ * ```
58
+ */
17
59
  export declare function ifUint8Array(input: unknown): Uint8Array | undefined;
18
60
  /**
19
61
  * Coerces various binary data representations into a Uint8Array.
20
62
  *
21
- * @return `undefined` if the input could not be coerced into a {@link Uint8Array}.
63
+ * Handles the following input types:
64
+ * - `Uint8Array` - Returned as-is
65
+ * - `ArrayBufferView` (e.g., DataView, other TypedArrays) - Converted to Uint8Array
66
+ * - `ArrayBuffer` - Wrapped in a Uint8Array
67
+ *
68
+ * @param input - The value to convert
69
+ * @returns A Uint8Array, or `undefined` if the input could not be converted
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { asUint8Array } from '@atproto/lex-data'
74
+ *
75
+ * asUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
76
+ * asUint8Array(new ArrayBuffer(4)) // Uint8Array of length 4
77
+ * asUint8Array(new Int16Array([1, 2])) // Uint8Array view of the buffer
78
+ * asUint8Array('string') // undefined
79
+ * ```
22
80
  */
23
81
  export declare function asUint8Array(input: unknown): Uint8Array | undefined;
82
+ /**
83
+ * Compares two Uint8Arrays for byte-by-byte equality.
84
+ *
85
+ * @param a - First Uint8Array to compare
86
+ * @param b - Second Uint8Array to compare
87
+ * @returns `true` if both arrays have the same length and identical bytes
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * import { ui8Equals } from '@atproto/lex-data'
92
+ *
93
+ * ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 2])) // true
94
+ * ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 3])) // false
95
+ * ui8Equals(new Uint8Array([1]), new Uint8Array([1, 2])) // false
96
+ * ```
97
+ */
24
98
  export declare function ui8Equals(a: Uint8Array, b: Uint8Array): boolean;
99
+ /**
100
+ * Concatenates multiple Uint8Arrays into a single Uint8Array.
101
+ *
102
+ * Uses Node.js Buffer.concat when available for performance,
103
+ * falling back to a ponyfill implementation.
104
+ *
105
+ * @param arrays - The Uint8Arrays to concatenate
106
+ * @returns A new Uint8Array containing all input bytes in order
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * import { ui8Concat } from '@atproto/lex-data'
111
+ *
112
+ * const a = new Uint8Array([1, 2])
113
+ * const b = new Uint8Array([3, 4])
114
+ * ui8Concat([a, b]) // Uint8Array([1, 2, 3, 4])
115
+ * ```
116
+ */
25
117
  export declare const ui8Concat: (array: readonly Uint8Array[]) => Uint8Array;
26
118
  //# sourceMappingURL=uint8array.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uint8array.d.ts","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAavD,YAAY,EAAE,cAAc,EAAE,CAAA;AAO9B;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,CACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,cAAc,KACtB,MAGa,CAAA;AAElB;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,UAGe,CAAA;AAUpB,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAMnE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAkBnE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAY/D;AAED,eAAO,MAAM,SAAS,8CACgD,CAAA"}
1
+ {"version":3,"file":"uint8array.d.ts","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAavD,YAAY,EAAE,cAAc,EAAE,CAAA;AAO9B;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,EAAE,CACrB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,cAAc,KACtB,MAGa,CAAA;AAElB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,UAAU,EAAE,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,UAGe,CAAA;AAUpB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAMnE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAkBnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAY/D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,8CACgD,CAAA"}
@@ -14,18 +14,45 @@ const uint8array_to_base64_js_1 = require("./uint8array-to-base64.js");
14
14
  /**
15
15
  * Encodes a Uint8Array into a base64 string.
16
16
  *
17
+ * Uses native Uint8Array.prototype.toBase64 when available (Node.js 24+, modern browsers),
18
+ * falling back to Node.js Buffer or a ponyfill implementation.
19
+ *
20
+ * @param bytes - The binary data to encode
21
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
17
22
  * @returns The base64 encoded string
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { toBase64 } from '@atproto/lex-data'
27
+ *
28
+ * const bytes = new Uint8Array([72, 101, 108, 108, 111])
29
+ * toBase64(bytes) // 'SGVsbG8='
30
+ * toBase64(bytes, 'base64url') // 'SGVsbG8' (URL-safe, no padding)
31
+ * ```
18
32
  */
19
33
  exports.toBase64 =
20
34
  /* v8 ignore next -- @preserve */ uint8array_to_base64_js_1.toBase64Native ??
21
35
  uint8array_to_base64_js_1.toBase64Node ??
22
36
  uint8array_to_base64_js_1.toBase64Ponyfill;
23
37
  /**
24
- * Decodes a base64 string into a Uint8Array. This function supports both padded
25
- * and unpadded base64 strings.
38
+ * Decodes a base64 string into a Uint8Array.
39
+ *
40
+ * Supports both padded and unpadded base64 strings. Uses native
41
+ * Uint8Array.fromBase64 when available, falling back to Node.js Buffer
42
+ * or a ponyfill implementation.
26
43
  *
27
- * @returns The decoded {@link Uint8Array}
44
+ * @param b64 - The base64 string to decode
45
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'
46
+ * @returns The decoded binary data
28
47
  * @throws If the input is not a valid base64 string
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * import { fromBase64 } from '@atproto/lex-data'
52
+ *
53
+ * fromBase64('SGVsbG8=') // Uint8Array([72, 101, 108, 108, 111])
54
+ * fromBase64('SGVsbG8', 'base64url') // Same, URL-safe alphabet
55
+ * ```
29
56
  */
30
57
  exports.fromBase64 =
31
58
  /* v8 ignore next -- @preserve */ uint8array_from_base64_js_1.fromBase64Native ??
@@ -36,6 +63,21 @@ if (exports.toBase64 === uint8array_to_base64_js_1.toBase64Ponyfill || exports.f
36
63
  /*#__PURE__*/
37
64
  console.warn('[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.');
38
65
  }
66
+ /**
67
+ * Returns the input if it is a Uint8Array, otherwise returns undefined.
68
+ *
69
+ * @param input - The value to check
70
+ * @returns The input if it's a Uint8Array, otherwise undefined
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { ifUint8Array } from '@atproto/lex-data'
75
+ *
76
+ * ifUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
77
+ * ifUint8Array('not binary') // undefined
78
+ * ifUint8Array(new ArrayBuffer(4)) // undefined
79
+ * ```
80
+ */
39
81
  function ifUint8Array(input) {
40
82
  if (input instanceof Uint8Array) {
41
83
  return input;
@@ -45,7 +87,23 @@ function ifUint8Array(input) {
45
87
  /**
46
88
  * Coerces various binary data representations into a Uint8Array.
47
89
  *
48
- * @return `undefined` if the input could not be coerced into a {@link Uint8Array}.
90
+ * Handles the following input types:
91
+ * - `Uint8Array` - Returned as-is
92
+ * - `ArrayBufferView` (e.g., DataView, other TypedArrays) - Converted to Uint8Array
93
+ * - `ArrayBuffer` - Wrapped in a Uint8Array
94
+ *
95
+ * @param input - The value to convert
96
+ * @returns A Uint8Array, or `undefined` if the input could not be converted
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * import { asUint8Array } from '@atproto/lex-data'
101
+ *
102
+ * asUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])
103
+ * asUint8Array(new ArrayBuffer(4)) // Uint8Array of length 4
104
+ * asUint8Array(new Int16Array([1, 2])) // Uint8Array view of the buffer
105
+ * asUint8Array('string') // undefined
106
+ * ```
49
107
  */
50
108
  function asUint8Array(input) {
51
109
  if (input instanceof Uint8Array) {
@@ -59,6 +117,22 @@ function asUint8Array(input) {
59
117
  }
60
118
  return undefined;
61
119
  }
120
+ /**
121
+ * Compares two Uint8Arrays for byte-by-byte equality.
122
+ *
123
+ * @param a - First Uint8Array to compare
124
+ * @param b - Second Uint8Array to compare
125
+ * @returns `true` if both arrays have the same length and identical bytes
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * import { ui8Equals } from '@atproto/lex-data'
130
+ *
131
+ * ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 2])) // true
132
+ * ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 3])) // false
133
+ * ui8Equals(new Uint8Array([1]), new Uint8Array([1, 2])) // false
134
+ * ```
135
+ */
62
136
  function ui8Equals(a, b) {
63
137
  if (a.byteLength !== b.byteLength) {
64
138
  return false;
@@ -70,6 +144,24 @@ function ui8Equals(a, b) {
70
144
  }
71
145
  return true;
72
146
  }
147
+ /**
148
+ * Concatenates multiple Uint8Arrays into a single Uint8Array.
149
+ *
150
+ * Uses Node.js Buffer.concat when available for performance,
151
+ * falling back to a ponyfill implementation.
152
+ *
153
+ * @param arrays - The Uint8Arrays to concatenate
154
+ * @returns A new Uint8Array containing all input bytes in order
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * import { ui8Concat } from '@atproto/lex-data'
159
+ *
160
+ * const a = new Uint8Array([1, 2])
161
+ * const b = new Uint8Array([3, 4])
162
+ * ui8Concat([a, b]) // Uint8Array([1, 2, 3, 4])
163
+ * ```
164
+ */
73
165
  exports.ui8Concat =
74
166
  /* v8 ignore next -- @preserve */ uint8array_concat_js_1.ui8ConcatNode ?? uint8array_concat_js_1.ui8ConcatPonyfill;
75
167
  //# sourceMappingURL=uint8array.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uint8array.js","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":";;;AAwDA,oCAMC;AAOD,oCAkBC;AAED,8BAYC;AApGD,iEAAyE;AACzE,2EAIoC;AACpC,uEAIkC;AAIlC,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,0CAA0C;AAE1C;;;;GAIG;AACU,QAAA,QAAQ;AAInB,iCAAiC,CAAC,wCAAc;IAChD,sCAAY;IACZ,0CAAgB,CAAA;AAElB;;;;;;GAMG;AACU,QAAA,UAAU;AAIrB,iCAAiC,CAAC,4CAAgB;IAClD,0CAAc;IACd,8CAAkB,CAAA;AAEpB,iCAAiC;AACjC,IAAI,gBAAQ,KAAK,0CAAgB,IAAI,kBAAU,KAAK,8CAAkB,EAAE,CAAC;IACvE,aAAa;IACb,OAAO,CAAC,IAAI,CACV,wJAAwJ,CACzJ,CAAA;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,UAAU,CACnB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAChD,CAAA;IACH,CAAC;IAED,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAgB,SAAS,CAAC,CAAa,EAAE,CAAa;IACpD,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAEY,QAAA,SAAS;AACpB,iCAAiC,CAAC,oCAAa,IAAI,wCAAiB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array-base64.js'\nimport { ui8ConcatNode, ui8ConcatPonyfill } from './uint8array-concat.js'\nimport {\n fromBase64Native,\n fromBase64Node,\n fromBase64Ponyfill,\n} from './uint8array-from-base64.js'\nimport {\n toBase64Native,\n toBase64Node,\n toBase64Ponyfill,\n} from './uint8array-to-base64.js'\n\nexport type { Base64Alphabet }\n\n// @TODO drop dependency on uint8arrays package once Uint8Array.fromBase64 /\n// Uint8Array.prototype.toBase64 is widely supported, and mark fromBase64 /\n// toBase64 as deprecated. We can also drop NodeJS specific implementations\n// once NodeJS <24 is no longer supported.\n\n/**\n * Encodes a Uint8Array into a base64 string.\n *\n * @returns The base64 encoded string\n */\nexport const toBase64: (\n bytes: Uint8Array,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ toBase64Native ??\n toBase64Node ??\n toBase64Ponyfill\n\n/**\n * Decodes a base64 string into a Uint8Array. This function supports both padded\n * and unpadded base64 strings.\n *\n * @returns The decoded {@link Uint8Array}\n * @throws If the input is not a valid base64 string\n */\nexport const fromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => Uint8Array =\n /* v8 ignore next -- @preserve */ fromBase64Native ??\n fromBase64Node ??\n fromBase64Ponyfill\n\n/* v8 ignore next -- @preserve */\nif (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\nexport function ifUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n return undefined\n}\n\n/**\n * Coerces various binary data representations into a Uint8Array.\n *\n * @return `undefined` if the input could not be coerced into a {@link Uint8Array}.\n */\nexport function asUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n if (ArrayBuffer.isView(input)) {\n return new Uint8Array(\n input.buffer,\n input.byteOffset,\n input.byteLength / Uint8Array.BYTES_PER_ELEMENT,\n )\n }\n\n if (input instanceof ArrayBuffer) {\n return new Uint8Array(input)\n }\n\n return undefined\n}\n\nexport function ui8Equals(a: Uint8Array, b: Uint8Array): boolean {\n if (a.byteLength !== b.byteLength) {\n return false\n }\n\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n\n return true\n}\n\nexport const ui8Concat =\n /* v8 ignore next -- @preserve */ ui8ConcatNode ?? ui8ConcatPonyfill\n"]}
1
+ {"version":3,"file":"uint8array.js","sourceRoot":"","sources":["../src/uint8array.ts"],"names":[],"mappings":";;;AAkGA,oCAMC;AAuBD,oCAkBC;AAkBD,8BAYC;AA9KD,iEAAyE;AACzE,2EAIoC;AACpC,uEAIkC;AAIlC,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,0CAA0C;AAE1C;;;;;;;;;;;;;;;;;;GAkBG;AACU,QAAA,QAAQ;AAInB,iCAAiC,CAAC,wCAAc;IAChD,sCAAY;IACZ,0CAAgB,CAAA;AAElB;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,UAAU;AAIrB,iCAAiC,CAAC,4CAAgB;IAClD,0CAAc;IACd,8CAAkB,CAAA;AAEpB,iCAAiC;AACjC,IAAI,gBAAQ,KAAK,0CAAgB,IAAI,kBAAU,KAAK,8CAAkB,EAAE,CAAC;IACvE,aAAa;IACb,OAAO,CAAC,IAAI,CACV,wJAAwJ,CACzJ,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,UAAU,CACnB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAChD,CAAA;IACH,CAAC;IAED,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,SAAS,CAAC,CAAa,EAAE,CAAa;IACpD,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,SAAS;AACpB,iCAAiC,CAAC,oCAAa,IAAI,wCAAiB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array-base64.js'\nimport { ui8ConcatNode, ui8ConcatPonyfill } from './uint8array-concat.js'\nimport {\n fromBase64Native,\n fromBase64Node,\n fromBase64Ponyfill,\n} from './uint8array-from-base64.js'\nimport {\n toBase64Native,\n toBase64Node,\n toBase64Ponyfill,\n} from './uint8array-to-base64.js'\n\nexport type { Base64Alphabet }\n\n// @TODO drop dependency on uint8arrays package once Uint8Array.fromBase64 /\n// Uint8Array.prototype.toBase64 is widely supported, and mark fromBase64 /\n// toBase64 as deprecated. We can also drop NodeJS specific implementations\n// once NodeJS <24 is no longer supported.\n\n/**\n * Encodes a Uint8Array into a base64 string.\n *\n * Uses native Uint8Array.prototype.toBase64 when available (Node.js 24+, modern browsers),\n * falling back to Node.js Buffer or a ponyfill implementation.\n *\n * @param bytes - The binary data to encode\n * @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'\n * @returns The base64 encoded string\n *\n * @example\n * ```typescript\n * import { toBase64 } from '@atproto/lex-data'\n *\n * const bytes = new Uint8Array([72, 101, 108, 108, 111])\n * toBase64(bytes) // 'SGVsbG8='\n * toBase64(bytes, 'base64url') // 'SGVsbG8' (URL-safe, no padding)\n * ```\n */\nexport const toBase64: (\n bytes: Uint8Array,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ toBase64Native ??\n toBase64Node ??\n toBase64Ponyfill\n\n/**\n * Decodes a base64 string into a Uint8Array.\n *\n * Supports both padded and unpadded base64 strings. Uses native\n * Uint8Array.fromBase64 when available, falling back to Node.js Buffer\n * or a ponyfill implementation.\n *\n * @param b64 - The base64 string to decode\n * @param alphabet - The base64 alphabet to use ('base64' or 'base64url'), defaults to 'base64'\n * @returns The decoded binary data\n * @throws If the input is not a valid base64 string\n *\n * @example\n * ```typescript\n * import { fromBase64 } from '@atproto/lex-data'\n *\n * fromBase64('SGVsbG8=') // Uint8Array([72, 101, 108, 108, 111])\n * fromBase64('SGVsbG8', 'base64url') // Same, URL-safe alphabet\n * ```\n */\nexport const fromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => Uint8Array =\n /* v8 ignore next -- @preserve */ fromBase64Native ??\n fromBase64Node ??\n fromBase64Ponyfill\n\n/* v8 ignore next -- @preserve */\nif (toBase64 === toBase64Ponyfill || fromBase64 === fromBase64Ponyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Uint8Array.fromBase64 / Uint8Array.prototype.toBase64 not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\n/**\n * Returns the input if it is a Uint8Array, otherwise returns undefined.\n *\n * @param input - The value to check\n * @returns The input if it's a Uint8Array, otherwise undefined\n *\n * @example\n * ```typescript\n * import { ifUint8Array } from '@atproto/lex-data'\n *\n * ifUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])\n * ifUint8Array('not binary') // undefined\n * ifUint8Array(new ArrayBuffer(4)) // undefined\n * ```\n */\nexport function ifUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n return undefined\n}\n\n/**\n * Coerces various binary data representations into a Uint8Array.\n *\n * Handles the following input types:\n * - `Uint8Array` - Returned as-is\n * - `ArrayBufferView` (e.g., DataView, other TypedArrays) - Converted to Uint8Array\n * - `ArrayBuffer` - Wrapped in a Uint8Array\n *\n * @param input - The value to convert\n * @returns A Uint8Array, or `undefined` if the input could not be converted\n *\n * @example\n * ```typescript\n * import { asUint8Array } from '@atproto/lex-data'\n *\n * asUint8Array(new Uint8Array([1, 2])) // Uint8Array([1, 2])\n * asUint8Array(new ArrayBuffer(4)) // Uint8Array of length 4\n * asUint8Array(new Int16Array([1, 2])) // Uint8Array view of the buffer\n * asUint8Array('string') // undefined\n * ```\n */\nexport function asUint8Array(input: unknown): Uint8Array | undefined {\n if (input instanceof Uint8Array) {\n return input\n }\n\n if (ArrayBuffer.isView(input)) {\n return new Uint8Array(\n input.buffer,\n input.byteOffset,\n input.byteLength / Uint8Array.BYTES_PER_ELEMENT,\n )\n }\n\n if (input instanceof ArrayBuffer) {\n return new Uint8Array(input)\n }\n\n return undefined\n}\n\n/**\n * Compares two Uint8Arrays for byte-by-byte equality.\n *\n * @param a - First Uint8Array to compare\n * @param b - Second Uint8Array to compare\n * @returns `true` if both arrays have the same length and identical bytes\n *\n * @example\n * ```typescript\n * import { ui8Equals } from '@atproto/lex-data'\n *\n * ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 2])) // true\n * ui8Equals(new Uint8Array([1, 2]), new Uint8Array([1, 3])) // false\n * ui8Equals(new Uint8Array([1]), new Uint8Array([1, 2])) // false\n * ```\n */\nexport function ui8Equals(a: Uint8Array, b: Uint8Array): boolean {\n if (a.byteLength !== b.byteLength) {\n return false\n }\n\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Concatenates multiple Uint8Arrays into a single Uint8Array.\n *\n * Uses Node.js Buffer.concat when available for performance,\n * falling back to a ponyfill implementation.\n *\n * @param arrays - The Uint8Arrays to concatenate\n * @returns A new Uint8Array containing all input bytes in order\n *\n * @example\n * ```typescript\n * import { ui8Concat } from '@atproto/lex-data'\n *\n * const a = new Uint8Array([1, 2])\n * const b = new Uint8Array([3, 4])\n * ui8Concat([a, b]) // Uint8Array([1, 2, 3, 4])\n * ```\n */\nexport const ui8Concat =\n /* v8 ignore next -- @preserve */ ui8ConcatNode ?? ui8ConcatPonyfill\n"]}
package/dist/utf8.d.ts CHANGED
@@ -1,6 +1,83 @@
1
1
  import { Base64Alphabet } from './uint8array.js';
2
+ /**
3
+ * Counts the number of grapheme clusters (user-perceived characters) in a string.
4
+ *
5
+ * Grapheme clusters represent what users typically think of as "characters",
6
+ * handling complex cases like:
7
+ * - Emoji with skin tones and ZWJ sequences (e.g., family emoji)
8
+ * - Combined characters (e.g., 'e' + combining accent)
9
+ * - Regional indicator pairs (flag emoji)
10
+ *
11
+ * Uses native {@link Intl.Segmenter} when available, falling back to a ponyfill.
12
+ *
13
+ * @param str - The string to measure
14
+ * @returns The number of grapheme clusters
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { graphemeLen } from '@atproto/lex-data'
19
+ *
20
+ * graphemeLen('hello') // 5
21
+ * graphemeLen('cafe\u0301') // 4 (cafe with combining accent)
22
+ * graphemeLen('\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}') // 1 (family emoji)
23
+ * ```
24
+ */
2
25
  export declare const graphemeLen: (str: string) => number;
26
+ /**
27
+ * Calculates the UTF-8 byte length of a string.
28
+ *
29
+ * Returns the number of bytes the string would occupy when encoded as UTF-8.
30
+ * This is important for Lexicon validation where schemas specify byte limits.
31
+ *
32
+ * Uses Node.js Buffer.byteLength when available for performance,
33
+ * falling back to a computed implementation.
34
+ *
35
+ * @param str - The string to measure
36
+ * @returns The UTF-8 byte length
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * import { utf8Len } from '@atproto/lex-data'
41
+ *
42
+ * utf8Len('hello') // 5 (ASCII: 1 byte per char)
43
+ * utf8Len('\u00e9') // 2 (e with accent: 2 bytes)
44
+ * utf8Len('\u{1F600}') // 4 (emoji: 4 bytes)
45
+ * utf8Len('\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}') // 25 (family emoji)
46
+ * ```
47
+ */
3
48
  export declare const utf8Len: (string: string) => number;
49
+ /**
50
+ * Encodes a UTF-8 string to base64.
51
+ *
52
+ * First encodes the string as UTF-8 bytes, then encodes those bytes as base64.
53
+ *
54
+ * @param str - The string to encode
55
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url')
56
+ * @returns The base64-encoded string
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * import { utf8ToBase64 } from '@atproto/lex-data'
61
+ *
62
+ * utf8ToBase64('Hello') // 'SGVsbG8='
63
+ * ```
64
+ */
4
65
  export declare const utf8ToBase64: (str: string, alphabet?: Base64Alphabet) => string;
66
+ /**
67
+ * Decodes a base64 string to UTF-8.
68
+ *
69
+ * Decodes the base64 to bytes, then interprets those bytes as UTF-8 text.
70
+ *
71
+ * @param b64 - The base64 string to decode
72
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url')
73
+ * @returns The decoded UTF-8 string
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * import { utf8FromBase64 } from '@atproto/lex-data'
78
+ *
79
+ * utf8FromBase64('SGVsbG8=') // 'Hello'
80
+ * ```
81
+ */
5
82
  export declare const utf8FromBase64: (b64: string, alphabet?: Base64Alphabet) => string;
6
83
  //# sourceMappingURL=utf8.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utf8.d.ts","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAShD,eAAO,MAAM,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MACiC,CAAA;AAU5E,eAAO,MAAM,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MACuB,CAAA;AAEjE,eAAO,MAAM,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,MACK,CAAA;AAE5E,eAAO,MAAM,cAAc,EAAE,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,MAC2E,CAAA"}
1
+ {"version":3,"file":"utf8.d.ts","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAShD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MACiC,CAAA;AAU5E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MACuB,CAAA;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,MACK,CAAA;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,EAAE,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,cAAc,KACtB,MAC2E,CAAA"}
package/dist/utf8.js CHANGED
@@ -5,6 +5,29 @@ const utf8_from_base64_js_1 = require("./utf8-from-base64.js");
5
5
  const utf8_grapheme_len_js_1 = require("./utf8-grapheme-len.js");
6
6
  const utf8_len_js_1 = require("./utf8-len.js");
7
7
  const utf8_to_base64_js_1 = require("./utf8-to-base64.js");
8
+ /**
9
+ * Counts the number of grapheme clusters (user-perceived characters) in a string.
10
+ *
11
+ * Grapheme clusters represent what users typically think of as "characters",
12
+ * handling complex cases like:
13
+ * - Emoji with skin tones and ZWJ sequences (e.g., family emoji)
14
+ * - Combined characters (e.g., 'e' + combining accent)
15
+ * - Regional indicator pairs (flag emoji)
16
+ *
17
+ * Uses native {@link Intl.Segmenter} when available, falling back to a ponyfill.
18
+ *
19
+ * @param str - The string to measure
20
+ * @returns The number of grapheme clusters
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { graphemeLen } from '@atproto/lex-data'
25
+ *
26
+ * graphemeLen('hello') // 5
27
+ * graphemeLen('cafe\u0301') // 4 (cafe with combining accent)
28
+ * graphemeLen('\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}') // 1 (family emoji)
29
+ * ```
30
+ */
8
31
  exports.graphemeLen =
9
32
  /* v8 ignore next -- @preserve */ utf8_grapheme_len_js_1.graphemeLenNative ?? utf8_grapheme_len_js_1.graphemeLenPonyfill;
10
33
  /* v8 ignore next -- @preserve */
@@ -12,10 +35,64 @@ if (exports.graphemeLen === utf8_grapheme_len_js_1.graphemeLenPonyfill) {
12
35
  /*#__PURE__*/
13
36
  console.warn('[@atproto/lex-data]: Intl.Segmenter is not available in this environment. Falling back to ponyfill implementation.');
14
37
  }
38
+ /**
39
+ * Calculates the UTF-8 byte length of a string.
40
+ *
41
+ * Returns the number of bytes the string would occupy when encoded as UTF-8.
42
+ * This is important for Lexicon validation where schemas specify byte limits.
43
+ *
44
+ * Uses Node.js Buffer.byteLength when available for performance,
45
+ * falling back to a computed implementation.
46
+ *
47
+ * @param str - The string to measure
48
+ * @returns The UTF-8 byte length
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { utf8Len } from '@atproto/lex-data'
53
+ *
54
+ * utf8Len('hello') // 5 (ASCII: 1 byte per char)
55
+ * utf8Len('\u00e9') // 2 (e with accent: 2 bytes)
56
+ * utf8Len('\u{1F600}') // 4 (emoji: 4 bytes)
57
+ * utf8Len('\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}') // 25 (family emoji)
58
+ * ```
59
+ */
15
60
  exports.utf8Len =
16
61
  /* v8 ignore next -- @preserve */ utf8_len_js_1.utf8LenNode ?? utf8_len_js_1.utf8LenCompute;
62
+ /**
63
+ * Encodes a UTF-8 string to base64.
64
+ *
65
+ * First encodes the string as UTF-8 bytes, then encodes those bytes as base64.
66
+ *
67
+ * @param str - The string to encode
68
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url')
69
+ * @returns The base64-encoded string
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { utf8ToBase64 } from '@atproto/lex-data'
74
+ *
75
+ * utf8ToBase64('Hello') // 'SGVsbG8='
76
+ * ```
77
+ */
17
78
  exports.utf8ToBase64 =
18
79
  /* v8 ignore next -- @preserve */ utf8_to_base64_js_1.utf8ToBase64Node ?? utf8_to_base64_js_1.utf8ToBase64Ponyfill;
80
+ /**
81
+ * Decodes a base64 string to UTF-8.
82
+ *
83
+ * Decodes the base64 to bytes, then interprets those bytes as UTF-8 text.
84
+ *
85
+ * @param b64 - The base64 string to decode
86
+ * @param alphabet - The base64 alphabet to use ('base64' or 'base64url')
87
+ * @returns The decoded UTF-8 string
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * import { utf8FromBase64 } from '@atproto/lex-data'
92
+ *
93
+ * utf8FromBase64('SGVsbG8=') // 'Hello'
94
+ * ```
95
+ */
19
96
  exports.utf8FromBase64 =
20
97
  /* v8 ignore next -- @preserve */ utf8_from_base64_js_1.utf8FromBase64Node ?? utf8_from_base64_js_1.utf8FromBase64Ponyfill;
21
98
  //# sourceMappingURL=utf8.js.map
package/dist/utf8.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utf8.js","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":";;;AACA,+DAG8B;AAC9B,iEAA+E;AAC/E,+CAA2D;AAC3D,2DAA4E;AAE/D,QAAA,WAAW;AACtB,iCAAiC,CAAC,wCAAiB,IAAI,0CAAmB,CAAA;AAE5E,iCAAiC;AACjC,IAAI,mBAAW,KAAK,0CAAmB,EAAE,CAAC;IACxC,aAAa;IACb,OAAO,CAAC,IAAI,CACV,oHAAoH,CACrH,CAAA;AACH,CAAC;AAEY,QAAA,OAAO;AAClB,iCAAiC,CAAC,yBAAW,IAAI,4BAAc,CAAA;AAEpD,QAAA,YAAY;AACvB,iCAAiC,CAAC,oCAAgB,IAAI,wCAAoB,CAAA;AAE/D,QAAA,cAAc;AAIzB,iCAAiC,CAAC,wCAAkB,IAAI,4CAAsB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array.js'\nimport {\n utf8FromBase64Node,\n utf8FromBase64Ponyfill,\n} from './utf8-from-base64.js'\nimport { graphemeLenNative, graphemeLenPonyfill } from './utf8-grapheme-len.js'\nimport { utf8LenCompute, utf8LenNode } from './utf8-len.js'\nimport { utf8ToBase64Node, utf8ToBase64Ponyfill } from './utf8-to-base64.js'\n\nexport const graphemeLen: (str: string) => number =\n /* v8 ignore next -- @preserve */ graphemeLenNative ?? graphemeLenPonyfill\n\n/* v8 ignore next -- @preserve */\nif (graphemeLen === graphemeLenPonyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Intl.Segmenter is not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\nexport const utf8Len: (string: string) => number =\n /* v8 ignore next -- @preserve */ utf8LenNode ?? utf8LenCompute\n\nexport const utf8ToBase64: (str: string, alphabet?: Base64Alphabet) => string =\n /* v8 ignore next -- @preserve */ utf8ToBase64Node ?? utf8ToBase64Ponyfill\n\nexport const utf8FromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ utf8FromBase64Node ?? utf8FromBase64Ponyfill\n"]}
1
+ {"version":3,"file":"utf8.js","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":";;;AACA,+DAG8B;AAC9B,iEAA+E;AAC/E,+CAA2D;AAC3D,2DAA4E;AAE5E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACU,QAAA,WAAW;AACtB,iCAAiC,CAAC,wCAAiB,IAAI,0CAAmB,CAAA;AAE5E,iCAAiC;AACjC,IAAI,mBAAW,KAAK,0CAAmB,EAAE,CAAC;IACxC,aAAa;IACb,OAAO,CAAC,IAAI,CACV,oHAAoH,CACrH,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACU,QAAA,OAAO;AAClB,iCAAiC,CAAC,yBAAW,IAAI,4BAAc,CAAA;AAEjE;;;;;;;;;;;;;;;GAeG;AACU,QAAA,YAAY;AACvB,iCAAiC,CAAC,oCAAgB,IAAI,wCAAoB,CAAA;AAE5E;;;;;;;;;;;;;;;GAeG;AACU,QAAA,cAAc;AAIzB,iCAAiC,CAAC,wCAAkB,IAAI,4CAAsB,CAAA","sourcesContent":["import { Base64Alphabet } from './uint8array.js'\nimport {\n utf8FromBase64Node,\n utf8FromBase64Ponyfill,\n} from './utf8-from-base64.js'\nimport { graphemeLenNative, graphemeLenPonyfill } from './utf8-grapheme-len.js'\nimport { utf8LenCompute, utf8LenNode } from './utf8-len.js'\nimport { utf8ToBase64Node, utf8ToBase64Ponyfill } from './utf8-to-base64.js'\n\n/**\n * Counts the number of grapheme clusters (user-perceived characters) in a string.\n *\n * Grapheme clusters represent what users typically think of as \"characters\",\n * handling complex cases like:\n * - Emoji with skin tones and ZWJ sequences (e.g., family emoji)\n * - Combined characters (e.g., 'e' + combining accent)\n * - Regional indicator pairs (flag emoji)\n *\n * Uses native {@link Intl.Segmenter} when available, falling back to a ponyfill.\n *\n * @param str - The string to measure\n * @returns The number of grapheme clusters\n *\n * @example\n * ```typescript\n * import { graphemeLen } from '@atproto/lex-data'\n *\n * graphemeLen('hello') // 5\n * graphemeLen('cafe\\u0301') // 4 (cafe with combining accent)\n * graphemeLen('\\u{1F468}\\u{200D}\\u{1F469}\\u{200D}\\u{1F467}\\u{200D}\\u{1F466}') // 1 (family emoji)\n * ```\n */\nexport const graphemeLen: (str: string) => number =\n /* v8 ignore next -- @preserve */ graphemeLenNative ?? graphemeLenPonyfill\n\n/* v8 ignore next -- @preserve */\nif (graphemeLen === graphemeLenPonyfill) {\n /*#__PURE__*/\n console.warn(\n '[@atproto/lex-data]: Intl.Segmenter is not available in this environment. Falling back to ponyfill implementation.',\n )\n}\n\n/**\n * Calculates the UTF-8 byte length of a string.\n *\n * Returns the number of bytes the string would occupy when encoded as UTF-8.\n * This is important for Lexicon validation where schemas specify byte limits.\n *\n * Uses Node.js Buffer.byteLength when available for performance,\n * falling back to a computed implementation.\n *\n * @param str - The string to measure\n * @returns The UTF-8 byte length\n *\n * @example\n * ```typescript\n * import { utf8Len } from '@atproto/lex-data'\n *\n * utf8Len('hello') // 5 (ASCII: 1 byte per char)\n * utf8Len('\\u00e9') // 2 (e with accent: 2 bytes)\n * utf8Len('\\u{1F600}') // 4 (emoji: 4 bytes)\n * utf8Len('\\u{1F468}\\u{200D}\\u{1F469}\\u{200D}\\u{1F467}\\u{200D}\\u{1F466}') // 25 (family emoji)\n * ```\n */\nexport const utf8Len: (string: string) => number =\n /* v8 ignore next -- @preserve */ utf8LenNode ?? utf8LenCompute\n\n/**\n * Encodes a UTF-8 string to base64.\n *\n * First encodes the string as UTF-8 bytes, then encodes those bytes as base64.\n *\n * @param str - The string to encode\n * @param alphabet - The base64 alphabet to use ('base64' or 'base64url')\n * @returns The base64-encoded string\n *\n * @example\n * ```typescript\n * import { utf8ToBase64 } from '@atproto/lex-data'\n *\n * utf8ToBase64('Hello') // 'SGVsbG8='\n * ```\n */\nexport const utf8ToBase64: (str: string, alphabet?: Base64Alphabet) => string =\n /* v8 ignore next -- @preserve */ utf8ToBase64Node ?? utf8ToBase64Ponyfill\n\n/**\n * Decodes a base64 string to UTF-8.\n *\n * Decodes the base64 to bytes, then interprets those bytes as UTF-8 text.\n *\n * @param b64 - The base64 string to decode\n * @param alphabet - The base64 alphabet to use ('base64' or 'base64url')\n * @returns The decoded UTF-8 string\n *\n * @example\n * ```typescript\n * import { utf8FromBase64 } from '@atproto/lex-data'\n *\n * utf8FromBase64('SGVsbG8=') // 'Hello'\n * ```\n */\nexport const utf8FromBase64: (\n b64: string,\n alphabet?: Base64Alphabet,\n) => string =\n /* v8 ignore next -- @preserve */ utf8FromBase64Node ?? utf8FromBase64Ponyfill\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-data",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "license": "MIT",
5
5
  "description": "Core utilities for AT Lexicons",
6
6
  "keywords": [
@@ -31,7 +31,7 @@
31
31
  "types": "./dist/index.d.ts",
32
32
  "browser": "./dist/index.js",
33
33
  "import": "./dist/index.js",
34
- "require": "./dist/index.js"
34
+ "default": "./dist/index.js"
35
35
  }
36
36
  },
37
37
  "dependencies": {