@helios-lang/effect 0.1.5 → 0.1.6

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 (109) hide show
  1. package/bun.lock +60 -0
  2. package/package.json +1 -1
  3. package/tsconfig.build.tsbuildinfo +1 -0
  4. package/tsconfig.check.tsbuildinfo +1 -0
  5. package/tsconfig.tsbuildinfo +1 -0
  6. package/types/Address.d.ts +5 -0
  7. package/types/Address.d.ts.map +1 -0
  8. package/types/Bech32.d.ts +30 -0
  9. package/types/Bech32.d.ts.map +1 -0
  10. package/types/Cbor.d.ts +430 -0
  11. package/types/Cbor.d.ts.map +1 -0
  12. package/types/Ledger/Address.d.ts +109 -0
  13. package/types/Ledger/Address.d.ts.map +1 -0
  14. package/types/Ledger/AssetClass.d.ts +101 -0
  15. package/types/Ledger/AssetClass.d.ts.map +1 -0
  16. package/types/Ledger/Assets.d.ts +70 -0
  17. package/types/Ledger/Assets.d.ts.map +1 -0
  18. package/types/Ledger/Credential.d.ts +26 -0
  19. package/types/Ledger/Credential.d.ts.map +1 -0
  20. package/types/Ledger/DatumHash.d.ts +40 -0
  21. package/types/Ledger/DatumHash.d.ts.map +1 -0
  22. package/types/Ledger/IsMainnet.d.ts +6 -0
  23. package/types/Ledger/IsMainnet.d.ts.map +1 -0
  24. package/types/Ledger/MintingPolicy.d.ts +39 -0
  25. package/types/Ledger/MintingPolicy.d.ts.map +1 -0
  26. package/{src/Ledger/NetworkParams.ts → types/Ledger/NetworkParams.d.ts} +24 -26
  27. package/types/Ledger/NetworkParams.d.ts.map +1 -0
  28. package/types/Ledger/PubKeyHash.d.ts +40 -0
  29. package/types/Ledger/PubKeyHash.d.ts.map +1 -0
  30. package/types/Ledger/TxId.d.ts +10 -0
  31. package/types/Ledger/TxId.d.ts.map +1 -0
  32. package/types/Ledger/TxInput.d.ts +55 -0
  33. package/types/Ledger/TxInput.d.ts.map +1 -0
  34. package/types/Ledger/TxOutput.d.ts +63 -0
  35. package/types/Ledger/TxOutput.d.ts.map +1 -0
  36. package/types/Ledger/TxOutputDatum.d.ts +41 -0
  37. package/types/Ledger/TxOutputDatum.d.ts.map +1 -0
  38. package/types/Ledger/TxOutputId.d.ts +14 -0
  39. package/types/Ledger/TxOutputId.d.ts.map +1 -0
  40. package/types/Ledger/ValidatorHash.d.ts +40 -0
  41. package/types/Ledger/ValidatorHash.d.ts.map +1 -0
  42. package/types/Ledger/index.d.ts +16 -0
  43. package/types/Ledger/index.d.ts.map +1 -0
  44. package/types/Uplc/Cek.d.ts +72 -0
  45. package/types/Uplc/Cek.d.ts.map +1 -0
  46. package/types/Uplc/Data.d.ts +530 -0
  47. package/types/Uplc/Data.d.ts.map +1 -0
  48. package/types/Uplc/DataSchema.d.ts +227 -0
  49. package/types/Uplc/DataSchema.d.ts.map +1 -0
  50. package/types/Uplc/Primitive.d.ts +26 -0
  51. package/types/Uplc/Primitive.d.ts.map +1 -0
  52. package/types/Uplc/index.d.ts +3 -0
  53. package/types/Uplc/index.d.ts.map +1 -0
  54. package/types/index.d.ts +5 -0
  55. package/types/index.d.ts.map +1 -0
  56. package/types/internal/Base32.d.ts +49 -0
  57. package/types/internal/Base32.d.ts.map +1 -0
  58. package/types/internal/BigEndian.d.ts +22 -0
  59. package/types/internal/BigEndian.d.ts.map +1 -0
  60. package/types/internal/Bits.d.ts +123 -0
  61. package/types/internal/Bits.d.ts.map +1 -0
  62. package/types/internal/Bytes.d.ts +88 -0
  63. package/types/internal/Bytes.d.ts.map +1 -0
  64. package/types/internal/Flat.d.ts +71 -0
  65. package/types/internal/Flat.d.ts.map +1 -0
  66. package/types/internal/Float.d.ts +38 -0
  67. package/types/internal/Float.d.ts.map +1 -0
  68. package/types/internal/Utf8.d.ts +24 -0
  69. package/types/internal/Utf8.d.ts.map +1 -0
  70. package/src/Bech32.test.ts +0 -117
  71. package/src/Bech32.ts +0 -198
  72. package/src/Cbor.test.ts +0 -1610
  73. package/src/Cbor.ts +0 -1704
  74. package/src/Ledger/Address.ts +0 -248
  75. package/src/Ledger/AssetClass.ts +0 -90
  76. package/src/Ledger/Assets.ts +0 -164
  77. package/src/Ledger/Credential.ts +0 -29
  78. package/src/Ledger/DatumHash.ts +0 -36
  79. package/src/Ledger/IsMainnet.ts +0 -6
  80. package/src/Ledger/MintingPolicy.ts +0 -57
  81. package/src/Ledger/PubKeyHash.ts +0 -36
  82. package/src/Ledger/TxId.ts +0 -31
  83. package/src/Ledger/TxInput.test.ts +0 -21
  84. package/src/Ledger/TxInput.ts +0 -66
  85. package/src/Ledger/TxOutput.ts +0 -166
  86. package/src/Ledger/TxOutputDatum.ts +0 -64
  87. package/src/Ledger/TxOutputId.ts +0 -63
  88. package/src/Ledger/ValidatorHash.ts +0 -36
  89. package/src/Ledger/index.ts +0 -15
  90. package/src/Uplc/Cek.ts +0 -92
  91. package/src/Uplc/Data.test.ts +0 -321
  92. package/src/Uplc/Data.ts +0 -657
  93. package/src/Uplc/Primitive.ts +0 -56
  94. package/src/Uplc/index.ts +0 -2
  95. package/src/index.ts +0 -4
  96. package/src/internal/Base32.test.ts +0 -219
  97. package/src/internal/Base32.ts +0 -341
  98. package/src/internal/BigEndian.test.ts +0 -79
  99. package/src/internal/BigEndian.ts +0 -67
  100. package/src/internal/Bits.test.ts +0 -300
  101. package/src/internal/Bits.ts +0 -398
  102. package/src/internal/Bytes.test.ts +0 -369
  103. package/src/internal/Bytes.ts +0 -343
  104. package/src/internal/Flat.test.ts +0 -29
  105. package/src/internal/Flat.ts +0 -387
  106. package/src/internal/Float.test.ts +0 -51
  107. package/src/internal/Float.ts +0 -190
  108. package/src/internal/Utf8.test.ts +0 -69
  109. package/src/internal/Utf8.ts +0 -58
@@ -1,369 +0,0 @@
1
- import { describe, expect, it } from "bun:test"
2
- import { Effect } from "effect"
3
- import * as Bytes from "./Bytes.js"
4
-
5
- describe("Bytes.toArray()", () => {
6
- it("converts [255] into [255]", () => {
7
- expect(Bytes.toArray([255])).toEqual([255])
8
- })
9
-
10
- it("converts #ff into [255]", () => {
11
- expect(Bytes.toArray("ff")).toEqual([255])
12
- })
13
-
14
- it("converts Uint8Array([255]) into [255]", () => {
15
- expect(Bytes.toArray(new Uint8Array([255]))).toEqual([255])
16
- })
17
-
18
- it("converts ByteStream([255]) into [255]", () => {
19
- expect(Bytes.toArray(Bytes.makeStream({ bytes: [255] }))).toEqual([255])
20
- })
21
-
22
- it("converts ByteStream([255]) into [255]", () => {
23
- expect(Bytes.toArray(Bytes.makeStream([255]))).toEqual([255])
24
- })
25
-
26
- it("fails for wrong type", () => {
27
- expect(() => Bytes.toArray({} as string)).toThrow()
28
- })
29
- })
30
-
31
- describe("Bytes.toUint8Array()", () => {
32
- it("returns [] for #", () => {
33
- expect(Bytes.toUint8Array("")).toEqual(new Uint8Array([]))
34
- })
35
-
36
- it("returns [] for []", () => {
37
- expect(Bytes.toUint8Array([])).toEqual(new Uint8Array([]))
38
- })
39
-
40
- it("returns [] for empty Uint8Array", () => {
41
- expect(Bytes.toUint8Array(new Uint8Array([]))).toEqual(new Uint8Array([]))
42
- })
43
-
44
- it("returns [255] for #ff", () => {
45
- expect(Bytes.toUint8Array("ff")).toEqual(new Uint8Array([255]))
46
- })
47
-
48
- it("returns [255] for [255]", () => {
49
- expect(Bytes.toUint8Array([255])).toEqual(new Uint8Array([255]))
50
- })
51
-
52
- it("returns [0] for [256]", () => {
53
- expect(Bytes.toUint8Array([256])).toEqual(new Uint8Array([0]))
54
- })
55
-
56
- it("returns [255] for Uint8Array([255])", () => {
57
- expect(Bytes.toUint8Array(new Uint8Array([255]))).toEqual(
58
- new Uint8Array([255])
59
- )
60
- })
61
- })
62
-
63
- describe("Bytes.Stream", () => {
64
- describe("initialized with [255]", () => {
65
- it("returns 255 when peeking a single byte", () => {
66
- const bs = Bytes.makeStream({ bytes: [255] })
67
-
68
- expect(Effect.runSync(bs.peekOne())).toBe(255)
69
- })
70
-
71
- it("returns Uint8Array([255]) when inspecting all bytes", () => {
72
- const bs = Bytes.makeStream([255])
73
-
74
- expect(bs.bytes).toEqual(new Uint8Array([255]))
75
- })
76
-
77
- it("returns pos == 0 right after initialization", () => {
78
- const bs = Bytes.makeStream([255])
79
-
80
- expect(bs.pos).toBe(0)
81
- })
82
-
83
- it(`returns 255 when shifting a single byte`, () => {
84
- const bs = Bytes.makeStream([255])
85
-
86
- expect(Effect.runSync(bs.shiftOne())).toBe(255)
87
- expect(bs.pos).toBe(1)
88
- expect(bs.shiftRemaining()).toEqual([])
89
- })
90
-
91
- it(`after shifting a single byte, stream is at end`, () => {
92
- const bs = Bytes.makeStream([255])
93
- bs.shiftOne()
94
-
95
- expect(bs.isAtEnd()).toBe(true)
96
- })
97
-
98
- it("fails after shifting two bytes", () => {
99
- const bs = Bytes.makeStream([255])
100
- Effect.runSync(bs.shiftOne())
101
-
102
- expect(() => Effect.runSync(bs.shiftOne())).toThrow()
103
- })
104
-
105
- it("after shifting a single byte, fails when peeking", () => {
106
- const bs = Bytes.makeStream([255])
107
- Effect.runSync(bs.shiftOne())
108
-
109
- expect(() => Effect.runSync(bs.peekOne())).toThrow()
110
- })
111
-
112
- it(`returns [255] when calling shiftMany(1)`, () => {
113
- const bs = Bytes.makeStream([255])
114
-
115
- expect(Effect.runSync(bs.shiftMany(1))).toEqual([255])
116
- })
117
-
118
- it(`returns [] when calling shiftMany(0)`, () => {
119
- const bs = Bytes.makeStream([255])
120
-
121
- expect(Effect.runSync(bs.shiftMany(0))).toEqual([])
122
- })
123
-
124
- it(`fails when calling shiftMany(-1)`, () => {
125
- const bs = Bytes.makeStream([255])
126
-
127
- expect(() => Effect.runSync(bs.shiftMany(-1))).toThrow()
128
- })
129
-
130
- it(`fails when calling shiftMany(2)`, () => {
131
- const bs = Bytes.makeStream([255])
132
-
133
- expect(() => Effect.runSync(bs.shiftMany(2))).toThrow()
134
- })
135
-
136
- it(`returns [255] when calling peekMany(1)`, () => {
137
- const bs = Bytes.makeStream([255])
138
-
139
- expect(Effect.runSync(bs.peekMany(1))).toEqual([255])
140
- })
141
-
142
- it(`returns [] when calling peekMany(0)`, () => {
143
- const bs = Bytes.makeStream([255])
144
-
145
- expect(Effect.runSync(bs.peekMany(0))).toEqual([])
146
- })
147
-
148
- it(`fails when calling peekMany(-1)`, () => {
149
- const bs = Bytes.makeStream([255])
150
-
151
- expect(() => Effect.runSync(bs.peekMany(-1))).toThrow()
152
- })
153
-
154
- it(`fails when calling peekMany(2)`, () => {
155
- const bs = Bytes.makeStream([255])
156
-
157
- expect(() => Effect.runSync(bs.peekMany(2))).toThrow()
158
- })
159
- })
160
-
161
- describe(`initialized using makeByteStream({bytes: [255]})`, () => {
162
- it("returns 255 when peeking a single byte", () => {
163
- const bs = Bytes.makeStream([255])
164
-
165
- expect(Effect.runSync(bs.peekOne())).toBe(255)
166
- })
167
- })
168
-
169
- describe(`initialized using makeByteStream({bytes: [255]}).copy()`, () => {
170
- it("returns 255 when peeking a single byte", () => {
171
- const bs = Bytes.makeStream([255]).copy()
172
-
173
- expect(Effect.runSync(bs.peekOne())).toBe(255)
174
- })
175
- })
176
-
177
- describe(`initialized using makeByteStream({bytes: Uint8Array.from([255])})`, () => {
178
- it("returns 255 when peeking a single byte", () => {
179
- const bs = Bytes.makeStream(Uint8Array.from([255]))
180
-
181
- expect(Effect.runSync(bs.peekOne())).toBe(255)
182
- })
183
- })
184
-
185
- describe(`initialized using makeByteStream({bytes: makeByteStream({bytes: [255]})})`, () => {
186
- it("returns 255 when peeking a single byte", () => {
187
- const bs = Bytes.makeStream({
188
- bytes: Bytes.makeStream([255])
189
- })
190
- expect(Effect.runSync(bs.peekOne())).toBe(255)
191
- })
192
- })
193
-
194
- describe("initialized with [255, 1]", () => {
195
- it(`after shifting a single byte, stream is NOT at end`, () => {
196
- const bs = Bytes.makeStream([255, 1])
197
- bs.shiftOne()
198
-
199
- expect(bs.isAtEnd()).toBe(false)
200
- })
201
- })
202
-
203
- describe("typecheck of makeByteStream", () => {
204
- it("must be able to pass BytesLike to makeByteStream", () => {
205
- const bytes: string | number[] | Uint8Array | Bytes.Stream =
206
- /** @type {any} */ []
207
-
208
- Bytes.makeStream({ bytes })
209
- })
210
- })
211
- })
212
-
213
- describe("Bytes.pad", () => {
214
- describe("padding with n=0", () => {
215
- it("returns [] for []", () => {
216
- expect(Bytes.pad([], 0)).toEqual([])
217
- })
218
-
219
- it("fails for [1]", () => {
220
- expect(() => Bytes.pad([1], 0)).toThrow()
221
- })
222
- })
223
-
224
- describe("padding with n=2", () => {
225
- it("returns [0, 0] for []", () => {
226
- expect(Bytes.pad([], 2)).toEqual([0, 0])
227
- })
228
-
229
- it("returns [1, 0] for [1]", () => {
230
- expect(Bytes.pad([1], 2)).toEqual([1, 0])
231
- })
232
- })
233
-
234
- describe("padding [0, 1, 2]", () => {
235
- it("fails if n=-1", () => {
236
- expect(() => Bytes.pad([0, 1, 2], -1)).toThrow()
237
- })
238
-
239
- it("returns [0, 1, 2, 0, 0, ...] if n=32", () => {
240
- const expected = new Array(32).fill(0) as number[]
241
- expected[1] = 1
242
- expected[2] = 2
243
- expect(Bytes.pad([0, 1, 2], 32)).toEqual(expected)
244
- })
245
- })
246
- })
247
-
248
- describe("Bytes.prepad", () => {
249
- describe("prepadding with n=0", () => {
250
- it("returns [] for []", () => {
251
- expect(Bytes.prepad([], 0)).toEqual([])
252
- })
253
-
254
- it("fails for [1]", () => {
255
- expect(() => Bytes.prepad([1], 0)).toThrow()
256
- })
257
- })
258
-
259
- describe("prepadding with n=2", () => {
260
- it("returns [0, 0] for []", () => {
261
- expect(Bytes.prepad([], 2)).toEqual([0, 0])
262
- })
263
-
264
- it("returns [0, 1] for [1]", () => {
265
- expect(Bytes.prepad([1], 2)).toEqual([0, 1])
266
- })
267
-
268
- it("returns [1, 1] for [1, 1]", () => {
269
- expect(Bytes.prepad([1, 1], 2)).toEqual([1, 1])
270
- })
271
-
272
- it("fails for [1, 1, 1]", () => {
273
- expect(() => {
274
- Bytes.prepad([1, 1, 1], 2)
275
- }).toThrow()
276
- })
277
- })
278
-
279
- describe("prepadding [0, 1, 2]", () => {
280
- it("fails if n=-1", () => {
281
- expect(() => Bytes.prepad([0, 1, 2], -1)).toThrow()
282
- })
283
-
284
- it("returns [0, 0, ..., 0, 1, 2] if n=32", () => {
285
- const expected = new Array(32).fill(0) as number[]
286
- expected[30] = 1
287
- expected[31] = 2
288
- expect(Bytes.prepad([0, 1, 2], 32)).toEqual(expected)
289
- })
290
- })
291
- })
292
-
293
- describe("Bytes.compare", () => {
294
- it("returns -1 when comparing #01010101 to #02020202", () => {
295
- expect(
296
- Bytes.compare([0x01, 0x01, 0x01, 0x01], [0x02, 0x02, 0x02, 0x02])
297
- ).toBe(-1)
298
- })
299
-
300
- it("returns 1 when comparing #02020202 to #02010202", () => {
301
- expect(Bytes.compare("02020202", "02010202")).toBe(1)
302
- })
303
-
304
- it("returns 1 when comparing #01010101 to #020202 with shortestFirst=true", () => {
305
- expect(
306
- Bytes.compare([0x01, 0x01, 0x01, 0x01], Bytes.toArray("020202"), true)
307
- ).toBe(1)
308
- })
309
-
310
- it("returns 1 when comparing #010101 to #02020202 with shortestFirst=true", () => {
311
- expect(
312
- Bytes.compare(
313
- Bytes.toArray("010101"),
314
- Bytes.toUint8Array("02020202"),
315
- true
316
- )
317
- ).toBe(-1)
318
- })
319
-
320
- it("returns 0 when comparing #01010101 to #01010101", () => {
321
- expect(Bytes.compare(Bytes.toArray("01010101"), "01010101")).toBe(0)
322
- })
323
-
324
- it("returns 1 when comparing #01010101 to #010101", () => {
325
- expect(Bytes.compare("01010101", "010101")).toBe(1)
326
- })
327
-
328
- it("returns 1 when comparing #010101 to #01010101", () => {
329
- expect(
330
- Bytes.compare(Bytes.toUint8Array("010101"), Bytes.makeStream("01010101"))
331
- ).toBe(-1)
332
- })
333
- })
334
-
335
- describe("Bytes.dummy", () => {
336
- it("returns all 0 with default 2nd arg", () => {
337
- expect(Bytes.dummy(28)).toEqual(new Array(28).fill(0) as number[])
338
- })
339
- })
340
-
341
- describe("Bytes.equals", () => {
342
- it("returns false for [] and [1]", () => {
343
- expect(Bytes.equals([], [1])).toBe(false)
344
- })
345
-
346
- it("returns true for [1] and [1]", () => {
347
- expect(Bytes.equals([1], [1])).toBe(true)
348
- })
349
-
350
- it("returns true of Uint8Array([1]) and Uint8Array([1])", () => {
351
- expect(Bytes.equals(new Uint8Array([1]), new Uint8Array([1]))).toBe(true)
352
- })
353
-
354
- it("returns true for Uint8Array([1]) and [1]", () => {
355
- expect(Bytes.equals(new Uint8Array([1]), [1])).toBe(true)
356
- })
357
-
358
- it("returns true for [1] and Uint8Array([1])", () => {
359
- expect(Bytes.equals([1], new Uint8Array([1]))).toBe(true)
360
- })
361
-
362
- it("returns false for [0] and Uint8Array([1])", () => {
363
- expect(Bytes.equals([0], new Uint8Array([1]))).toBe(false)
364
- })
365
-
366
- it("returns false for Uint8Array([0]) and Uint8Array([1])", () => {
367
- expect(Bytes.equals(new Uint8Array([0]), new Uint8Array([1]))).toBe(false)
368
- })
369
- })
@@ -1,343 +0,0 @@
1
- import { Data, Effect, Encoding } from "effect"
2
- import { encode as encodeIntBE } from "./BigEndian"
3
-
4
- export type BytesLike = string | number[] | Uint8Array | Stream
5
-
6
- export class EndOfStreamError extends Data.TaggedError("EndOfStreamError")<{
7
- message: string
8
- }> {
9
- constructor(stream: Stream) {
10
- super({ message: `Bytes.Stream is at end (pos=${stream.pos})` })
11
- }
12
- }
13
-
14
- /**
15
- * Doesn't throw an error if any input number is outside the range [0,256)
16
- * @param bytes
17
- * @returns
18
- */
19
- export function toArray(
20
- bytes: string | readonly number[] | Uint8Array | Stream
21
- ): number[] {
22
- if (bytes instanceof Uint8Array) {
23
- return Array.from(bytes)
24
- } else if (typeof bytes == "string") {
25
- const result = Encoding.decodeHex(bytes)
26
- if (result._tag == "Left") {
27
- // eslint-disable-next-line @typescript-eslint/only-throw-error
28
- throw result.left
29
- }
30
-
31
- return Array.from(result.right)
32
- } else if (Array.isArray(bytes)) {
33
- return bytes as number[]
34
- } else if ("peekRemaining" in bytes) {
35
- return bytes.peekRemaining()
36
- } else {
37
- throw new Error("Expected BytesLike")
38
- }
39
- }
40
-
41
- export function toHex(bytes: string | number[] | Uint8Array | Stream): string {
42
- if (bytes instanceof Uint8Array) {
43
- return Encoding.encodeHex(bytes)
44
- } else if (typeof bytes == "string") {
45
- return bytes
46
- } else if (Array.isArray(bytes)) {
47
- return Encoding.encodeHex(Uint8Array.from(bytes))
48
- } else if ("peekRemaining" in bytes) {
49
- return Encoding.encodeHex(Uint8Array.from(bytes.peekRemaining()))
50
- } else {
51
- throw new Error("Expected BytesLike")
52
- }
53
- }
54
-
55
- /**
56
- * Doesn't throw an error if any input number is outside the range [0,256)
57
- * @param bytes
58
- * @returns
59
- */
60
- export function toUint8Array(
61
- bytes: string | number[] | Uint8Array | Stream
62
- ): Uint8Array {
63
- if (bytes instanceof Uint8Array) {
64
- return bytes
65
- } else if (typeof bytes == "string") {
66
- const result = Encoding.decodeHex(bytes)
67
- if (result._tag == "Left") {
68
- // eslint-disable-next-line @typescript-eslint/only-throw-error
69
- throw result.left
70
- }
71
-
72
- return result.right
73
- } else if (Array.isArray(bytes)) {
74
- return Uint8Array.from(bytes)
75
- } else if ("peekRemaining" in bytes) {
76
- return bytes.bytes.slice(bytes.pos)
77
- } else {
78
- throw new Error(`Expected BytesLike`)
79
- }
80
- }
81
-
82
- export interface Stream {
83
- readonly bytes: Uint8Array
84
- readonly pos: number
85
- copy(): Stream
86
- isAtEnd(): boolean
87
- peekOne(): Effect.Effect<number, EndOfStreamError>
88
- peekMany(n: number): Effect.Effect<number[], EndOfStreamError>
89
- peekRemaining(): number[]
90
- shiftOne(): Effect.Effect<number, EndOfStreamError>
91
- shiftMany(n: number): Effect.Effect<number[], EndOfStreamError>
92
- shiftRemaining(): number[]
93
- }
94
-
95
- /**
96
- * @param arg
97
- * @returns
98
- */
99
- export function makeStream(
100
- arg:
101
- | string
102
- | number[]
103
- | Uint8Array
104
- | Stream
105
- | { bytes: string | number[] | Uint8Array | Stream }
106
- ): Stream {
107
- if (arg instanceof StreamImpl) {
108
- // most common case
109
- return arg
110
- } else if (typeof arg == "string" || Array.isArray(arg)) {
111
- return new StreamImpl(toUint8Array(arg))
112
- } else if ("pos" in arg && "bytes" in arg) {
113
- return arg
114
- } else if (arg instanceof Uint8Array) {
115
- return new StreamImpl(arg)
116
- }
117
-
118
- return makeStream(arg.bytes)
119
- }
120
-
121
- class StreamImpl implements Stream {
122
- readonly bytes: Uint8Array
123
-
124
- pos: number
125
-
126
- /**
127
- * @param bytes
128
- * @param pos
129
- */
130
- constructor(bytes: Uint8Array, pos: number = 0) {
131
- this.bytes = bytes
132
- this.pos = pos
133
- }
134
-
135
- /**
136
- * Copy ByteStream so mutations doesn't change original ByteStream
137
- * @returns
138
- */
139
- copy(): Stream {
140
- return new StreamImpl(this.bytes, this.pos)
141
- }
142
-
143
- isAtEnd(): boolean {
144
- return this.pos >= this.bytes.length
145
- }
146
-
147
- /**
148
- * @returns
149
- * The byte at the current position
150
- */
151
- peekOne(): Effect.Effect<number, EndOfStreamError> {
152
- if (this.pos < this.bytes.length) {
153
- return Effect.succeed(this.bytes[this.pos])
154
- } else {
155
- return Effect.fail(new EndOfStreamError(this))
156
- }
157
- }
158
-
159
- /**
160
- * @param n
161
- * @returns
162
- * @throws
163
- * If n is negative
164
- */
165
- peekMany(n: number): Effect.Effect<number[], EndOfStreamError> {
166
- if (n < 0) {
167
- throw new RangeError(`Unexpected negative n: ${n}`)
168
- }
169
-
170
- if (this.pos + n <= this.bytes.length) {
171
- return Effect.succeed(
172
- Array.from(this.bytes.slice(this.pos, this.pos + n))
173
- )
174
- } else {
175
- return Effect.fail(new EndOfStreamError(this))
176
- }
177
- }
178
-
179
- peekRemaining(): number[] {
180
- return Array.from(this.bytes.slice(this.pos))
181
- }
182
-
183
- /**
184
- * @returns
185
- * @throws
186
- * If at end
187
- */
188
- shiftOne(): Effect.Effect<number, EndOfStreamError> {
189
- if (this.pos < this.bytes.length) {
190
- const b = this.bytes[this.pos]
191
- this.pos += 1
192
- return Effect.succeed(b)
193
- } else {
194
- return Effect.fail(new EndOfStreamError(this))
195
- }
196
- }
197
-
198
- /**
199
- * @param n
200
- * @returns {number[]}
201
- * @throws
202
- * If n is negative
203
- */
204
- shiftMany(n: number): Effect.Effect<number[], EndOfStreamError> {
205
- if (n < 0) {
206
- throw new RangeError(`Unexpected negative n: ${n}`)
207
- }
208
-
209
- if (this.pos + n <= this.bytes.length) {
210
- const res = Array.from(this.bytes.slice(this.pos, this.pos + n))
211
- this.pos += n
212
- return Effect.succeed(res)
213
- } else {
214
- return Effect.fail(new EndOfStreamError(this))
215
- }
216
- }
217
-
218
- shiftRemaining(): number[] {
219
- const res = Array.from(this.bytes.slice(this.pos))
220
- this.pos = this.bytes.length
221
- return res
222
- }
223
- }
224
-
225
- /**
226
- * @param a
227
- * @param b
228
- * @param shortestFirst defaults to false (strictly lexicographic comparison)
229
- * @returns
230
- * -1 if a < b, 0 if a == b, 1 if a > b
231
- */
232
- export function compare(
233
- a: string | number[] | Uint8Array | Stream,
234
- b: string | number[] | Uint8Array | Stream,
235
- shortestFirst: boolean = false
236
- ): -1 | 0 | 1 {
237
- const la = toArray(a)
238
- const lb = toArray(b)
239
- const na = la.length
240
- const nb = lb.length
241
-
242
- if (shortestFirst && na != nb) {
243
- return na < nb ? -1 : 1
244
- }
245
-
246
- for (let i = 0; i < Math.min(na, nb); i++) {
247
- if (la[i] < lb[i]) {
248
- return -1
249
- } else if (la[i] > lb[i]) {
250
- return 1
251
- }
252
- }
253
-
254
- if (na != nb) {
255
- return na < nb ? -1 : 1
256
- } else {
257
- return 0
258
- }
259
- }
260
-
261
- /**
262
- * Used to create dummy hashes for testing
263
- * @param n
264
- * @param seed
265
- * @returns
266
- */
267
- export function dummy(n: number, seed: number = 0): number[] {
268
- return pad(encodeIntBE(seed), n).slice(0, n)
269
- }
270
-
271
- /**
272
- * @param a
273
- * @param b
274
- * @returns
275
- */
276
- export function equals(
277
- a: string | number[] | Uint8Array | Stream,
278
- b: string | number[] | Uint8Array | Stream
279
- ): boolean {
280
- return compare(a, b) == 0
281
- }
282
-
283
- /**
284
- * Pad by appending zeroes.
285
- * If `n < nCurrent`, pad to next multiple of `n`.
286
- * @param bytes
287
- * @param n pad length
288
- * @returns
289
- * @throws
290
- * If pad length is zero or negative
291
- */
292
- export function pad(bytes: number[], n: number): number[] {
293
- const nBytes = bytes.length
294
-
295
- if (nBytes == n) {
296
- return bytes
297
- } else if (n <= 0) {
298
- throw new Error(`Invalid pad length (must be > 0, got ${n})`)
299
- } else if (nBytes % n != 0 || nBytes == 0) {
300
- // padded to multiple of n
301
- const nPad = n - (nBytes % n)
302
-
303
- bytes = bytes.concat(new Array(nPad).fill(0))
304
- }
305
-
306
- return bytes
307
- }
308
-
309
- /**
310
- * Pad by prepending zeroes.
311
- * Throws an error
312
- * @param bytes
313
- * @param n prepad length
314
- * @returns
315
- * @throws
316
- * If prepad length is zero or negative
317
- * @throws
318
- * if bytes.length > n
319
- */
320
- export function prepad(bytes: number[], n: number): number[] {
321
- const nBytes = bytes.length
322
-
323
- if (nBytes == n) {
324
- return bytes
325
- } else if (n <= 0) {
326
- throw new Error(`Invalid prepad length (must be > 0, got ${n})`)
327
- } else if (nBytes > n) {
328
- throw new Error(
329
- `Padding goal length smaller than bytes length (${n} < ${nBytes})`
330
- )
331
- } else {
332
- const nPad = n - nBytes
333
-
334
- return new Array(nPad).fill(0).concat(bytes) as number[]
335
- }
336
- }
337
-
338
- export function DecodeException(
339
- bytes: string | number[] | Uint8Array | Stream,
340
- message: string
341
- ) {
342
- return Encoding.DecodeException(toHex(bytes), message)
343
- }