@aidc-toolkit/app-extension 1.0.31-beta → 1.0.32-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.
Files changed (40) hide show
  1. package/dist/index.cjs +3446 -627
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +575 -300
  4. package/dist/index.d.ts +575 -300
  5. package/dist/index.js +3435 -610
  6. package/dist/index.js.map +1 -1
  7. package/package.json +8 -9
  8. package/src/app-data.ts +94 -0
  9. package/src/app-extension.ts +162 -93
  10. package/src/app-utility-proxy.ts +154 -103
  11. package/src/descriptor.ts +33 -6
  12. package/src/generator/generator.ts +3 -6
  13. package/src/generator/locale-resources-generator.ts +30 -28
  14. package/src/gs1/character-set-proxy.ts +8 -8
  15. package/src/gs1/check-proxy.ts +14 -14
  16. package/src/gs1/gtin-creator-proxy.ts +12 -25
  17. package/src/gs1/gtin-descriptor.ts +0 -21
  18. package/src/gs1/gtin-validator-proxy.ts +34 -35
  19. package/src/gs1/identifier-creator-proxy.ts +44 -32
  20. package/src/gs1/identifier-descriptor.ts +15 -0
  21. package/src/gs1/identifier-type.ts +37 -0
  22. package/src/gs1/identifier-validator-proxy.ts +52 -19
  23. package/src/gs1/index.ts +8 -0
  24. package/src/gs1/non-gtin-creator-proxy.ts +22 -22
  25. package/src/gs1/non-gtin-validator-proxy.ts +22 -22
  26. package/src/gs1/prefix-manager-proxy.ts +199 -4
  27. package/src/gs1/service-proxy.ts +56 -0
  28. package/src/gs1/variable-measure-proxy.ts +61 -0
  29. package/src/index.ts +6 -0
  30. package/src/lib-proxy.ts +112 -70
  31. package/src/locale/en/locale-resources.ts +147 -34
  32. package/src/locale/fr/locale-resources.ts +147 -34
  33. package/src/locale/i18n.ts +2 -5
  34. package/src/proxy.ts +82 -106
  35. package/src/streaming.ts +13 -0
  36. package/src/type.ts +8 -7
  37. package/src/utility/character-set-proxy.ts +33 -32
  38. package/src/utility/reg-exp-proxy.ts +7 -6
  39. package/src/utility/string-proxy.ts +3 -7
  40. package/src/utility/transformer-proxy.ts +19 -13
@@ -0,0 +1,56 @@
1
+ import { isNullish, type Nullishable } from "@aidc-toolkit/core";
2
+ import { verifiedByGS1 } from "@aidc-toolkit/gs1";
3
+ import { type ExtendsParameterDescriptor, type ParameterDescriptor, Types } from "../descriptor.js";
4
+ import { LibProxy } from "../lib-proxy.js";
5
+ import { proxy } from "../proxy.js";
6
+ import type { ErrorExtends, Matrix, MatrixResult } from "../type.js";
7
+ import { identifierParameterDescriptor, identifierTypeParameterDescriptor } from "./identifier-descriptor.js";
8
+ import { validateIdentifierType } from "./identifier-type.js";
9
+
10
+ const hyperlinkIdentifierParameterDescriptor: ExtendsParameterDescriptor = {
11
+ extendsDescriptor: identifierParameterDescriptor,
12
+ name: "hyperlinkIdentifier"
13
+ };
14
+
15
+ const hyperlinkTextParameterDescriptor: ParameterDescriptor = {
16
+ name: "hyperlinkText",
17
+ type: Types.String,
18
+ isMatrix: false,
19
+ isRequired: false
20
+ };
21
+
22
+ const hyperlinkDetailsParameterDescriptor: ParameterDescriptor = {
23
+ name: "hyperlinkDetails",
24
+ type: Types.String,
25
+ isMatrix: false,
26
+ isRequired: false
27
+ };
28
+
29
+ @proxy.describeClass(false, {
30
+ namespace: "GS1"
31
+ })
32
+ export class ServiceProxy<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TStreamingInvocationContext, TBigInt> extends LibProxy<ThrowError, TError, TInvocationContext, TStreamingInvocationContext, TBigInt> {
33
+ @proxy.describeMethod({
34
+ type: Types.Any,
35
+ isMatrix: true,
36
+ requiresContext: true,
37
+ parameterDescriptors: [
38
+ identifierTypeParameterDescriptor,
39
+ hyperlinkIdentifierParameterDescriptor,
40
+ hyperlinkTextParameterDescriptor,
41
+ hyperlinkDetailsParameterDescriptor
42
+ ]
43
+ })
44
+ async verifiedByGS1(identifierType: string, matrixIdentifiers: Matrix<string>, text: Nullishable<string>, details: Nullishable<string>, invocationContext: Nullishable<TInvocationContext>): Promise<MatrixResult<unknown, ThrowError, TError>> {
45
+ if (isNullish(invocationContext)) {
46
+ // Application error; no localization necessary.
47
+ throw new Error("Invocation context not provided by application");
48
+ }
49
+
50
+ return this.appExtension.mapHyperlinkResults(invocationContext, this.setUpMatrixResult(() =>
51
+ validateIdentifierType(identifierType),
52
+ matrixIdentifiers, (validatedIdentifierType, identifier) =>
53
+ verifiedByGS1(validatedIdentifierType, identifier, text ?? undefined, details ?? undefined)
54
+ ));
55
+ }
56
+ }
@@ -0,0 +1,61 @@
1
+ import { VariableMeasure } from "@aidc-toolkit/gs1";
2
+ import { type ParameterDescriptor, Types } from "../descriptor.js";
3
+ import { LibProxy } from "../lib-proxy.js";
4
+ import { proxy } from "../proxy.js";
5
+ import type { ErrorExtends, Matrix, MatrixResult } from "../type.js";
6
+
7
+ const rcnFormatParameterDescriptor: ParameterDescriptor = {
8
+ name: "rcnFormat",
9
+ type: Types.String,
10
+ isMatrix: false,
11
+ isRequired: true
12
+ };
13
+
14
+ const rcnParameterDescriptor: ParameterDescriptor = {
15
+ name: "rcn",
16
+ type: Types.String,
17
+ isMatrix: true,
18
+ isRequired: true
19
+ };
20
+
21
+ const rcnItemReferenceParameterDescriptor: ParameterDescriptor = {
22
+ name: "rcnItemReference",
23
+ type: Types.Number,
24
+ isMatrix: false,
25
+ isRequired: true
26
+ };
27
+
28
+ const rcnPriceOrWeightParameterDescriptor: ParameterDescriptor = {
29
+ name: "rcnPriceOrWeight",
30
+ type: Types.Number,
31
+ isMatrix: true,
32
+ isRequired: true
33
+ };
34
+
35
+ @proxy.describeClass(false, {
36
+ namespace: "GS1"
37
+ })
38
+ export class VariableMeasureProxy<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TStreamingInvocationContext, TBigInt> extends LibProxy<ThrowError, TError, TInvocationContext, TStreamingInvocationContext, TBigInt> {
39
+ @proxy.describeMethod({
40
+ type: Types.Number,
41
+ isMatrix: true,
42
+ parameterDescriptors: [rcnFormatParameterDescriptor, rcnParameterDescriptor]
43
+ })
44
+ parseVariableMeasureRCN(format: string, matrixRCNs: Matrix<string>): MatrixResult<number, ThrowError, TError> {
45
+ return this.arrayResult(matrixRCNs, (rcn) => {
46
+ const rcnReference = VariableMeasure.parseRCN(format, rcn);
47
+
48
+ return [rcnReference.itemReference, rcnReference.priceOrWeight];
49
+ });
50
+ }
51
+
52
+ @proxy.describeMethod({
53
+ type: Types.String,
54
+ isMatrix: true,
55
+ ignoreInfix: true,
56
+ parameterDescriptors: [rcnFormatParameterDescriptor, rcnItemReferenceParameterDescriptor, rcnPriceOrWeightParameterDescriptor]
57
+ })
58
+ createVariableMeasureRCN(format: string, itemReference: number, matrixPricesOrWeights: Matrix<number>): MatrixResult<string, ThrowError, TError> {
59
+ return this.matrixResult(matrixPricesOrWeights, priceOrWeight => VariableMeasure.createRCN(format, itemReference, priceOrWeight));
60
+ }
61
+ }
package/src/index.ts CHANGED
@@ -15,12 +15,18 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  export * from "./locale/i18n.js";
18
+
18
19
  export type * from "./type.js";
20
+ export * from "./app-data.js";
21
+
22
+ export type * from "./streaming.js";
19
23
  export * from "./app-extension.js";
20
24
  export * from "./lib-proxy.js";
25
+
21
26
  export * from "./descriptor.js";
22
27
  export * from "./app-utility-proxy.js";
23
28
  export * from "./utility/index.js";
24
29
  export * as GS1 from "./gs1/index.js";
30
+
25
31
  export * from "./generator/index.js";
26
32
  export { expandParameterDescriptor } from "./proxy.js";
package/src/lib-proxy.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { mapIterable } from "@aidc-toolkit/utility";
2
2
  import type { AppExtension } from "./app-extension.js";
3
3
  import { i18nextAppExtension } from "./locale/i18n.js";
4
- import type { ErrorExtends, Matrix, MatrixResultError, ResultError } from "./type.js";
4
+ import type { ErrorExtends, Matrix, MatrixResult, SingletonResult } from "./type.js";
5
5
 
6
6
  /**
7
7
  * Library proxy.
@@ -15,14 +15,17 @@ import type { ErrorExtends, Matrix, MatrixResultError, ResultError } from "./typ
15
15
  * @template TInvocationContext
16
16
  * Application-specific invocation context type.
17
17
  *
18
+ * @template TStreamingInvocationContext
19
+ * Application-specific streaming invocation context type.
20
+ *
18
21
  * @template TBigInt
19
22
  * Type to which big integer is mapped.
20
23
  */
21
- export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt> {
24
+ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TStreamingInvocationContext, TBigInt> {
22
25
  /**
23
26
  * Application extension.
24
27
  */
25
- readonly #appExtension: AppExtension<ThrowError, TError, TInvocationContext, TBigInt>;
28
+ readonly #appExtension: AppExtension<ThrowError, TError, TInvocationContext, TStreamingInvocationContext, TBigInt>;
26
29
 
27
30
  /**
28
31
  * Constructor.
@@ -30,14 +33,14 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
30
33
  * @param appExtension
31
34
  * Application extension.
32
35
  */
33
- constructor(appExtension: AppExtension<ThrowError, TError, TInvocationContext, TBigInt>) {
36
+ constructor(appExtension: AppExtension<ThrowError, TError, TInvocationContext, TStreamingInvocationContext, TBigInt>) {
34
37
  this.#appExtension = appExtension;
35
38
  }
36
39
 
37
40
  /**
38
41
  * Get the application extension.
39
42
  */
40
- get appExtension(): AppExtension<ThrowError, TError, TInvocationContext, TBigInt> {
43
+ get appExtension(): AppExtension<ThrowError, TError, TInvocationContext, TStreamingInvocationContext, TBigInt> {
41
44
  return this.#appExtension;
42
45
  }
43
46
 
@@ -50,12 +53,13 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
50
53
  * @returns
51
54
  * Mapped big integer value.
52
55
  */
53
- mapBigInt(value: bigint): ResultError<TBigInt, ThrowError, TError> {
56
+ mapBigInt(value: bigint): SingletonResult<TBigInt, ThrowError, TError> {
54
57
  return this.#appExtension.mapBigInt(value);
55
58
  }
56
59
 
57
60
  /**
58
- * Handle an error thrown by a function call.
61
+ * Handle an error thrown by a function call. Return type is {@linkcode SingletonResult} to ensure assignment
62
+ * compatibility.
59
63
  *
60
64
  * @param e
61
65
  * Error.
@@ -63,8 +67,8 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
63
67
  * @returns
64
68
  * Error if errors are not thrown.
65
69
  */
66
- #handleError<TResult>(e: unknown): ResultError<TResult, ThrowError, TError> {
67
- let result: ResultError<TResult, ThrowError, TError>;
70
+ #handleError<TResult>(e: unknown): SingletonResult<TResult, ThrowError, TError> {
71
+ let result: SingletonResult<TResult, ThrowError, TError>;
68
72
 
69
73
  if (e instanceof RangeError) {
70
74
  const error = this.#appExtension.mapRangeError(e);
@@ -74,34 +78,30 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
74
78
  throw error as Error;
75
79
  }
76
80
 
77
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type determination is handled above.
78
- result = error as ResultError<TResult, ThrowError, TError>;
81
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Won't get here if ThrowError is false so result is TError.
82
+ result = error as SingletonResult<TResult, ThrowError, TError>;
79
83
  } else {
80
- // Unknown error; pass up the stack.
81
- // eslint-disable-next-line @typescript-eslint/only-throw-error -- Error is being passed on from elsewhere.
82
- throw e;
84
+ // Unknown error; pass on to application extension.
85
+ result = this.appExtension.handleError(e instanceof Error ? e.message : String(e));
83
86
  }
84
87
 
85
88
  return result;
86
89
  }
87
90
 
88
91
  /**
89
- * Do the callback for a simple return.
90
- *
91
- * @param value
92
- * Value.
92
+ * Call a singleton result function with error handling.
93
93
  *
94
94
  * @param callback
95
95
  * Callback.
96
96
  *
97
97
  * @returns
98
- * Callback result or error if errors are not thrown.
98
+ * Callback return or error if errors are not thrown.
99
99
  */
100
- #doCallback<TValue, TResult>(value: TValue, callback: (value: TValue) => TResult): ResultError<TResult, ThrowError, TError> {
101
- let result: ResultError<TResult, ThrowError, TError>;
100
+ singletonResult<TResult>(callback: () => SingletonResult<TResult, ThrowError, TError>): SingletonResult<TResult, ThrowError, TError> {
101
+ let result: SingletonResult<TResult, ThrowError, TError>;
102
102
 
103
103
  try {
104
- result = callback(value);
104
+ result = callback();
105
105
  } catch (e: unknown) {
106
106
  result = this.#handleError(e);
107
107
  }
@@ -110,19 +110,60 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
110
110
  }
111
111
 
112
112
  /**
113
- * Map a matrix of values using a callback.
113
+ * Call a matrix result function with error handling.
114
114
  *
115
115
  * @param matrixValues
116
116
  * Matrix of values.
117
117
  *
118
- * @param callback
119
- * Callback.
118
+ * @param valueCallback
119
+ * Callback to process value.
120
120
  *
121
121
  * @returns
122
122
  * Matrix of callback results and errors if errors are not thrown.
123
123
  */
124
- protected mapMatrix<TValue, TResult>(matrixValues: Matrix<TValue>, callback: (value: TValue) => TResult): MatrixResultError<TResult, ThrowError, TError> {
125
- return matrixValues.map(rowValues => rowValues.map(value => this.#doCallback(value, callback)));
124
+ protected matrixResult<TValue, TResult>(matrixValues: Matrix<TValue>, valueCallback: (value: TValue) => SingletonResult<TResult, ThrowError, TError>): MatrixResult<TResult, ThrowError, TError> {
125
+ return matrixValues.map(rowValues => rowValues.map(value => this.singletonResult(() => valueCallback(value))));
126
+ }
127
+
128
+ /**
129
+ * Map a matrix of validate string results to boolean. If the string is empty, the result is true, indicating that
130
+ * there is no error.
131
+ *
132
+ * @param matrixValidateResults
133
+ * Matrix of results from a call to a validate function.
134
+ *
135
+ * @returns
136
+ * Matrix of boolean values, true if corresponding string is empty.
137
+ */
138
+ protected isValidString(matrixValidateResults: MatrixResult<string, ThrowError, TError>): Matrix<boolean> {
139
+ return matrixValidateResults.map(rowValues => rowValues.map(value => (validateResult => validateResult === "")(value)));
140
+ }
141
+
142
+ /**
143
+ * Set up a mapping and call a matrix result function with error handling.
144
+ *
145
+ * @param setUpCallback
146
+ * Callback to set up the mapping.
147
+ *
148
+ * @param matrixValues
149
+ * Matrix of values.
150
+ *
151
+ * @param valueCallback
152
+ * Callback to process value.
153
+ *
154
+ * @returns
155
+ * Matrix of callback results and errors if errors are not thrown.
156
+ */
157
+ protected setUpMatrixResult<TSetup, TValue, TResult>(setUpCallback: () => TSetup, matrixValues: Matrix<TValue>, valueCallback: (setup: TSetup, value: TValue) => SingletonResult<TResult, ThrowError, TError>): MatrixResult<TResult, ThrowError, TError> {
158
+ let result: MatrixResult<TResult, ThrowError, TError>;
159
+
160
+ try {
161
+ result = matrixValues.map(rowValues => rowValues.map(value => this.singletonResult(() => valueCallback(setUpCallback(), value))));
162
+ } catch (e: unknown) {
163
+ result = [[this.#handleError(e)]];
164
+ }
165
+
166
+ return result;
126
167
  }
127
168
 
128
169
  /**
@@ -137,15 +178,15 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
137
178
  * @returns
138
179
  * Callback result or error as array if errors are not thrown.
139
180
  */
140
- #doArrayCallback<TValue, TResult>(value: TValue, callback: (value: TValue) => TResult[]): Array<ResultError<TResult, ThrowError, TError>> {
141
- const result = this.#doCallback(value, callback);
181
+ #arrayCallback<TValue, TResult>(value: TValue, callback: (value: TValue) => Array<SingletonResult<TResult, ThrowError, TError>>): Array<SingletonResult<TResult, ThrowError, TError>> {
182
+ const result = this.singletonResult(() => callback(value));
142
183
 
143
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Type determination is handled.
144
- return result instanceof Array ? result : [result as ResultError<TResult, ThrowError, TError>];
184
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- If result is not an array, it must be an error.
185
+ return result instanceof Array ? result : [result as SingletonResult<TResult, ThrowError, TError>];
145
186
  }
146
187
 
147
188
  /**
148
- * Map a one-dimensional matrix of values using a callback.
189
+ * Call an array result function with error handling and map to a matrix.
149
190
  *
150
191
  * @param matrixValues
151
192
  * Matrix of values.
@@ -156,65 +197,62 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
156
197
  * @returns
157
198
  * Matrix of callback results and errors if errors are not thrown.
158
199
  */
159
- protected mapArray<TValue, TResult>(matrixValues: Matrix<TValue>, callback: (value: TValue) => TResult[]): MatrixResultError<TResult, ThrowError, TError> {
160
- let matrixResultError: MatrixResultError<TResult, ThrowError, TError>;
200
+ protected arrayResult<TValue, TResult>(matrixValues: Matrix<TValue>, callback: (value: TValue) => Array<SingletonResult<TResult, ThrowError, TError>>): MatrixResult<TResult, ThrowError, TError> {
201
+ let result: MatrixResult<TResult, ThrowError, TError>;
161
202
 
162
203
  if (matrixValues.length === 0) {
163
204
  // Special case; unlikely to occur.
164
- matrixResultError = [[]];
205
+ result = [[]];
165
206
  } else if (matrixValues.length === 1) {
166
- matrixResultError = [];
207
+ result = [];
167
208
 
168
209
  matrixValues[0].forEach((value, columnIndex) => {
169
- const arrayResultError = this.#doArrayCallback(value, callback);
210
+ const arrayResult = this.#arrayCallback(value, callback);
170
211
 
171
- arrayResultError.forEach((resultError, rowIndex) => {
172
- if (matrixResultError.length <= rowIndex) {
173
- matrixResultError.push([]);
212
+ arrayResult.forEach((resultError, rowIndex) => {
213
+ // Append a row if necessary.
214
+ if (result.length <= rowIndex) {
215
+ result.push([]);
174
216
  }
175
217
 
176
- // Assignment will automatically expand array.
177
- matrixResultError[rowIndex][columnIndex] = resultError;
218
+ // Assignment will automatically expand row to the number of columns in the matrix.
219
+ result[rowIndex][columnIndex] = resultError;
178
220
  });
179
221
  });
180
222
  } else {
181
- matrixResultError = matrixValues.map((rowValue) => {
182
- let arrayResultError: Array<ResultError<TResult, ThrowError, TError>>;
223
+ result = matrixValues.map((rowValue) => {
224
+ let arrayResult: Array<SingletonResult<TResult, ThrowError, TError>>;
183
225
 
184
226
  if (rowValue.length === 0) {
185
227
  // Special case; unlikely to occur.
186
- arrayResultError = [];
228
+ arrayResult = [];
187
229
  } else if (rowValue.length === 1) {
188
- arrayResultError = this.#doArrayCallback(rowValue[0], callback);
230
+ arrayResult = this.#arrayCallback(rowValue[0], callback);
189
231
  } else {
190
- arrayResultError = [this.#handleError(new RangeError(i18nextAppExtension.t("Proxy.matrixMustBeArray")))];
232
+ arrayResult = [this.#handleError(new RangeError(i18nextAppExtension.t("Proxy.matrixMustBeArray")))];
191
233
  }
192
234
 
193
- return arrayResultError;
235
+ return arrayResult;
194
236
  });
195
237
  }
196
238
 
197
- return matrixResultError;
239
+ return result;
198
240
  }
199
241
 
200
242
  /**
201
- * Map a matrix of values to a matrix of strings via a callback that either returns or throws a range error. If the
202
- * callback returns, the result for that element is the empty string; otherwise, if it's a range error, the result
203
- * for that element is the error message.
243
+ * Call a matrix result function with error handling and map a non-error result to an empty string and {@linkcode
244
+ * RangeError} to the string error message.
204
245
  *
205
246
  * @param matrixValues
206
- * Matrix to map.
247
+ * Matrix of values.
207
248
  *
208
249
  * @param callback
209
250
  * Callback that either returns or throws an exception.
210
251
  *
211
252
  * @returns
212
253
  * Matrix of strings.
213
- *
214
- * @template TValue
215
- * Value type.
216
254
  */
217
- protected static mapMatrixRangeError<TValue>(matrixValues: Matrix<TValue>, callback: (value: TValue) => void): Matrix<string> {
255
+ protected matrixErrorResult<TValue>(matrixValues: Matrix<TValue>, callback: (value: TValue) => void): Matrix<string> {
218
256
  return matrixValues.map(rowValues => rowValues.map((value) => {
219
257
  let result: string;
220
258
 
@@ -229,11 +267,7 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
229
267
  result = e.message;
230
268
  } else {
231
269
  // Unknown error; pass up the stack.
232
- throw e instanceof Error ?
233
- e :
234
- new Error("Unknown error", {
235
- cause: e
236
- });
270
+ throw e;
237
271
  }
238
272
  }
239
273
 
@@ -242,18 +276,26 @@ export abstract class LibProxy<ThrowError extends boolean, TError extends ErrorE
242
276
  }
243
277
 
244
278
  /**
245
- * Convert an iterable result of a callback to a matrix result. Although the natural approach would be to map to a
246
- * single-element array containing an array of *N* results (i.e., [[r0, r1, r2, ..., r*N*]]), this is rendered
247
- * visually as a single row. The more readable approach is as a single column, so the mapping is to an *N*-element
248
- * array of single-element result arrays (i.e., [[r0], [r1], [r2], ..., [r*N*]]).
279
+ * Call an iterable result function with error handling and map to a matrix. Although the natural approach would be
280
+ * to map to a single-element array containing an array of *N* results (i.e., [[r0, r1, r2, ..., r*N*]]), this is
281
+ * rendered visually as a single row. The more readable approach is as a single column, so the mapping is to an
282
+ * *N*-element array of single-element result arrays (i.e., [[r0], [r1], [r2], ..., [r*N*]]).
249
283
  *
250
- * @param iterableResult
251
- * Iterable result.
284
+ * @param iterableCallback
285
+ * Iterable callback.
252
286
  *
253
287
  * @returns
254
288
  * Matrix of callback results.
255
289
  */
256
- protected static matrixResult<TResult>(iterableResult: Iterable<TResult>): Matrix<TResult> {
257
- return Array.from(mapIterable(iterableResult, result => [result]));
290
+ protected iterableResult<TResult>(iterableCallback: () => Iterable<SingletonResult<TResult, ThrowError, TError>>): MatrixResult<TResult, ThrowError, TError> {
291
+ let result: MatrixResult<TResult, ThrowError, TError>;
292
+
293
+ try {
294
+ result = Array.from(mapIterable(iterableCallback(), result => [result]));
295
+ } catch (e: unknown) {
296
+ result = [[this.#handleError(e)]];
297
+ }
298
+
299
+ return result;
258
300
  }
259
301
  }