@aidc-toolkit/utility 0.9.6-beta → 0.9.8-beta

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.
@@ -1,8 +1,8 @@
1
- import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
1
+ import { I18NEnvironment } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
- import { EncryptionTransformer, IdentityTransformer, Sequencer, Transformer } from "../src/index.js";
3
+ import { EncryptionTransformer, i18nUtilityInit, IdentityTransformer, Sequencer, Transformer } from "../src/index.js";
4
4
 
5
- await i18nInit(I18NEnvironment.CLI);
5
+ await i18nUtilityInit(I18NEnvironment.CLI);
6
6
 
7
7
  function testTransformer(domain: number, tweak?: number, callback?: (value: bigint, forwardValue: bigint) => void): void {
8
8
  const transformer = Transformer.get(domain, tweak);
@@ -139,3 +139,31 @@ describe("Encryption", () => {
139
139
  expect(Transformer.get(1000000n, 1234567n).forward(987654n)).toBe(639402n);
140
140
  });
141
141
  });
142
+
143
+ describe("Non-sequencer", () => {
144
+ function testIterables(sequencer: Sequencer): void {
145
+ const nonSequencer = Array.from(sequencer);
146
+
147
+ const transformer = Transformer.get(1000n, 1234n);
148
+
149
+ const sequencerForward = transformer.forward(sequencer);
150
+ const nonSequencerForward = transformer.forward(nonSequencer);
151
+
152
+ const nonSequencerIterator = nonSequencerForward[Symbol.iterator]();
153
+
154
+ for (const sequencerValue of sequencerForward) {
155
+ const nonSequencerNext = nonSequencerIterator.next();
156
+
157
+ expect(nonSequencerNext.done).not.toBe(true);
158
+ expect(nonSequencerNext.value).toBe(sequencerValue);
159
+ }
160
+ }
161
+
162
+ test("Ascending", () => {
163
+ testIterables(new Sequencer(0, 10));
164
+ });
165
+
166
+ test("Descending", () => {
167
+ testIterables(new Sequencer(9, -10));
168
+ });
169
+ });
@@ -1,517 +0,0 @@
1
- /**
2
- * Iteration source; shortcut for iterator or iterable.
3
- *
4
- * Client applications should **not** rely on long-term availability of this variable as it will be removed once there
5
- * is widespread support for iterator helpers.
6
- */
7
- type IterationSource<T> = Iterator<T> | Iterable<T>;
8
-
9
- /**
10
- * Iterator proxy base; provides common functionality for all iterator objects.
11
- */
12
- abstract class IteratorProxyBase<TInitial, TFinal> implements IteratorObject<TFinal, undefined> {
13
- /**
14
- * Convert an iteration source to an iterable.
15
- *
16
- * @param iterationSource
17
- * Iteration source.
18
- *
19
- * @returns
20
- * Iteration source if it is already an iterable, otherwise iteration source wrapped in an iterable.
21
- */
22
- protected static toIterable<T>(iterationSource: IterationSource<T>): Iterable<T> {
23
- return Symbol.iterator in iterationSource ?
24
- iterationSource :
25
- {
26
- [Symbol.iterator](): Iterator<T> {
27
- return iterationSource;
28
- }
29
- };
30
- }
31
-
32
- /**
33
- * Initial iterable.
34
- */
35
- private readonly _initialIterable: Iterable<TInitial>;
36
-
37
- /**
38
- * Initial iterator.
39
- */
40
- private _initialIterator?: Iterator<TInitial>;
41
-
42
- /**
43
- * Constructor.
44
- *
45
- * @param initialIterationSource
46
- * Initial iteration source.
47
- */
48
- constructor(initialIterationSource: IterationSource<TInitial>) {
49
- this._initialIterable = IteratorProxyBase.toIterable(initialIterationSource);
50
- }
51
-
52
- /**
53
- * Get the initial iterable.
54
- */
55
- protected get initialIterable(): Iterable<TInitial> {
56
- return this._initialIterable;
57
- }
58
-
59
- /**
60
- * Get the initial iterator.
61
- */
62
- protected get initialIterator(): Iterator<TInitial> {
63
- if (this._initialIterator === undefined) {
64
- this._initialIterator = this.initialIterable[Symbol.iterator]();
65
- }
66
-
67
- return this._initialIterator;
68
- }
69
-
70
- /**
71
- * @inheritDoc
72
- */
73
- get [Symbol.toStringTag](): string {
74
- return "IteratorProxy";
75
- }
76
-
77
- /**
78
- * @inheritDoc
79
- */
80
- [Symbol.dispose](): void {
81
- }
82
-
83
- /**
84
- * @inheritDoc
85
- */
86
- [Symbol.iterator](): IteratorObject<TFinal, undefined> {
87
- return this;
88
- }
89
-
90
- /**
91
- * Get the next result from the initial iterator.
92
- *
93
- * @param value
94
- * Tuple value to be passed to Iterator.next().
95
- *
96
- * @returns
97
- * Next result from the initial iterator.
98
- */
99
- protected initialNext(...value: [] | [unknown]): IteratorResult<TInitial, undefined> {
100
- return this.initialIterator.next(...value);
101
- }
102
-
103
- /**
104
- * @inheritDoc
105
- */
106
- abstract next(...value: [] | [unknown]): IteratorResult<TFinal, undefined>;
107
-
108
- /**
109
- * @inheritDoc
110
- */
111
- map<U>(callback: (value: TFinal, index: number) => U): IteratorObject<U, undefined> {
112
- return new IteratorMapProxy(this, callback);
113
- }
114
-
115
- /**
116
- * @inheritDoc
117
- */
118
- flatMap<U>(callback: (value: TFinal, index: number) => IterationSource<U>): IteratorObject<U, undefined> {
119
- return new IteratorFlatMapProxy(this, callback);
120
- }
121
-
122
- /**
123
- * @inheritDoc
124
- */
125
- filter(predicate: (value: TFinal, index: number) => unknown): IteratorObject<TFinal, undefined> {
126
- return new IteratorFilterProxy(this, predicate, true);
127
- }
128
-
129
- /**
130
- * @inheritDoc
131
- */
132
- take(limit: number): IteratorObject<TFinal, undefined> {
133
- return new IteratorTakeProxy(this, limit);
134
- }
135
-
136
- /**
137
- * @inheritDoc
138
- */
139
- drop(count: number): IteratorObject<TFinal, undefined> {
140
- return new IteratorDropProxy(this, count);
141
- }
142
-
143
- /**
144
- * @inheritDoc
145
- */
146
- reduce<U>(callback: (previousValue: U, currentValue: TFinal, currentIndex: number) => U, initialValue?: U): U {
147
- let index = 0;
148
- let result = initialValue;
149
-
150
- for (const value of this) {
151
- // Need to check arguments length as U could include undefined.
152
- if (index === 0 && arguments.length === 1) {
153
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Initial value is not supplied only when U is identical to TFinal.
154
- result = value as unknown as U;
155
- } else {
156
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Iteration has occurred at least once so result is of the expected type.
157
- result = callback(result as U, value, index);
158
- }
159
-
160
- index++;
161
- }
162
-
163
- if (index === 0 && arguments.length === 1) {
164
- throw new Error("reduce() of empty iterator with no initial value");
165
- }
166
-
167
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Iteration has occurred at least once so result is of the expected type.
168
- return result as U;
169
- }
170
-
171
- /**
172
- * @inheritDoc
173
- */
174
- toArray(): TFinal[] {
175
- return Array.from(this);
176
- }
177
-
178
- /**
179
- * @inheritDoc
180
- */
181
- forEach(callback: (value: TFinal, index: number) => void): void {
182
- let index = 0;
183
-
184
- for (const element of this) {
185
- callback(element, index++);
186
- }
187
- }
188
-
189
- /**
190
- * @inheritDoc
191
- */
192
- some(predicate: (value: TFinal, index: number) => unknown): boolean {
193
- // Filter until predicate returns truthy; return true if found.
194
- return new IteratorFilterProxy(this, predicate, true).next().done !== true;
195
- }
196
-
197
- /**
198
- * @inheritDoc
199
- */
200
- every(predicate: (value: TFinal, index: number) => unknown): boolean {
201
- // Filter until predicate returns falsy; return false if found.
202
- return new IteratorFilterProxy(this, predicate, false).next().done === true;
203
- }
204
-
205
- /**
206
- * @inheritDoc
207
- */
208
- find(predicate: (value: TFinal, index: number) => unknown): TFinal | undefined {
209
- // Filter until predicate returns truthy; return value.
210
- return new IteratorFilterProxy(this, predicate, true).next().value;
211
- }
212
- }
213
-
214
- /**
215
- * Core iterator proxy object.
216
- */
217
- class IteratorProxyObject<T> extends IteratorProxyBase<T, T> {
218
- /**
219
- * @inheritDoc
220
- */
221
- next(...value: [] | [unknown]): IteratorResult<T, undefined> {
222
- // Initial result is the final result.
223
- return this.initialNext(...value);
224
- }
225
- }
226
-
227
- /**
228
- * Iterator map proxy base.
229
- */
230
- abstract class IteratorMapProxyBase<TInitial, TIntermediate, TFinal> extends IteratorProxyBase<TInitial, TFinal> {
231
- /**
232
- * Callback.
233
- */
234
- private readonly _callback: (element: TInitial, index: number) => TIntermediate;
235
-
236
- /**
237
- * Index into initial iteration source.
238
- */
239
- private _index: number;
240
-
241
- /**
242
- * Constructor.
243
- *
244
- * @param initialIterationSource
245
- * Initial iteration source.
246
- *
247
- * @param callback
248
- * Callback.
249
- */
250
- constructor(initialIterationSource: IterationSource<TInitial>, callback: (element: TInitial, index: number) => TIntermediate) {
251
- super(initialIterationSource);
252
-
253
- this._callback = callback;
254
- this._index = 0;
255
- }
256
-
257
- /**
258
- * Get the next result from the intermediate iterator.
259
- *
260
- * @param value
261
- * Tuple value to be passed to Iterator.next().
262
- *
263
- * @returns
264
- * Next result from the intermediate iterator.
265
- */
266
- protected intermediateNext(...value: [] | [unknown]): IteratorResult<TIntermediate, undefined> {
267
- const initialResult = this.initialNext(...value);
268
-
269
- return initialResult.done !== true ?
270
- {
271
- value: this._callback(initialResult.value, this._index++)
272
- } :
273
- {
274
- done: true,
275
- value: undefined
276
- };
277
- }
278
- }
279
-
280
- /**
281
- * Iterator map proxy.
282
- */
283
- class IteratorMapProxy<TInitial, TFinal> extends IteratorMapProxyBase<TInitial, TFinal, TFinal> {
284
- /**
285
- * @inheritDoc
286
- */
287
- next(...value: [] | [unknown]): IteratorResult<TFinal, undefined> {
288
- // Intermediate result is the final result.
289
- return this.intermediateNext(...value);
290
- }
291
- }
292
-
293
- /**
294
- * Iterator flat map proxy.
295
- */
296
- class IteratorFlatMapProxy<TInitial, TFinal> extends IteratorMapProxyBase<TInitial, IterationSource<TFinal>, TFinal> {
297
- private _intermediateIterator: Iterator<TFinal, undefined> | undefined;
298
-
299
- /**
300
- * @inheritDoc
301
- */
302
- next(...value: [] | [unknown]): IteratorResult<TFinal, undefined> {
303
- let finalResult: IteratorResult<TFinal, undefined> | undefined = undefined;
304
-
305
- do {
306
- if (this._intermediateIterator === undefined) {
307
- const intermediateResult = this.intermediateNext(...value);
308
-
309
- if (intermediateResult.done === true) {
310
- finalResult = intermediateResult;
311
- } else {
312
- this._intermediateIterator = IteratorProxyBase.toIterable(intermediateResult.value)[Symbol.iterator]();
313
- }
314
- } else {
315
- const pendingFinalResult = this._intermediateIterator.next();
316
-
317
- if (pendingFinalResult.done === true) {
318
- this._intermediateIterator = undefined;
319
- } else {
320
- finalResult = pendingFinalResult;
321
- }
322
- }
323
- } while (finalResult === undefined);
324
-
325
- return finalResult;
326
- }
327
- }
328
-
329
- /**
330
- * Iterator filter proxy.
331
- */
332
- class IteratorFilterProxy<T> extends IteratorProxyBase<T, T> {
333
- /**
334
- * Predicate.
335
- */
336
- private readonly _predicate: (value: T, index: number) => unknown;
337
-
338
- /**
339
- * Expected truthy result of the predicate.
340
- */
341
- private readonly _expectedTruthy: boolean;
342
-
343
- /**
344
- * Index into iteration source.
345
- */
346
- private _index: number;
347
-
348
- /**
349
- * Constructor.
350
- *
351
- * @param iterationSource
352
- * Iteration source.
353
- *
354
- * @param predicate
355
- * Predicate.
356
- *
357
- * @param expectedTruthy
358
- * Expected truthy result of the predicate.
359
- */
360
- constructor(iterationSource: IterationSource<T>, predicate: (element: T, index: number) => unknown, expectedTruthy: boolean) {
361
- super(iterationSource);
362
-
363
- this._predicate = predicate;
364
- this._expectedTruthy = expectedTruthy;
365
-
366
- this._index = 0;
367
- }
368
-
369
- /**
370
- * @inheritDoc
371
- */
372
- next(...value: [] | [unknown]): IteratorResult<T, undefined> {
373
- let result: IteratorResult<T, undefined> | undefined;
374
-
375
- const expectedTruthy = this._expectedTruthy;
376
-
377
- do {
378
- result = this.initialNext(...value);
379
- } while (result.done !== true && Boolean(this._predicate(result.value, this._index++)) !== expectedTruthy);
380
-
381
- return result;
382
- }
383
- }
384
-
385
- /**
386
- * Iterator count proxy base.
387
- */
388
- abstract class IteratorCountProxyBase<T> extends IteratorProxyObject<T> {
389
- /**
390
- * Count.
391
- */
392
- private _count: number;
393
-
394
- /**
395
- * Constructor.
396
- *
397
- * @param initialIterationSource
398
- * Initial iteration source.
399
- *
400
- * @param count
401
- * Count.
402
- */
403
- constructor(initialIterationSource: IterationSource<T>, count: number) {
404
- super(initialIterationSource);
405
-
406
- if (!Number.isInteger(count) || count < 0) {
407
- throw new RangeError("Count must be a positive integer");
408
- }
409
-
410
- this._count = count;
411
- }
412
-
413
- /**
414
- * Determine if iterator is exhausted (by count or by iterator itself).
415
- */
416
- protected get exhausted(): boolean {
417
- return this._count <= 0;
418
- }
419
-
420
- /**
421
- * @inheritDoc
422
- */
423
- override next(...value: [] | [unknown]): IteratorResult<T, undefined> {
424
- const result = super.next(...value);
425
-
426
- if (result.done !== true) {
427
- this._count--;
428
- } else {
429
- // Iterator exhausted before count.
430
- this._count = 0;
431
- }
432
-
433
- return result;
434
- }
435
- }
436
-
437
- /**
438
- * Iterator take proxy.
439
- */
440
- class IteratorTakeProxy<T> extends IteratorCountProxyBase<T> {
441
- /**
442
- * @inheritDoc
443
- */
444
- override next(...value: [] | [unknown]): IteratorResult<T, undefined> {
445
- return !this.exhausted ?
446
- super.next(...value) :
447
- {
448
- done: true,
449
- value: undefined
450
- };
451
- }
452
- }
453
-
454
- /**
455
- * Iterator drop proxy.
456
- */
457
- class IteratorDropProxy<T> extends IteratorCountProxyBase<T> {
458
- /**
459
- * @inheritDoc
460
- */
461
- override next(...value: [] | [unknown]): IteratorResult<T, undefined> {
462
- while (!this.exhausted) {
463
- super.next(...value);
464
- }
465
-
466
- return super.next(...value);
467
- }
468
- }
469
-
470
- /**
471
- * Get Iterator variable if supported or a proxy for it if not.
472
- *
473
- * @returns
474
- * Iterator variable if supported or a proxy for it if not.
475
- */
476
- function iteratorProxy(): Pick<typeof Iterator, "from"> {
477
- let supported: boolean;
478
-
479
- try {
480
- // Not supported if in testing.
481
- supported = process.env["NODE_ENV"] !== "test";
482
- } catch (_e) {
483
- // Assume supported.
484
- supported = true;
485
- }
486
-
487
- if (supported) {
488
- try {
489
- // This will throw a ReferenceError if Iterator variable is not supported.
490
- Iterator.from([]);
491
- } catch (_e) {
492
- supported = false;
493
- }
494
- }
495
-
496
- return supported ?
497
- Iterator :
498
- {
499
- /**
500
- * @inheritDoc
501
- */
502
- from<T>(value: Iterator<T> | Iterable<T>): IteratorObject<T, undefined> {
503
- return value instanceof IteratorProxyBase ? value : new IteratorProxyObject(value);
504
- }
505
- };
506
- }
507
-
508
- /**
509
- * Iterator proxy. In environments where
510
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator#iterator_helpers |
511
- * iterator helpers} are supported, this references the {@linkcode Iterator} variable directly. Otherwise, it references
512
- * an implementation of "from" that uses an internally-defined iterator proxy object.
513
- *
514
- * Client applications should **not** rely on long-term availability of this variable as it will be removed once there
515
- * is widespread support for iterator helpers.
516
- */
517
- export const IteratorProxy = iteratorProxy();
package/src/types.ts DELETED
@@ -1,46 +0,0 @@
1
- /**
2
- * Transformer input, one of:
3
- *
4
- * - T (primitive type)
5
- * - Iterable<T>
6
- *
7
- * @template T
8
- * Primitive type.
9
- */
10
- export type TransformerInput<T extends string | number | bigint | boolean> =
11
- T | Iterable<T>;
12
-
13
- /**
14
- * Transformer callback, used to convert transformed value to its final value.
15
- *
16
- * @template TInput
17
- * Type of input to callback.
18
- *
19
- * @template TOutput
20
- * Type of output to callback.
21
- *
22
- * @param input
23
- * Input value.
24
- *
25
- * @param index
26
- * Index in sequence (0 for single transformation).
27
- *
28
- * @returns
29
- * Output value.
30
- */
31
- export type TransformerCallback<TInput, TOutput> = (input: TInput, index: number) => TOutput;
32
-
33
- /**
34
- * Transformer output, based on transformer input:
35
- *
36
- * - If type T is primitive type, result is type U.
37
- * - If type T is Iterable type, result is type IterableIterator<U>.
38
- *
39
- * @template T
40
- * Transformer input type.
41
- *
42
- * @template U
43
- * Output base type.
44
- */
45
- export type TransformerOutput<T extends TransformerInput<string | number | bigint | boolean>, U> =
46
- T extends (T extends TransformerInput<infer V> ? V : never) ? U : IterableIterator<U>;