a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(multibase): move base64 web native/polyfill into its own file

Mary 33455f07 9870d552

+153 -165
+39
packages/utilities/multibase/lib/bases/base64-web-native.ts
··· 1 + // #region base64 2 + export const fromBase64 = (str: string): Uint8Array => { 3 + return Uint8Array.fromBase64(str, { alphabet: 'base64', lastChunkHandling: 'loose' }); 4 + }; 5 + 6 + export const toBase64 = (bytes: Uint8Array): string => { 7 + return bytes.toBase64({ alphabet: 'base64', omitPadding: true }); 8 + }; 9 + // #endregion 10 + 11 + // #region base64pad 12 + export const fromBase64Pad = (str: string): Uint8Array => { 13 + return Uint8Array.fromBase64(str, { alphabet: 'base64', lastChunkHandling: 'strict' }); 14 + }; 15 + 16 + export const toBase64Pad = (bytes: Uint8Array): string => { 17 + return bytes.toBase64({ alphabet: 'base64', omitPadding: false }); 18 + }; 19 + // #endregion 20 + 21 + // #region base64url 22 + export const fromBase64Url = (str: string): Uint8Array => { 23 + return Uint8Array.fromBase64(str, { alphabet: 'base64url', lastChunkHandling: 'loose' }); 24 + }; 25 + 26 + export const toBase64Url = (bytes: Uint8Array): string => { 27 + return bytes.toBase64({ alphabet: 'base64url', omitPadding: true }); 28 + }; 29 + // #endregion 30 + 31 + // #region base64urlpad 32 + export const fromBase64UrlPad = (str: string): Uint8Array => { 33 + return Uint8Array.fromBase64(str, { alphabet: 'base64url', lastChunkHandling: 'strict' }); 34 + }; 35 + 36 + export const toBase64UrlPad = (bytes: Uint8Array): string => { 37 + return bytes.toBase64({ alphabet: 'base64url', omitPadding: false }); 38 + }; 39 + // #endregion
+24
packages/utilities/multibase/lib/bases/base64-web-polyfill.ts
··· 1 + import { createRfc4648Decode, createRfc4648Encode } from '../utils.js'; 2 + 3 + const BASE64_CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 4 + const BASE64URL_CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; 5 + 6 + // #region base64 7 + export const fromBase64 = /*#__PURE__*/ createRfc4648Decode(BASE64_CHARSET, 6, false); 8 + export const toBase64 = /*#__PURE__*/ createRfc4648Encode(BASE64_CHARSET, 6, false); 9 + // #endregion 10 + 11 + // #region base64pad 12 + export const fromBase64Pad = /*#__PURE__*/ createRfc4648Decode(BASE64_CHARSET, 6, true); 13 + export const toBase64Pad = /*#__PURE__*/ createRfc4648Encode(BASE64_CHARSET, 6, true); 14 + // #endregion 15 + 16 + // #region base64url 17 + export const fromBase64Url = /*#__PURE__*/ createRfc4648Decode(BASE64URL_CHARSET, 6, false); 18 + export const toBase64Url = /*#__PURE__*/ createRfc4648Encode(BASE64URL_CHARSET, 6, false); 19 + // #endregion 20 + 21 + // #region base64urlpad 22 + export const fromBase64UrlPad = /*#__PURE__*/ createRfc4648Decode(BASE64URL_CHARSET, 6, true); 23 + export const toBase64UrlPad = /*#__PURE__*/ createRfc4648Encode(BASE64URL_CHARSET, 6, true); 24 + // #endregion
+29 -79
packages/utilities/multibase/lib/bases/base64-web.ts
··· 1 - import { createRfc4648Decode, createRfc4648Encode } from '../utils.js'; 1 + import { 2 + fromBase64 as fromBase64Native, 3 + fromBase64Pad as fromBase64PadNative, 4 + fromBase64Url as fromBase64UrlNative, 5 + fromBase64UrlPad as fromBase64UrlPadNative, 6 + toBase64 as toBase64Native, 7 + toBase64Pad as toBase64PadNative, 8 + toBase64Url as toBase64UrlNative, 9 + toBase64UrlPad as toBase64UrlPadNative, 10 + } from './base64-web-native.js'; 11 + import { 12 + fromBase64Pad as fromBase64PadPolyfill, 13 + fromBase64 as fromBase64Polyfill, 14 + fromBase64UrlPad as fromBase64UrlPadPolyfill, 15 + fromBase64Url as fromBase64UrlPolyfill, 16 + toBase64Pad as toBase64PadPolyfill, 17 + toBase64 as toBase64Polyfill, 18 + toBase64UrlPad as toBase64UrlPadPolyfill, 19 + toBase64Url as toBase64UrlPolyfill, 20 + } from './base64-web-polyfill.js'; 2 21 3 - const HAS_UINT8_BASE64_SUPPORT = 'fromBase64' in Uint8Array; 4 - 5 - const BASE64_CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 6 - const BASE64URL_CHARSET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; 22 + const HAS_NATIVE_SUPPORT = 'fromBase64' in Uint8Array; 7 23 8 24 // #region base64 9 - /** @internal */ 10 - export const _fromBase64Polyfill = /*#__PURE__*/ createRfc4648Decode(BASE64_CHARSET, 6, false); 11 - /** @internal */ 12 - export const _toBase64Polyfill = /*#__PURE__*/ createRfc4648Encode(BASE64_CHARSET, 6, false); 13 - 14 - /** @internal */ 15 - export const _fromBase64Native = (str: string): Uint8Array => { 16 - return Uint8Array.fromBase64(str, { alphabet: 'base64', lastChunkHandling: 'loose' }); 17 - }; 18 - 19 - /** @internal */ 20 - export const _toBase64Native = (bytes: Uint8Array): string => { 21 - return bytes.toBase64({ alphabet: 'base64', omitPadding: true }); 22 - }; 23 - 24 - export const fromBase64 = !HAS_UINT8_BASE64_SUPPORT ? _fromBase64Polyfill : _fromBase64Native; 25 - 26 - export const toBase64 = !HAS_UINT8_BASE64_SUPPORT ? _toBase64Polyfill : _toBase64Native; 25 + export const fromBase64 = !HAS_NATIVE_SUPPORT ? fromBase64Polyfill : fromBase64Native; 26 + export const toBase64 = !HAS_NATIVE_SUPPORT ? toBase64Polyfill : toBase64Native; 27 27 // #endregion 28 28 29 29 // #region base64pad 30 - /** @internal */ 31 - export const _fromBase64PadPolyfill = /*#__PURE__*/ createRfc4648Decode(BASE64_CHARSET, 6, true); 32 - /** @internal */ 33 - export const _toBase64PadPolyfill = /*#__PURE__*/ createRfc4648Encode(BASE64_CHARSET, 6, true); 34 - 35 - /** @internal */ 36 - export const _fromBase64PadNative = (str: string): Uint8Array => { 37 - return Uint8Array.fromBase64(str, { alphabet: 'base64', lastChunkHandling: 'strict' }); 38 - }; 39 - 40 - /** @internal */ 41 - export const _toBase64PadNative = (bytes: Uint8Array): string => { 42 - return bytes.toBase64({ alphabet: 'base64', omitPadding: false }); 43 - }; 44 - 45 - export const fromBase64Pad = !HAS_UINT8_BASE64_SUPPORT ? _fromBase64PadPolyfill : _fromBase64PadNative; 46 - 47 - export const toBase64Pad = !HAS_UINT8_BASE64_SUPPORT ? _toBase64PadPolyfill : _toBase64PadNative; 30 + export const fromBase64Pad = !HAS_NATIVE_SUPPORT ? fromBase64PadPolyfill : fromBase64PadNative; 31 + export const toBase64Pad = !HAS_NATIVE_SUPPORT ? toBase64PadPolyfill : toBase64PadNative; 48 32 // #endregion 49 33 50 34 // #region base64url 51 - /** @internal */ 52 - export const _fromBase64UrlPolyfill = /*#__PURE__*/ createRfc4648Decode(BASE64URL_CHARSET, 6, false); 53 - /** @internal */ 54 - export const _toBase64UrlPolyfill = /*#__PURE__*/ createRfc4648Encode(BASE64URL_CHARSET, 6, false); 55 - 56 - /** @internal */ 57 - export const _fromBase64UrlNative = (str: string): Uint8Array => { 58 - return Uint8Array.fromBase64(str, { alphabet: 'base64url', lastChunkHandling: 'loose' }); 59 - }; 60 - 61 - /** @internal */ 62 - export const _toBase64UrlNative = (bytes: Uint8Array): string => { 63 - return bytes.toBase64({ alphabet: 'base64url', omitPadding: true }); 64 - }; 65 - 66 - export const fromBase64Url = !HAS_UINT8_BASE64_SUPPORT ? _fromBase64UrlPolyfill : _fromBase64UrlNative; 67 - 68 - export const toBase64Url = !HAS_UINT8_BASE64_SUPPORT ? _toBase64UrlPolyfill : _toBase64UrlNative; 35 + export const fromBase64Url = !HAS_NATIVE_SUPPORT ? fromBase64UrlPolyfill : fromBase64UrlNative; 36 + export const toBase64Url = !HAS_NATIVE_SUPPORT ? toBase64UrlPolyfill : toBase64UrlNative; 69 37 // #endregion 70 38 71 39 // #region base64urlpad 72 - /** @internal */ 73 - export const _fromBase64UrlPadPolyfill = /*#__PURE__*/ createRfc4648Decode(BASE64URL_CHARSET, 6, true); 74 - /** @internal */ 75 - export const _toBase64UrlPadPolyfill = /*#__PURE__*/ createRfc4648Encode(BASE64URL_CHARSET, 6, true); 76 - 77 - /** @internal */ 78 - export const _fromBase64UrlPadNative = (str: string): Uint8Array => { 79 - return Uint8Array.fromBase64(str, { alphabet: 'base64url', lastChunkHandling: 'strict' }); 80 - }; 81 - 82 - /** @internal */ 83 - export const _toBase64UrlPadNative = (bytes: Uint8Array): string => { 84 - return bytes.toBase64({ alphabet: 'base64url', omitPadding: false }); 85 - }; 86 - 87 - export const fromBase64UrlPad = !HAS_UINT8_BASE64_SUPPORT 88 - ? _fromBase64UrlPadPolyfill 89 - : _fromBase64UrlPadNative; 90 - 91 - export const toBase64UrlPad = !HAS_UINT8_BASE64_SUPPORT ? _toBase64UrlPadPolyfill : _toBase64UrlPadNative; 40 + export const fromBase64UrlPad = !HAS_NATIVE_SUPPORT ? fromBase64UrlPadPolyfill : fromBase64UrlPadNative; 41 + export const toBase64UrlPad = !HAS_NATIVE_SUPPORT ? toBase64UrlPadPolyfill : toBase64UrlPadNative; 92 42 // #endregion
+9 -8
packages/utilities/multibase/lib/bases/base64.bench.ts
··· 1 1 import { bench, do_not_optimize, run, summary } from 'mitata'; 2 2 3 - import { fromBase64 as _fromBase64Node, toBase64 as _toBase64Node } from './base64-node.js'; 4 - import { _fromBase64Native, _fromBase64Polyfill, _toBase64Native, _toBase64Polyfill } from './base64-web.js'; 3 + import { fromBase64 as fromBase64Node, toBase64 as toBase64Node } from './base64-node.js'; 4 + import { fromBase64 as fromBase64Native, toBase64 as toBase64Native } from './base64-web-native.js'; 5 + import { fromBase64 as fromBase64Polyfill, toBase64 as toBase64Polyfill } from './base64-web-polyfill.js'; 5 6 6 7 summary(() => { 7 8 bench('Uint8Array.fromBase64', () => { 8 - return do_not_optimize(_fromBase64Native('RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmch')); 9 + return do_not_optimize(fromBase64Native('RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmch')); 9 10 }); 10 11 11 12 bench('Node.js Buffer#from', () => { 12 - return do_not_optimize(_fromBase64Node('RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmch')); 13 + return do_not_optimize(fromBase64Node('RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmch')); 13 14 }); 14 15 15 16 bench('fromBase64 polyfill', () => { 16 - return do_not_optimize(_fromBase64Polyfill('RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmch')); 17 + return do_not_optimize(fromBase64Polyfill('RGVjZW50cmFsaXplIGV2ZXJ5dGhpbmch')); 17 18 }); 18 19 }); 19 20 ··· 27 28 ]); 28 29 }, 29 30 bench(bytes: Uint8Array) { 30 - return do_not_optimize(_toBase64Native(bytes)); 31 + return do_not_optimize(toBase64Native(bytes)); 31 32 }, 32 33 }; 33 34 }); ··· 41 42 ]); 42 43 }, 43 44 bench(bytes: Uint8Array) { 44 - return do_not_optimize(_toBase64Node(bytes)); 45 + return do_not_optimize(toBase64Node(bytes)); 45 46 }, 46 47 }; 47 48 }); ··· 55 56 ]); 56 57 }, 57 58 bench(bytes: Uint8Array) { 58 - return do_not_optimize(_toBase64Polyfill(bytes)); 59 + return do_not_optimize(toBase64Polyfill(bytes)); 59 60 }, 60 61 }; 61 62 });
+52 -78
packages/utilities/multibase/lib/bases/base64.test.ts
··· 1 - import { describe, expect, it, mock } from 'bun:test'; 1 + import { expect, it, mock } from 'bun:test'; 2 2 3 3 import { 4 - fromBase64 as _fromBase64Node, 5 - fromBase64Pad as _fromBase64PadNode, 6 - fromBase64Url as _fromBase64UrlNode, 7 - fromBase64UrlPad as _fromBase64UrlPadNode, 8 - toBase64 as _toBase64Node, 9 - toBase64Pad as _toBase64PadNode, 10 - toBase64Url as _toBase64UrlNode, 11 - toBase64UrlPad as _toBase64UrlPadNode, 4 + fromBase64 as fromBase64Node, 5 + fromBase64Pad as fromBase64PadNode, 6 + fromBase64Url as fromBase64UrlNode, 7 + fromBase64UrlPad as fromBase64UrlPadNode, 8 + toBase64 as toBase64Node, 9 + toBase64Pad as toBase64PadNode, 10 + toBase64Url as toBase64UrlNode, 11 + toBase64UrlPad as toBase64UrlPadNode, 12 12 } from './base64-node.js'; 13 13 import { 14 - _fromBase64Native, 15 - _fromBase64PadNative, 16 - _fromBase64PadPolyfill, 17 - _fromBase64Polyfill, 18 - _fromBase64UrlNative, 19 - _fromBase64UrlPadNative, 20 - _fromBase64UrlPadPolyfill, 21 - _fromBase64UrlPolyfill, 22 - _toBase64Native, 23 - _toBase64PadNative, 24 - _toBase64PadPolyfill, 25 - _toBase64Polyfill, 26 - _toBase64UrlNative, 27 - _toBase64UrlPadNative, 28 - _toBase64UrlPadPolyfill, 29 - _toBase64UrlPolyfill, 30 - } from './base64-web.js'; 14 + fromBase64 as fromBase64Native, 15 + fromBase64Pad as fromBase64PadNative, 16 + fromBase64Url as fromBase64UrlNative, 17 + fromBase64UrlPad as fromBase64UrlPadNative, 18 + toBase64 as toBase64Native, 19 + toBase64Pad as toBase64PadNative, 20 + toBase64Url as toBase64UrlNative, 21 + toBase64UrlPad as toBase64UrlPadNative, 22 + } from './base64-web-native.js'; 23 + import { 24 + fromBase64Pad as fromBase64PadPolyfill, 25 + fromBase64 as fromBase64Polyfill, 26 + fromBase64UrlPad as fromBase64UrlPadPolyfill, 27 + fromBase64Url as fromBase64UrlPolyfill, 28 + toBase64Pad as toBase64PadPolyfill, 29 + toBase64 as toBase64Polyfill, 30 + toBase64UrlPad as toBase64UrlPadPolyfill, 31 + toBase64Url as toBase64UrlPolyfill, 32 + } from './base64-web-polyfill.js'; 31 33 32 34 const inputs = [ 33 35 { ··· 49 51 50 52 it('can encode', () => { 51 53 for (const input of inputs) { 52 - expect(_toBase64Polyfill(input.buffer)).toEqual(input.base64); 53 - expect(_toBase64Node(input.buffer)).toEqual(input.base64); 54 - expect(_toBase64Native(input.buffer)).toEqual(input.base64); 54 + expect(toBase64Polyfill(input.buffer)).toEqual(input.base64); 55 + expect(toBase64Node(input.buffer)).toEqual(input.base64); 56 + expect(toBase64Native(input.buffer)).toEqual(input.base64); 55 57 56 - expect(_toBase64PadPolyfill(input.buffer)).toEqual(input.base64pad); 57 - expect(_toBase64PadNode(input.buffer)).toEqual(input.base64pad); 58 - expect(_toBase64PadNative(input.buffer)).toEqual(input.base64pad); 58 + expect(toBase64PadPolyfill(input.buffer)).toEqual(input.base64pad); 59 + expect(toBase64PadNode(input.buffer)).toEqual(input.base64pad); 60 + expect(toBase64PadNative(input.buffer)).toEqual(input.base64pad); 59 61 60 - expect(_toBase64UrlPolyfill(input.buffer)).toEqual(input.base64url); 61 - expect(_toBase64UrlNode(input.buffer)).toEqual(input.base64url); 62 - expect(_toBase64UrlNative(input.buffer)).toEqual(input.base64url); 62 + expect(toBase64UrlPolyfill(input.buffer)).toEqual(input.base64url); 63 + expect(toBase64UrlNode(input.buffer)).toEqual(input.base64url); 64 + expect(toBase64UrlNative(input.buffer)).toEqual(input.base64url); 63 65 64 - expect(_toBase64UrlPadPolyfill(input.buffer)).toEqual(input.base64urlpad); 65 - expect(_toBase64UrlPadNode(input.buffer)).toEqual(input.base64urlpad); 66 - expect(_toBase64UrlPadNative(input.buffer)).toEqual(input.base64urlpad); 66 + expect(toBase64UrlPadPolyfill(input.buffer)).toEqual(input.base64urlpad); 67 + expect(toBase64UrlPadNode(input.buffer)).toEqual(input.base64urlpad); 68 + expect(toBase64UrlPadNative(input.buffer)).toEqual(input.base64urlpad); 67 69 } 68 70 }); 69 71 70 72 it('can decode', () => { 71 73 for (const input of inputs) { 72 - expect(_fromBase64Polyfill(input.base64)).toEqual(input.buffer); 73 - expect(_fromBase64Node(input.base64)).toEqual(input.buffer); 74 - expect(_fromBase64Native(input.base64)).toEqual(input.buffer); 74 + expect(fromBase64Polyfill(input.base64)).toEqual(input.buffer); 75 + expect(fromBase64Node(input.base64)).toEqual(input.buffer); 76 + expect(fromBase64Native(input.base64)).toEqual(input.buffer); 75 77 76 - expect(_fromBase64PadPolyfill(input.base64pad)).toEqual(input.buffer); 77 - expect(_fromBase64PadNode(input.base64pad)).toEqual(input.buffer); 78 - expect(_fromBase64PadNative(input.base64pad)).toEqual(input.buffer); 78 + expect(fromBase64PadPolyfill(input.base64pad)).toEqual(input.buffer); 79 + expect(fromBase64PadNode(input.base64pad)).toEqual(input.buffer); 80 + expect(fromBase64PadNative(input.base64pad)).toEqual(input.buffer); 79 81 80 - expect(_fromBase64UrlPolyfill(input.base64url)).toEqual(input.buffer); 81 - expect(_fromBase64UrlNode(input.base64url)).toEqual(input.buffer); 82 - expect(_fromBase64UrlNative(input.base64url)).toEqual(input.buffer); 82 + expect(fromBase64UrlPolyfill(input.base64url)).toEqual(input.buffer); 83 + expect(fromBase64UrlNode(input.base64url)).toEqual(input.buffer); 84 + expect(fromBase64UrlNative(input.base64url)).toEqual(input.buffer); 83 85 84 - expect(_fromBase64UrlPadPolyfill(input.base64urlpad)).toEqual(input.buffer); 85 - expect(_fromBase64UrlPadNode(input.base64urlpad)).toEqual(input.buffer); 86 - expect(_fromBase64UrlPadNative(input.base64urlpad)).toEqual(input.buffer); 86 + expect(fromBase64UrlPadPolyfill(input.base64urlpad)).toEqual(input.buffer); 87 + expect(fromBase64UrlPadNode(input.base64urlpad)).toEqual(input.buffer); 88 + expect(fromBase64UrlPadNative(input.base64urlpad)).toEqual(input.buffer); 87 89 } 88 90 }); 89 - 90 - describe('nopad', () => { 91 - it('throws on padding', () => { 92 - for (const input of inputs) { 93 - expect(() => _fromBase64Polyfill(input.base64pad)).toThrowError(); 94 - expect(() => _fromBase64Node(input.base64pad)).toThrowError(); 95 - expect(() => _fromBase64Native(input.base64pad)).toThrowError(); 96 - 97 - expect(() => _fromBase64UrlPolyfill(input.base64urlpad)).toThrowError(); 98 - expect(() => _fromBase64UrlNode(input.base64urlpad)).toThrowError(); 99 - expect(() => _fromBase64UrlNative(input.base64urlpad)).toThrowError(); 100 - } 101 - }); 102 - }); 103 - 104 - describe('pad', () => { 105 - it('throws on no padding', () => { 106 - for (const input of inputs) { 107 - // expect(() => _fromBase64PadPolyfill(input.base64)).toThrowError(); 108 - expect(() => _fromBase64PadNode(input.base64)).toThrowError(); 109 - expect(() => _fromBase64PadNative(input.base64)).toThrowError(); 110 - 111 - // expect(() => _fromBase64UrlPadPolyfill(input.base64url)).toThrowError(); 112 - expect(() => _fromBase64UrlPadNode(input.base64url)).toThrowError(); 113 - expect(() => _fromBase64UrlPadNative(input.base64url)).toThrowError(); 114 - } 115 - }); 116 - });