@transia/isomorphic 1.0.1
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 +15 -0
- package/README.md +124 -0
- package/dist/internal/normalizeInput.d.ts +9 -0
- package/dist/internal/normalizeInput.d.ts.map +1 -0
- package/dist/internal/normalizeInput.js +13 -0
- package/dist/internal/normalizeInput.js.map +1 -0
- package/dist/internal/types.d.ts +31 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +3 -0
- package/dist/internal/types.js.map +1 -0
- package/dist/internal/wrapCryptoCreateHash.d.ts +11 -0
- package/dist/internal/wrapCryptoCreateHash.d.ts.map +1 -0
- package/dist/internal/wrapCryptoCreateHash.js +32 -0
- package/dist/internal/wrapCryptoCreateHash.js.map +1 -0
- package/dist/internal/wrapNoble.d.ts +9 -0
- package/dist/internal/wrapNoble.d.ts.map +1 -0
- package/dist/internal/wrapNoble.js +31 -0
- package/dist/internal/wrapNoble.js.map +1 -0
- package/dist/ripemd160/browser.d.ts +5 -0
- package/dist/ripemd160/browser.d.ts.map +1 -0
- package/dist/ripemd160/browser.js +13 -0
- package/dist/ripemd160/browser.js.map +1 -0
- package/dist/ripemd160/index.d.ts +5 -0
- package/dist/ripemd160/index.d.ts.map +1 -0
- package/dist/ripemd160/index.js +13 -0
- package/dist/ripemd160/index.js.map +1 -0
- package/dist/sha256/browser.d.ts +5 -0
- package/dist/sha256/browser.d.ts.map +1 -0
- package/dist/sha256/browser.js +13 -0
- package/dist/sha256/browser.js.map +1 -0
- package/dist/sha256/index.d.ts +5 -0
- package/dist/sha256/index.d.ts.map +1 -0
- package/dist/sha256/index.js +13 -0
- package/dist/sha256/index.js.map +1 -0
- package/dist/sha512/browser.d.ts +5 -0
- package/dist/sha512/browser.d.ts.map +1 -0
- package/dist/sha512/browser.js +13 -0
- package/dist/sha512/browser.js.map +1 -0
- package/dist/sha512/index.d.ts +5 -0
- package/dist/sha512/index.d.ts.map +1 -0
- package/dist/sha512/index.js +13 -0
- package/dist/sha512/index.js.map +1 -0
- package/dist/utils/browser.d.ts +8 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +56 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +85 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/shared.d.ts +4 -0
- package/dist/utils/shared.d.ts.map +1 -0
- package/dist/utils/shared.js +24 -0
- package/dist/utils/shared.js.map +1 -0
- package/dist/utils/types.d.ts +34 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +3 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/ws/browser.d.ts +52 -0
- package/dist/ws/browser.d.ts.map +1 -0
- package/dist/ws/browser.js +71 -0
- package/dist/ws/browser.js.map +1 -0
- package/dist/ws/index.d.ts +6 -0
- package/dist/ws/index.d.ts.map +1 -0
- package/dist/ws/index.js +14 -0
- package/dist/ws/index.js.map +1 -0
- package/package.json +52 -0
- package/ripemd160/package.json +7 -0
- package/sha256/package.json +7 -0
- package/sha512/package.json +7 -0
- package/src/internal/normalizeInput.ts +11 -0
- package/src/internal/types.ts +33 -0
- package/src/internal/wrapCryptoCreateHash.ts +32 -0
- package/src/internal/wrapNoble.ts +28 -0
- package/src/ripemd160/browser.ts +8 -0
- package/src/ripemd160/index.ts +7 -0
- package/src/sha256/browser.ts +8 -0
- package/src/sha256/index.ts +7 -0
- package/src/sha512/browser.ts +8 -0
- package/src/sha512/index.ts +7 -0
- package/src/utils/browser.ts +54 -0
- package/src/utils/index.ts +93 -0
- package/src/utils/shared.ts +21 -0
- package/src/utils/types.ts +37 -0
- package/src/ws/browser.ts +105 -0
- package/src/ws/index.ts +10 -0
- package/utils/package.json +7 -0
- package/ws/package.json +11 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { randomBytes as cryptoRandomBytes } from 'crypto'
|
|
2
|
+
import type { BytesToHexFn, HexToBytesFn, RandomBytesFn } from './types'
|
|
3
|
+
import { HexToStringFn, StringToHexFn } from './types'
|
|
4
|
+
import { HEX_REGEX } from './shared'
|
|
5
|
+
|
|
6
|
+
const OriginalBuffer = Symbol('OriginalBuffer')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* An extended Uint8Array that incorporates a reference to the original Node.js Buffer.
|
|
10
|
+
*
|
|
11
|
+
* When converting a Node.js Buffer to a Uint8Array, there's an optimization that shares
|
|
12
|
+
* the memory of the original Buffer with the resulting Uint8Array instead of copying data.
|
|
13
|
+
* The Uint8ArrayWithReference interface is used to attach a reference to the original Buffer, ensuring
|
|
14
|
+
* its persistence in memory (preventing garbage collection) as long as the Uint8Array exists.
|
|
15
|
+
* This strategy upholds the ownership semantics of the slice of the ArrayBuffer.
|
|
16
|
+
*/
|
|
17
|
+
interface Uint8ArrayWithReference extends Uint8Array {
|
|
18
|
+
[OriginalBuffer]: Buffer
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Converts a Node.js Buffer to a Uint8Array for uniform behavior with browser implementations.
|
|
23
|
+
*
|
|
24
|
+
* Choices:
|
|
25
|
+
* 1. Directly returning the Buffer:
|
|
26
|
+
* - Operation: Return Buffer as is (a Buffer *IS* an instanceof Uint8Array).
|
|
27
|
+
* - Pros: Most memory and performance efficient.
|
|
28
|
+
* - Cons: Violates strict Uint8Array typing and may lead to issues where Buffer-specific features are [ab]used.
|
|
29
|
+
*
|
|
30
|
+
* 2. Using `new Uint8Array(buffer)` or `Uint8Array.from(buffer)`:
|
|
31
|
+
* - Operation: Copies the buffer's data into a new Uint8Array.
|
|
32
|
+
* - Pros: Ensures data isolation; memory-safe.
|
|
33
|
+
* - Cons: Less performant due to data duplication.
|
|
34
|
+
*
|
|
35
|
+
* 3. Using buf.buffer slice:
|
|
36
|
+
* - Operation: Shares memory between Buffer and Uint8Array.
|
|
37
|
+
* - Pros: Performant.
|
|
38
|
+
* - Cons: Risks with shared memory and potential for invalid references.
|
|
39
|
+
*
|
|
40
|
+
* 4. Using buf.buffer slice and keeping a Buffer reference for ownership semantics:
|
|
41
|
+
* - Operation: Shares memory and associates the original Buffer with the resulting Uint8Array.
|
|
42
|
+
* - Pros: Performant while ensuring the original Buffer isn't garbage collected.
|
|
43
|
+
* - Cons: Risks with shared memory but mitigates potential for invalid references.
|
|
44
|
+
*
|
|
45
|
+
* The chosen method (4) prioritizes performance by sharing memory while ensuring buffer ownership.
|
|
46
|
+
*
|
|
47
|
+
* @param {Buffer} buffer - The Node.js Buffer to convert.
|
|
48
|
+
* @returns {Uint8Array} Resulting Uint8Array sharing the same memory as the Buffer and maintaining a reference to it.
|
|
49
|
+
*/
|
|
50
|
+
function toUint8Array(buffer: Buffer): Uint8Array {
|
|
51
|
+
const u8Array = new Uint8Array(
|
|
52
|
+
buffer.buffer.slice(
|
|
53
|
+
buffer.byteOffset,
|
|
54
|
+
buffer.byteOffset + buffer.byteLength,
|
|
55
|
+
),
|
|
56
|
+
) as Uint8ArrayWithReference
|
|
57
|
+
u8Array[OriginalBuffer] = buffer
|
|
58
|
+
return u8Array
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* eslint-disable func-style -- Typed to ensure uniformity between node and browser implementations and docs */
|
|
62
|
+
export const bytesToHex: typeof BytesToHexFn = (bytes) => {
|
|
63
|
+
const buf = Buffer.from(bytes)
|
|
64
|
+
return buf.toString('hex').toUpperCase()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const hexToBytes: typeof HexToBytesFn = (hex) => {
|
|
68
|
+
if (!HEX_REGEX.test(hex)) {
|
|
69
|
+
throw new Error('Invalid hex string')
|
|
70
|
+
}
|
|
71
|
+
return toUint8Array(Buffer.from(hex, 'hex'))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const randomBytes: typeof RandomBytesFn = (size) => {
|
|
75
|
+
return toUint8Array(cryptoRandomBytes(size))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const hexToString: typeof HexToStringFn = (
|
|
79
|
+
hex: string,
|
|
80
|
+
encoding = 'utf8',
|
|
81
|
+
): string => {
|
|
82
|
+
if (!HEX_REGEX.test(hex)) {
|
|
83
|
+
throw new Error('Invalid hex string')
|
|
84
|
+
}
|
|
85
|
+
return new TextDecoder(encoding).decode(hexToBytes(hex))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const stringToHex: typeof StringToHexFn = (string: string): string => {
|
|
89
|
+
return bytesToHex(new TextEncoder().encode(string))
|
|
90
|
+
}
|
|
91
|
+
/* eslint-enable func-style */
|
|
92
|
+
|
|
93
|
+
export * from './shared'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { concatBytes } from '@noble/hashes/utils'
|
|
2
|
+
|
|
3
|
+
export const HEX_REGEX = /^[A-F0-9]*$/iu
|
|
4
|
+
|
|
5
|
+
export function concat(views: Uint8Array[]): Uint8Array {
|
|
6
|
+
return concatBytes(...views)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function equal(buf1: Uint8Array, buf2: Uint8Array): boolean {
|
|
10
|
+
if (buf1.byteLength !== buf2.byteLength) {
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
const dv1 = new Int8Array(buf1)
|
|
14
|
+
const dv2 = new Int8Array(buf2)
|
|
15
|
+
for (let i = 0; i !== buf1.byteLength; i++) {
|
|
16
|
+
if (dv1[i] !== dv2[i]) {
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return true
|
|
21
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a UInt8Array to hex. The returned hex will be in all caps.
|
|
3
|
+
*
|
|
4
|
+
* @param bytes - {Uint8Array} to convert to hex
|
|
5
|
+
*/
|
|
6
|
+
export declare function BytesToHexFn(bytes: Uint8Array | number[]): string
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Convert hex to a Uint8Array.
|
|
10
|
+
*
|
|
11
|
+
* @param hex - {string} to convert to a Uint8Array
|
|
12
|
+
*/
|
|
13
|
+
export declare function HexToBytesFn(hex: string): Uint8Array
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create a Uint8Array of the supplied size.
|
|
17
|
+
*
|
|
18
|
+
* @param size - number of bytes to generate
|
|
19
|
+
*/
|
|
20
|
+
export declare function RandomBytesFn(size: number): Uint8Array
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Converts hex to its string equivalent. Useful to read the Domain field and some Memos.
|
|
24
|
+
*
|
|
25
|
+
* @param hex - The hex to convert to a string.
|
|
26
|
+
* @param encoding - The encoding to use. Defaults to 'utf8' (UTF-8). 'ascii' is also allowed.
|
|
27
|
+
* @returns The converted string.
|
|
28
|
+
*/
|
|
29
|
+
export declare function HexToStringFn(hex: string, encoding?: string): string
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Converts a utf-8 to its hex equivalent. Useful for Memos.
|
|
33
|
+
*
|
|
34
|
+
* @param string - The string to convert to Hex.
|
|
35
|
+
* @returns The Hex equivalent of the string.
|
|
36
|
+
*/
|
|
37
|
+
export declare function StringToHexFn(string: string): string
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/* eslint-disable max-classes-per-file -- Needs to be a wrapper for ws */
|
|
2
|
+
import { EventEmitter } from 'eventemitter3'
|
|
3
|
+
|
|
4
|
+
// Define the global WebSocket class found on the native browser
|
|
5
|
+
declare class WebSocket {
|
|
6
|
+
public onclose?: (closeEvent: CloseEvent) => void
|
|
7
|
+
public onopen?: (openEvent: Event) => void
|
|
8
|
+
public onerror?: (error: Error) => void
|
|
9
|
+
public onmessage?: (message: MessageEvent) => void
|
|
10
|
+
public readyState: number
|
|
11
|
+
public constructor(url: string)
|
|
12
|
+
public close(code?: number, reason?: Uint8Array): void
|
|
13
|
+
public send(message: string): void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface WSWrapperOptions {
|
|
17
|
+
perMessageDeflate: boolean
|
|
18
|
+
handshakeTimeout: number
|
|
19
|
+
protocolVersion: number
|
|
20
|
+
origin: string
|
|
21
|
+
maxPayload: number
|
|
22
|
+
followRedirects: boolean
|
|
23
|
+
maxRedirects: number
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Provides `EventEmitter` interface for native browser `WebSocket`,
|
|
28
|
+
* same, as `ws` package provides.
|
|
29
|
+
*/
|
|
30
|
+
export default class WSWrapper extends EventEmitter {
|
|
31
|
+
public static CONNECTING = 0
|
|
32
|
+
public static OPEN = 1
|
|
33
|
+
public static CLOSING = 2
|
|
34
|
+
|
|
35
|
+
public static CLOSED = 3
|
|
36
|
+
private readonly ws: WebSocket
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Constructs a browser-safe websocket.
|
|
40
|
+
*
|
|
41
|
+
* @param url - URL to connect to.
|
|
42
|
+
* @param _protocols - Not used.
|
|
43
|
+
* @param _websocketOptions - Not used.
|
|
44
|
+
*/
|
|
45
|
+
public constructor(
|
|
46
|
+
url: string,
|
|
47
|
+
_protocols: string | string[] | WSWrapperOptions | undefined,
|
|
48
|
+
_websocketOptions: WSWrapperOptions,
|
|
49
|
+
) {
|
|
50
|
+
super()
|
|
51
|
+
|
|
52
|
+
this.ws = new WebSocket(url)
|
|
53
|
+
|
|
54
|
+
this.ws.onclose = (closeEvent: CloseEvent): void => {
|
|
55
|
+
let reason: Uint8Array | undefined
|
|
56
|
+
if (closeEvent.reason) {
|
|
57
|
+
const enc = new TextEncoder()
|
|
58
|
+
reason = enc.encode(closeEvent.reason)
|
|
59
|
+
}
|
|
60
|
+
this.emit('close', closeEvent.code, reason)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.ws.onopen = (): void => {
|
|
64
|
+
this.emit('open')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.ws.onerror = (error): void => {
|
|
68
|
+
this.emit('error', error)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.ws.onmessage = (message: MessageEvent): void => {
|
|
72
|
+
this.emit('message', message.data)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get the ready state of the websocket.
|
|
78
|
+
*
|
|
79
|
+
* @returns The Websocket's ready state.
|
|
80
|
+
*/
|
|
81
|
+
public get readyState(): number {
|
|
82
|
+
return this.ws.readyState
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Closes the websocket.
|
|
87
|
+
*
|
|
88
|
+
* @param code - Close code.
|
|
89
|
+
* @param reason - Close reason.
|
|
90
|
+
*/
|
|
91
|
+
public close(code?: number, reason?: Buffer): void {
|
|
92
|
+
if (this.readyState === 1) {
|
|
93
|
+
this.ws.close(code, reason)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sends a message over the Websocket connection.
|
|
99
|
+
*
|
|
100
|
+
* @param message - Message to send.
|
|
101
|
+
*/
|
|
102
|
+
public send(message: string): void {
|
|
103
|
+
this.ws.send(message)
|
|
104
|
+
}
|
|
105
|
+
}
|
package/src/ws/index.ts
ADDED