@wener/utils 1.1.49 → 1.1.50

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.
Files changed (145) hide show
  1. package/lib/arrays/MaybeArray.js.map +1 -1
  2. package/lib/arrays/arrayFromAsync.js.map +1 -1
  3. package/lib/asyncs/AsyncInterval.js.map +1 -1
  4. package/lib/asyncs/MaybePromise.js.map +1 -1
  5. package/lib/asyncs/Promises.js.map +1 -1
  6. package/lib/asyncs/createAsyncIterator.js.map +1 -1
  7. package/lib/asyncs/createLazyPromise.js.map +1 -1
  8. package/lib/asyncs/firstOfAsyncIterator.js.map +1 -1
  9. package/lib/asyncs/generatorOfStream.js.map +1 -1
  10. package/lib/asyncs/isIterator.js.map +1 -1
  11. package/lib/asyncs/isPromise.js.map +1 -1
  12. package/lib/asyncs/isThenable.js.map +1 -1
  13. package/lib/asyncs/nextOfAsyncIterator.js.map +1 -1
  14. package/lib/asyncs/promiseOfCallback.js.map +1 -1
  15. package/lib/asyncs/timeout.js.map +1 -1
  16. package/lib/browsers/copy.js.map +1 -1
  17. package/lib/browsers/download.js.map +1 -1
  18. package/lib/browsers/getFileFromDataTransfer.js.map +1 -1
  19. package/lib/browsers/loaders.js.map +1 -1
  20. package/lib/cn/division/DivisionCode.js.map +1 -1
  21. package/lib/cn/division/binarySearch.js.map +1 -1
  22. package/lib/cn/formatChineseAmount.js.map +1 -1
  23. package/lib/cn/id/Mod11.js.map +1 -1
  24. package/lib/cn/id/ResidentIdNumber.js.map +1 -1
  25. package/lib/cn/id/types.js.map +1 -1
  26. package/lib/cn/index.js.map +1 -1
  27. package/lib/cn/parseChineseNumber.js.map +1 -1
  28. package/lib/cn/pinyin/cartesianProduct.js.map +1 -1
  29. package/lib/cn/pinyin/loader.js.map +1 -1
  30. package/lib/cn/pinyin/preload.js.map +1 -1
  31. package/lib/cn/pinyin/toPinyinPure.js.map +1 -1
  32. package/lib/cn/pinyin/transform.js.map +1 -1
  33. package/lib/cn/types.js.map +1 -1
  34. package/lib/cn/uscc/Mod31.js.map +1 -1
  35. package/lib/cn/uscc/USCC.js.map +1 -1
  36. package/lib/cn/uscc/isUSCC.js.map +1 -1
  37. package/lib/crypto/base.js.map +1 -1
  38. package/lib/crypto/getNodeCrypto.js.map +1 -1
  39. package/lib/crypto/getRandomValues.js.map +1 -1
  40. package/lib/crypto/hashing.js.map +1 -1
  41. package/lib/crypto/md5.bench.js.map +1 -1
  42. package/lib/crypto/md5.d.js.map +1 -1
  43. package/lib/crypto/md5.js.map +1 -1
  44. package/lib/crypto/pem/pem.js.map +1 -1
  45. package/lib/crypto/randomUUID.js.map +1 -1
  46. package/lib/crypto/randomUUIDv7.js.map +1 -1
  47. package/lib/crypto/ulid.js.map +1 -1
  48. package/lib/emitter/types.js.map +1 -1
  49. package/lib/errors/Errors.js +38 -17
  50. package/lib/errors/Errors.js.map +1 -1
  51. package/lib/fetch/HttpStatus.js.map +1 -1
  52. package/lib/fetch/createFetchWith.js.map +1 -1
  53. package/lib/fetch/createFetchWithLogging.js.map +1 -1
  54. package/lib/fetch/createFetchWithRetry.js.map +1 -1
  55. package/lib/fetch/dumpRequest.js.map +1 -1
  56. package/lib/fetch/dumpResponse.js.map +1 -1
  57. package/lib/fetch/http.types.js.map +1 -1
  58. package/lib/fetch/index.js.map +1 -1
  59. package/lib/fetch/types.js.map +1 -1
  60. package/lib/i18n/createTranslate.js.map +1 -1
  61. package/lib/index.js.map +1 -1
  62. package/lib/io/AbstractEncoding.js.map +1 -1
  63. package/lib/io/ArrayBuffer.test-d.js.map +1 -1
  64. package/lib/io/ArrayBuffers.js +217 -173
  65. package/lib/io/ArrayBuffers.js.map +1 -1
  66. package/lib/io/Buffer.js.map +1 -1
  67. package/lib/io/ByteBuffer.js.map +1 -1
  68. package/lib/io/base64.js +2 -2
  69. package/lib/io/base64.js.map +1 -1
  70. package/lib/io/dump.js.map +1 -1
  71. package/lib/io/isBuffer.js.map +1 -1
  72. package/lib/io/isTransferable.js.map +1 -1
  73. package/lib/io/parseDataUri.js.map +1 -1
  74. package/lib/langs/MaybeFunction.js.map +1 -1
  75. package/lib/langs/classOf.js.map +1 -1
  76. package/lib/langs/deepEqual.js.map +1 -1
  77. package/lib/langs/deepFreeze.js.map +1 -1
  78. package/lib/langs/getGlobalStates.js.map +1 -1
  79. package/lib/langs/getObjectId.js +1 -1
  80. package/lib/langs/getObjectId.js.map +1 -1
  81. package/lib/langs/isClass.js.map +1 -1
  82. package/lib/langs/isDefined.js.map +1 -1
  83. package/lib/langs/isEmptyObject.js.map +1 -1
  84. package/lib/langs/isFunction.js.map +1 -1
  85. package/lib/langs/isNullish.js.map +1 -1
  86. package/lib/langs/isPlainObject.js.map +1 -1
  87. package/lib/langs/memoize.js.map +1 -1
  88. package/lib/langs/mixin.js.map +1 -1
  89. package/lib/langs/parseBoolean.js.map +1 -1
  90. package/lib/langs/shallowClone.js.map +1 -1
  91. package/lib/langs/shallowEqual.js.map +1 -1
  92. package/lib/libs/ms.js.map +1 -1
  93. package/lib/logging/Logger.js.map +1 -1
  94. package/lib/logging/createChildLogger.js.map +1 -1
  95. package/lib/logging/createLogger.js.map +1 -1
  96. package/lib/logging/createNoopLogger.js.map +1 -1
  97. package/lib/logging/slog.js.map +1 -1
  98. package/lib/maths/clamp.js.map +1 -1
  99. package/lib/maths/random.js.map +1 -1
  100. package/lib/mitt/index.js.map +1 -1
  101. package/lib/modules/isModule.js.map +1 -1
  102. package/lib/modules/parseModuleId.js.map +1 -1
  103. package/lib/objects/computeIfAbsent.js.map +1 -1
  104. package/lib/objects/get.js.map +1 -1
  105. package/lib/objects/get.test-d.js.map +1 -1
  106. package/lib/objects/merge/index.js.map +1 -1
  107. package/lib/objects/merge/isMergeableObject.js.map +1 -1
  108. package/lib/objects/merge/merge.js.map +1 -1
  109. package/lib/objects/parseObjectPath.js.map +1 -1
  110. package/lib/objects/set.js.map +1 -1
  111. package/lib/runtime/AsyncCloser.js.map +1 -1
  112. package/lib/runtime/Closer.js.map +1 -1
  113. package/lib/runtime/getGlobalThis.js.map +1 -1
  114. package/lib/runtime/structuredClone.js.map +1 -1
  115. package/lib/schema/typebox/index.js.map +1 -1
  116. package/lib/schema/typebox/typebox.js.map +1 -1
  117. package/lib/scripts/getGenerateContext.js.map +1 -1
  118. package/lib/server/crypto/md5.js.map +1 -1
  119. package/lib/server/fetch/createFetchWithProxy.js.map +1 -1
  120. package/lib/server/fetch/createFetchWithProxyByNodeFetch.js.map +1 -1
  121. package/lib/server/fetch/createFetchWithProxyByUndici.js.map +1 -1
  122. package/lib/server/getPackageDir.js.map +1 -1
  123. package/lib/server/index.js.map +1 -1
  124. package/lib/server/jsdom.js.map +1 -1
  125. package/lib/server/node-fetch.js.map +1 -1
  126. package/lib/server/polyfill/polyfillBrowser.js.map +1 -1
  127. package/lib/server/polyfill/polyfillCrypto.js.map +1 -1
  128. package/lib/server/polyfill/polyfillFetch.js.map +1 -1
  129. package/lib/server/polyfill/polyfillJsDom.js.map +1 -1
  130. package/lib/server/polyfill/polyfillWebSocket.js.map +1 -1
  131. package/lib/server/ws.js.map +1 -1
  132. package/lib/strings/camelCase.js.map +1 -1
  133. package/lib/strings/formatBytes.js.map +1 -1
  134. package/lib/strings/renderTemplate.js.map +1 -1
  135. package/lib/typedoc.js.map +1 -1
  136. package/lib/types.d.js.map +1 -1
  137. package/lib/validations/asserts.js.map +1 -1
  138. package/lib/validations/isUUID.js.map +1 -1
  139. package/lib/validations/parseTimestamp.js.map +1 -1
  140. package/package.json +4 -4
  141. package/src/errors/Errors.ts +37 -16
  142. package/src/io/ArrayBuffers.base64.test.ts +7 -0
  143. package/src/io/ArrayBuffers.ts +272 -271
  144. package/src/io/base64.ts +2 -2
  145. package/src/langs/getObjectId.ts +1 -1
@@ -1,252 +1,153 @@
1
1
  import { classOf } from '../langs/classOf';
2
2
  import { getGlobalThis } from '../runtime/getGlobalThis';
3
- import { decodeBase64ToArrayBuffer, encodeArrayBufferToBase64 } from './base64';
3
+ import { decodeBase64ToUint8Array, encodeArrayBufferToBase64 } from './base64';
4
4
  import { isBuffer } from './isBuffer';
5
5
 
6
6
  /**
7
7
  * Various utils to work with {@link ArrayBuffer}
8
8
  *
9
- * @see https://github.com/tc39/proposal-arraybuffer-base64
10
9
  * @see https://github.com/tc39/proposal-resizablearraybuffer
11
10
  */
12
- export interface ArrayBuffers {
13
- /**
14
- * isArrayBuffer check if the given value is an {@link ArrayBuffer}
15
- */
16
- isArrayBuffer(v: any): v is ArrayBuffer;
17
-
18
- /**
19
- * slice the given view with the given offset and length, will handle the {@link Buffer} as well
20
- *
21
- * @see {@link https://nodejs.org/api/buffer.html#bufslicestart-end Buffer.slice}
22
- */
23
- slice<T extends ArrayBufferView>(o: T, start?: number, end?: number): T;
24
-
25
- /**
26
- * asView convert the given value to given {@link TypedArray} view
27
- *
28
- * TypedArray can be {@link Buffer}, will avoid copy
29
- */
30
- asView<C extends ArrayBufferViewConstructor<unknown>>(
31
- TypedArray: C,
32
- v: BufferSource,
33
- byteOffset?: number,
34
- byteLength?: number,
35
- ): InstanceType<C>;
36
-
37
- /**
38
- * toString convert the given {@link BufferSource} to string
39
- */
40
- toString(v: BufferSource | string, encoding?: ToStringEncoding): string;
41
-
42
- /**
43
- * Returns true if encoding is the name of a supported character encoding, or false otherwise.
44
- */
45
- isEncoding(v?: string): v is ToStringEncoding;
46
-
47
- toJSON<T = any>(v: BufferSource | string, reviver?: (this: any, key: string, value: any) => any): T;
11
+ export namespace ArrayBuffers {
12
+ /*
13
+ Uint8Array to/from base64 and hex
14
+ Stage 3
15
+ Uint8Array.fromBase64, Uint8Array.prototype.toBase64
16
+ Uint8Array.fromHex, Uint8Array.prototype.toHex
17
+ https://github.com/tc39/proposal-arraybuffer-base64
18
+ */
48
19
 
49
- /**
50
- * from convert the given value to {@link ArrayBuffer}
20
+ /*
21
+ In-Place Resizable and Growable ArrayBuffers
22
+ Stage 4
23
+ Chrome 111, Nodejs 20, Safari 16.4
24
+
25
+ SharedArrayBuffer & ArrayBuffer
26
+ constructor(byteLength, {maxByteLength})
27
+ prototype.resize(newByteLength)
28
+ prototype.slice(start, end)
29
+ prototype.{resizable,maxByteLength}
30
+ https://github.com/tc39/proposal-resizablearraybuffer
51
31
  */
52
- from(v: string | BufferSource, encoding?: ToStringEncoding): ArrayBuffer;
53
32
 
54
- from<C extends ArrayBufferViewConstructor<unknown>>(
55
- v: string | BufferSource,
56
- encoding: ToStringEncoding,
57
- TypedArray: C,
58
- ): C;
33
+ export type BinaryStringEncoding =
34
+ | 'ascii'
35
+ | 'utf16le'
36
+ // | 'utf-16le'
37
+ | 'ucs2'
38
+ | 'ucs-2'
39
+ | 'base64'
40
+ | 'base64url'
41
+ | 'latin1'
42
+ | 'binary'
43
+ | 'utf8'
44
+ | 'utf-8'
45
+ | 'hex';
46
+
47
+ let nativeBufferAllowed: boolean = true;
48
+ let isBufferAvailable: undefined | boolean;
59
49
 
60
50
  /**
61
- * concat the given {@link BufferSource} to a new {@link ArrayBuffer}
51
+ * isNativeBufferAvailable check if the native {@link Buffer} is available
62
52
  */
63
- concat(buffers: Array<BufferSource>, result?: ArrayBuffer, offset?: number): ArrayBuffer;
64
-
65
- fromBase64(v: string): Uint8Array;
66
-
67
- fromHex(v: string): Uint8Array;
68
-
69
- toBase64(v: BufferSource): string;
70
-
71
- toHex(v: BufferSource): string;
72
-
73
- resize(v: ArrayBuffer, newByteLength: number): ArrayBuffer;
74
-
75
- // truncate(v: ArrayBufferLike, len?: number): ArrayBufferLike;
76
- }
77
-
78
- type ToStringEncoding =
79
- | 'ascii'
80
- | 'utf16le'
81
- // | 'utf-16le'
82
- | 'ucs2'
83
- | 'ucs-2'
84
- | 'base64'
85
- | 'base64url'
86
- | 'latin1'
87
- | 'binary'
88
- | 'utf8'
89
- | 'utf-8'
90
- | 'hex';
91
-
92
- export class ArrayBuffers {
93
- static #nativeBufferAllowed: boolean = true;
94
- static #isBufferAvailable: undefined | boolean;
95
-
96
- static isNativeBufferAvailable() {
53
+ export function isNativeBufferAvailable(): boolean {
97
54
  // eslint-disable-next-line no-return-assign
98
- return (this.#isBufferAvailable ??= !(getGlobalThis().Buffer as any)?.isPollyfill?.());
55
+ return (isBufferAvailable ??= !(getGlobalThis().Buffer as any)?.isPollyfill?.());
99
56
  }
100
57
 
101
- static isNativeBufferAllowed() {
102
- return this.#nativeBufferAllowed && this.#isBufferAvailable;
58
+ export function isNativeBufferAllowed(): boolean {
59
+ return Boolean(nativeBufferAllowed && isBufferAvailable);
103
60
  }
104
61
 
105
- static setNativeBufferAllowed(v: boolean) {
106
- this.#nativeBufferAllowed = v;
62
+ export function setNativeBufferAllowed(v: boolean): void {
63
+ nativeBufferAllowed = v;
107
64
  }
108
65
 
109
- static isArrayBuffer = (v: any): v is ArrayBuffer => {
66
+ /**
67
+ * isArrayBuffer check if the given value is an {@link ArrayBuffer}
68
+ */
69
+ export function isArrayBuffer(v: any): v is ArrayBuffer {
110
70
  return v instanceof ArrayBuffer;
111
- };
112
-
113
- static toArrayBuffer(v: BufferSource): ArrayBuffer {
114
- return v instanceof ArrayBuffer ? v : (v.buffer as ArrayBuffer);
115
71
  }
116
72
 
117
- static toUint8Array(v: BufferSource) {
118
- return ArrayBuffers.asView(Uint8Array, v);
119
- }
120
-
121
- static toBase64 = (v: BufferSource) => {
122
- if ('toBase64' in Uint8Array.prototype) {
123
- return this.toUint8Array(v).toBase64();
124
- }
125
-
126
- if (ArrayBuffers.isNativeBufferAllowed()) {
127
- return Buffer.from(ArrayBuffers.asView(Uint8Array, v)).toString('base64');
128
- }
129
-
130
- return encodeArrayBufferToBase64(this.toArrayBuffer(v));
131
- };
132
-
133
- static toHex = (v: BufferSource) => {
134
- if ('toHex' in Uint8Array.prototype) {
135
- return this.toUint8Array(v).toHex();
136
- }
137
- if (ArrayBuffers.isNativeBufferAllowed()) {
138
- return Buffer.from(ArrayBuffers.asView(Uint8Array, v)).toString('hex');
139
- }
140
- return ArrayBuffers.toString(v, 'hex');
141
- };
142
-
143
- static fromBase64 = (v: string) => {
144
- if ('fromBase64' in Uint8Array) {
145
- return Uint8Array.fromBase64(v);
146
- }
147
- if (ArrayBuffers.isNativeBufferAllowed()) {
148
- return Buffer.from(v, 'base64');
149
- }
150
- return this.toUint8Array(decodeBase64ToArrayBuffer(v));
151
- };
152
-
153
- static fromHex = (v: string) => {
154
- if ('fromHex' in Uint8Array) {
155
- return Uint8Array.fromHex(v);
156
- }
157
- return this.toUint8Array(ArrayBuffers.from(v, 'hex'));
158
- };
159
-
160
- static resize = (v: ArrayBuffer, newByteLength?: number, maxByteLength?: number): ArrayBuffer => {
161
- if (newByteLength === undefined || newByteLength === null) {
162
- return v;
163
- }
164
-
165
- // Chrome 111, Nodejs 20
166
- if ('resize' in v && typeof v.resize === 'function') {
167
- if ('resizable' in v && v.resizable) {
168
- if ('maxByteLength' in v && typeof v.maxByteLength === 'number' && v.maxByteLength >= newByteLength) {
169
- v.resize(newByteLength);
170
- return v as ArrayBuffer;
171
- }
172
- }
173
- }
174
-
175
- const old = v;
176
- const newBuf = new ArrayBuffer(newByteLength, { maxByteLength: maxByteLength });
177
- const oldView = new Uint8Array(old);
178
- const newView = new Uint8Array(newBuf);
179
- newView.set(oldView);
180
- return newBuf;
181
- };
182
-
183
- static slice = (o: TypedArray, start?: number, end?: number) => {
73
+ /**
74
+ * slice the given view with the given offset and length, will handle the {@link Buffer} as well
75
+ *
76
+ * @see {@link https://nodejs.org/api/buffer.html#bufslicestart-end Buffer.slice}
77
+ */
78
+ export function slice<T extends TypedArray>(o: T, start?: number, end?: number): T {
184
79
  // NodeJS Buffer slice is not the same as UInt8Array slice
185
80
  // https://nodejs.org/api/buffer.html#bufslicestart-end
186
81
  if (isBuffer(o)) {
187
- return Uint8Array.prototype.slice.call(o, start, end);
82
+ return Uint8Array.prototype.slice.call(o, start, end) as T;
188
83
  }
189
- return o.slice(start, end);
190
- };
84
+ return o.slice(start, end) as T;
85
+ }
191
86
 
192
- static asView = <C extends ArrayBufferViewConstructor<unknown>, I extends InstanceType<C>>(
87
+ /**
88
+ * asView convert the given value to given {@link TypedArray} view
89
+ *
90
+ * TypedArray can be {@link Buffer}, will avoid copy
91
+ */
92
+ export function asView<C extends ArrayBufferViewConstructor<unknown>>(
193
93
  TypedArray: C,
194
94
  v: BufferSource,
195
95
  byteOffset?: number,
196
96
  byteLength?: number,
197
- ): I => {
97
+ ): InstanceType<C> {
198
98
  if (v instanceof TypedArray && (byteOffset ?? 0) === 0 && byteLength === undefined) {
199
- return v as I;
99
+ return v as InstanceType<C>;
200
100
  }
201
101
  if (ArrayBuffer.isView(v) || isBuffer(v)) {
202
- if (ArrayBuffers.isNativeBufferAllowed() && (TypedArray as any) === Buffer) {
102
+ if (isNativeBufferAllowed() && (TypedArray as any) === Buffer) {
203
103
  // new Buffer() is deprecated
204
- return Buffer.from(v.buffer, byteOffset, byteLength) as I;
104
+ return Buffer.from(v.buffer, byteOffset, byteLength) as InstanceType<C>;
205
105
  }
206
- return new TypedArray(v.buffer, v.byteOffset + (byteOffset ?? 0), byteLength ?? v.byteLength) as I;
106
+ return new TypedArray(v.buffer, v.byteOffset + (byteOffset ?? 0), byteLength ?? v.byteLength) as InstanceType<C>;
207
107
  }
208
- return new TypedArray(v, byteOffset, byteLength) as I;
209
- };
108
+ return new TypedArray(v, byteOffset, byteLength) as InstanceType<C>;
109
+ }
210
110
 
211
- static toString = (buf: BufferSource | string, encoding: ToStringEncoding = 'utf8') => {
111
+ /**
112
+ * toString convert the given {@link BufferSource} to string
113
+ */
114
+ export function toString(source: BufferSource | string, encoding: BinaryStringEncoding = 'utf8'): string {
212
115
  // 'ascii' 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex'
213
- if (typeof buf === 'string') {
116
+ if (typeof source === 'string') {
214
117
  switch (encoding) {
215
118
  case 'base64':
216
- return btoa(buf);
119
+ return btoa(source);
217
120
  case 'utf-8':
218
121
  case 'utf8':
219
- return buf;
122
+ return source;
220
123
  default:
221
124
  throw new Error(`[ArrayBuffers.toString] Unsupported encoding for string: ${encoding}`);
222
125
  }
223
126
  }
224
- if (ArrayBuffers.isNativeBufferAllowed()) {
225
- return Buffer.from(ArrayBuffers.asView(Uint8Array, buf)).toString(encoding);
127
+ let u8 = asView(Uint8Array, source);
128
+ if (isNativeBufferAllowed()) {
129
+ return Buffer.from(u8).toString(encoding);
226
130
  }
227
131
  // reference
228
132
  // https://github.com/feross/buffer/blob/master/index.js
229
133
  switch (encoding) {
230
134
  case 'hex': {
231
- const view: Uint8Array = ArrayBuffers.asView(Uint8Array, buf);
232
- return [...view].map((b) => hexLookupTable[b]).join('');
135
+ return [...u8].map((b) => hexLookupTable[b]).join('');
233
136
  }
234
137
  case 'base64': {
235
- return encodeArrayBufferToBase64(ArrayBuffers.asView(Uint8Array, buf));
138
+ return encodeArrayBufferToBase64(u8);
236
139
  }
237
140
  case 'utf8':
238
141
  // falls through
239
142
  case 'utf-8':
240
- return new TextDecoder().decode(buf as any);
143
+ return new TextDecoder().decode(source);
241
144
  case 'ascii': {
242
- const view: Uint8Array = ArrayBuffers.asView(Uint8Array, buf);
243
- return String.fromCharCode(...view.map((v) => v & 0x7f));
145
+ return String.fromCharCode(...u8.map((v) => v & 0x7f));
244
146
  }
245
147
  case 'latin1':
246
148
  // falls through
247
149
  case 'binary': {
248
- const view: Uint8Array = ArrayBuffers.asView(Uint8Array, buf);
249
- return String.fromCharCode(...view);
150
+ return String.fromCharCode(...u8);
250
151
  }
251
152
  case 'ucs2':
252
153
  // falls through
@@ -254,120 +155,113 @@ export class ArrayBuffers {
254
155
  // case 'utf-16le':
255
156
  // falls through
256
157
  case 'utf16le': {
257
- const view: Uint8Array = ArrayBuffers.asView(Uint8Array, buf);
258
158
  let res = '';
259
159
  // If length is odd, the last 8 bits must be ignored (same as node.js)
260
- for (let i = 0; i < view.length - 1; i += 2) {
261
- res += String.fromCharCode(view[i] + view[i + 1] * 256);
160
+ for (let i = 0; i < u8.length - 1; i += 2) {
161
+ res += String.fromCharCode(u8[i] + u8[i + 1] * 256);
262
162
  }
263
163
  return res;
264
164
  }
265
165
  default:
266
166
  throw new Error(`[ArrayBuffers.toString] Unknown encoding: ${encoding}`);
267
167
  }
268
- };
269
-
270
- static toJSON = (v: BufferSource | string, reviver?: (this: any, key: string, value: any) => any) => {
271
- return JSON.parse(ArrayBuffers.toString(v), reviver);
272
- };
168
+ }
273
169
 
274
- static alloc = (size: number, fill?: string | number, encoding?: ToStringEncoding) => {
275
- if (fill !== undefined) {
276
- if (typeof fill === 'number') {
277
- return new Uint8Array(size).fill(fill);
278
- }
279
- // as cast
280
- // https://stackoverflow.com/questions/73994091
281
- return ArrayBuffers.asView(Uint8Array, ArrayBuffers.from(fill, encoding)).slice(0, size);
170
+ function normalizeEncoding(encoding: string | undefined) {
171
+ switch (encoding?.toLowerCase()) {
172
+ case 'utf-8':
173
+ case 'utf8':
174
+ return 'utf8';
175
+ case 'utf-16le':
176
+ case 'ucs2':
177
+ case 'ucs-2':
178
+ return 'utf16le';
179
+ case 'hex':
180
+ case 'ascii':
181
+ case 'latin1':
182
+ case 'binary':
183
+ case 'base64':
184
+ case 'utf16le':
185
+ return encoding;
186
+ default:
187
+ return undefined;
282
188
  }
283
- return new ArrayBuffer(size);
284
- };
189
+ }
285
190
 
286
- static from = (
287
- v: string | BufferSource | ArrayLike<number> | Iterable<number>,
288
- encoding: ToStringEncoding = 'utf8',
191
+ /**
192
+ * Returns true if encoding is the name of a supported character encoding, or false otherwise.
193
+ */
194
+ export function isEncoding(v?: string): v is BinaryStringEncoding {
195
+ return normalizeEncoding(v) !== undefined;
196
+ }
197
+
198
+ export function toJSON<T = any>(v: BufferSource | string, reviver?: (this: any, key: string, value: any) => any): T {
199
+ return JSON.parse(toString(v), reviver);
200
+ }
201
+
202
+ /**
203
+ * from convert the given value to {@link ArrayBuffer} like
204
+ */
205
+ export function from(
206
+ src: string | BufferSource | Array<number> | Iterable<number>,
207
+ encoding?: BinaryStringEncoding,
208
+ ): ArrayBuffer | TypedArray;
209
+ /**
210
+ * from convert the given value to {@link TypedArray}
211
+ */
212
+ export function from<C extends ArrayBufferViewConstructor<unknown>>(
213
+ src: string | BufferSource | Array<number> | Iterable<number>,
214
+ encoding: BinaryStringEncoding,
215
+ TypedArray: C,
216
+ ): InstanceType<C>;
217
+ export function from(
218
+ src: string | BufferSource | Array<number> | Iterable<number>,
219
+ encoding: BinaryStringEncoding = 'utf8',
289
220
  view?: any,
290
- ): any => {
291
- if (view) {
292
- return this.asView(view, this.from(v, encoding));
221
+ ): any {
222
+ if (!src) {
223
+ return new (view || ArrayBuffer)(0);
224
+ }
225
+ if (isBufferSource(src)) {
226
+ return view ? asView(view, src) : src;
293
227
  }
294
- if (!v) {
295
- return new ArrayBuffer(0);
228
+ // Array<number> | Iterable<number>
229
+ if ((typeof src !== 'string' && isIterable(src)) || Array.isArray(src)) {
230
+ return (view || Uint8Array).from(src);
296
231
  }
297
- if (typeof v === 'string') {
298
- if (ArrayBuffers.isNativeBufferAllowed()) {
299
- return Buffer.from(v, encoding);
232
+ if (view) {
233
+ return asView(view, from(src, encoding));
234
+ }
235
+ if (typeof src === 'string') {
236
+ // is string
237
+ if (isNativeBufferAllowed()) {
238
+ return Buffer.from(src, encoding);
300
239
  }
301
-
302
240
  switch (encoding) {
303
241
  case 'utf-8':
304
242
  // falls through
305
243
  case 'utf8':
306
- return new TextEncoder().encode(v).buffer;
244
+ return new TextEncoder().encode(src).buffer;
307
245
  case 'base64':
308
246
  // replaceAll need higher version of nodejs
309
- return decodeBase64ToArrayBuffer(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
247
+ // return decodeBase64ToArrayBuffer(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
248
+ return fromBase64(src);
310
249
  case 'hex':
311
- return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))).buffer;
250
+ // return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))).buffer;
251
+ return fromHex(src);
312
252
  default:
313
- throw new Error(`[ArrayBuffers.from] Unknown encoding: ${encoding}`);
253
+ throw new Error(`ArrayBuffers.from unsupported encoding: ${encoding}`);
314
254
  }
315
255
  }
316
- if (v instanceof ArrayBuffer) {
317
- return v;
318
- }
319
- // lost length
320
- if (ArrayBuffer.isView(v) || isBuffer(v)) {
321
- if (v.byteOffset !== 0) {
322
- // return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength)
323
- throw new Error('ArrayBuffers.from do not support view with offset');
324
- }
325
- return v.buffer;
326
- }
327
- if (Array.isArray(v)) {
328
- return new Uint8Array(v);
329
- }
330
- const type = classOf(v);
256
+
257
+ const type = classOf(src);
331
258
  throw new TypeError(`ArrayBuffers.from unsupported type ${type}`);
332
- };
259
+ }
333
260
 
334
- static isEncoding = (encoding?: string) => {
335
- switch (String(encoding).toLowerCase()) {
336
- case 'hex':
337
- case 'utf8':
338
- case 'utf-8':
339
- case 'ascii':
340
- case 'latin1':
341
- case 'binary':
342
- case 'base64':
343
- case 'ucs2':
344
- case 'ucs-2':
345
- case 'utf16le':
346
- // case 'utf-16le':
347
- return true;
348
- default:
349
- return false;
350
- }
351
- };
352
-
353
- // static truncate = (a: ArrayBufferLike, len?: number) => {
354
- // if (len === 0) {
355
- // return new ArrayBuffer(0);
356
- // }
357
- // if (!len) {
358
- // return a;
359
- // }
360
- // if (a.byteLength > len) {
361
- // return a.slice(0, len);
362
- // } else if (a.byteLength < len) {
363
- // let b = new Uint8Array(len);
364
- // b.set(new Uint8Array(a));
365
- // return b;
366
- // }
367
- // return a;
368
- // };
369
-
370
- static concat = (buffers: Array<BufferSource>, result?: ArrayBuffer, offset = 0): ArrayBuffer => {
261
+ /**
262
+ * concat the given {@link BufferSource} to a new {@link ArrayBuffer}
263
+ */
264
+ export function concat(buffers: Array<BufferSource>, result?: ArrayBuffer, offset = 0): ArrayBuffer {
371
265
  // https://stackoverflow.com/questions/10786128/appending-arraybuffers
372
266
 
373
267
  const length = buffers.reduce((a, b) => a + b.byteLength, 0);
@@ -386,7 +280,106 @@ export class ArrayBuffers {
386
280
  offset += buffer.byteLength;
387
281
  }
388
282
  return r.buffer;
389
- };
283
+ }
284
+
285
+ export function fromBase64(v: string): Uint8Array {
286
+ if ('fromBase64' in Uint8Array) {
287
+ return Uint8Array.fromBase64(v);
288
+ }
289
+ if (isNativeBufferAllowed()) {
290
+ return Buffer.from(v, 'base64');
291
+ }
292
+ return decodeBase64ToUint8Array(v.replace(/[^0-9a-zA-Z=+/_]/g, ''));
293
+ }
294
+
295
+ export function fromHex(v: string): Uint8Array {
296
+ if ('fromHex' in Uint8Array) {
297
+ return Uint8Array.fromHex(v);
298
+ }
299
+ if (isNativeBufferAllowed()) {
300
+ return Buffer.from(v, 'hex');
301
+ }
302
+ return new Uint8Array(v.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16)));
303
+ }
304
+
305
+ /**
306
+ * toBase64 convert the given {@link BufferSource} to base64 string
307
+ * @param source if string, will be encoded as utf8
308
+ */
309
+ export function toBase64(source: BufferSource | string): string {
310
+ if (typeof source === 'string') {
311
+ source = new TextEncoder().encode(source);
312
+ }
313
+ if ('toBase64' in Uint8Array.prototype) {
314
+ return toUint8Array(source).toBase64();
315
+ }
316
+ if (isNativeBufferAllowed()) {
317
+ return Buffer.from(asView(Uint8Array, source)).toString('base64');
318
+ }
319
+ return encodeArrayBufferToBase64(toArrayBuffer(source));
320
+ }
321
+
322
+ export function toHex(v: BufferSource): string {
323
+ if ('toHex' in Uint8Array.prototype) {
324
+ return toUint8Array(v).toHex();
325
+ }
326
+ if (isNativeBufferAllowed()) {
327
+ return Buffer.from(asView(Uint8Array, v)).toString('hex');
328
+ }
329
+ return toString(v, 'hex');
330
+ }
331
+
332
+ export function resize(v: ArrayBuffer, newByteLength?: number, maxByteLength?: number): ArrayBuffer {
333
+ if (newByteLength === undefined || newByteLength === null) {
334
+ return v;
335
+ }
336
+
337
+ // Chrome 111, Nodejs 20
338
+ if ('resize' in v && typeof v.resize === 'function') {
339
+ if ('resizable' in v && v.resizable) {
340
+ if ('maxByteLength' in v && typeof v.maxByteLength === 'number' && v.maxByteLength >= newByteLength) {
341
+ v.resize(newByteLength);
342
+ return v as ArrayBuffer;
343
+ }
344
+ }
345
+ }
346
+
347
+ const old = v;
348
+ const newBuf = new ArrayBuffer(newByteLength, { maxByteLength: maxByteLength });
349
+ const oldView = new Uint8Array(old);
350
+ const newView = new Uint8Array(newBuf);
351
+ newView.set(oldView);
352
+ return newBuf;
353
+ }
354
+
355
+ export function toArrayBuffer(v: BufferSource): ArrayBuffer {
356
+ if (v instanceof ArrayBuffer) {
357
+ return v;
358
+ }
359
+ if (ArrayBuffer.isView(v)) {
360
+ if (v.byteOffset > 0) {
361
+ throw new Error('ArrayBuffers.toArrayBuffer do not support view with offset');
362
+ }
363
+ return v.buffer;
364
+ }
365
+ throw new Error(`ArrayBuffers.toArrayBuffer unsupported type ${classOf(v)}`);
366
+ }
367
+
368
+ export function toUint8Array(v: BufferSource): Uint8Array {
369
+ return asView(Uint8Array, v);
370
+ }
371
+
372
+ export function alloc(size: number, fill?: string | number, encoding?: BinaryStringEncoding): ArrayBuffer {
373
+ if (fill !== undefined) {
374
+ if (typeof fill === 'number') {
375
+ return new Uint8Array(size).fill(fill);
376
+ }
377
+ // as cast
378
+ // https://stackoverflow.com/questions/73994091
379
+ return asView(Uint8Array, from(fill, encoding)).slice(0, size);
380
+ }
381
+ return new ArrayBuffer(size);
382
+ }
390
383
  }
391
384
 
392
385
  export type TypedArray =
@@ -443,3 +436,11 @@ declare global {
443
436
  fromHex(v: string): Uint8Array;
444
437
  }
445
438
  }
439
+
440
+ function isIterable(obj: any): obj is Iterable<any> {
441
+ return typeof obj?.[Symbol.iterator] === 'function';
442
+ }
443
+
444
+ function isBufferSource(v: any): v is BufferSource {
445
+ return ArrayBuffer.isView(v) || v instanceof ArrayBuffer;
446
+ }
package/src/io/base64.ts CHANGED
@@ -29,7 +29,7 @@ export function encodeArrayBufferToBase64(arraybuffer: ArrayBuffer): string {
29
29
  return base64;
30
30
  }
31
31
 
32
- export function decodeBase64ToArrayBuffer(base64: string): ArrayBuffer {
32
+ export function decodeBase64ToUint8Array(base64: string): Uint8Array {
33
33
  const len = base64.length;
34
34
  let bufferLength = base64.length * 0.75;
35
35
  let i;
@@ -60,5 +60,5 @@ export function decodeBase64ToArrayBuffer(base64: string): ArrayBuffer {
60
60
  bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
61
61
  }
62
62
 
63
- return arraybuffer;
63
+ return bytes;
64
64
  }
@@ -3,7 +3,7 @@ import { getGlobalStates } from './getGlobalStates';
3
3
  export function getObjectId(k: any): number {
4
4
  const state = getGlobalStates('ObjectId', () => {
5
5
  return {
6
- id: 0,
6
+ id: 1,
7
7
  map: new WeakMap(),
8
8
  };
9
9
  });