@novasamatech/host-api 0.9.4 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hostApi.js +102 -3
- package/dist/index.d.ts +7 -1
- package/dist/index.js +6 -1
- package/dist/protocol/callError.d.ts +63 -0
- package/dist/protocol/callError.js +57 -0
- package/dist/protocol/impl.d.ts +370 -54
- package/dist/protocol/impl.js +86 -10
- package/dist/protocol/messageCodec.d.ts +903 -109
- package/dist/protocol/v1/accounts.d.ts +10 -10
- package/dist/protocol/v1/accounts.js +12 -11
- package/dist/protocol/v1/chainInteraction.d.ts +44 -12
- package/dist/protocol/v1/chainInteraction.js +25 -15
- package/dist/protocol/v1/chat.d.ts +3 -3
- package/dist/protocol/v1/chat.js +5 -4
- package/dist/protocol/v1/coinPayment.d.ts +345 -0
- package/dist/protocol/v1/coinPayment.js +105 -0
- package/dist/protocol/v1/createTransaction.d.ts +9 -9
- package/dist/protocol/v1/createTransaction.js +4 -3
- package/dist/protocol/v1/deriveEntropy.d.ts +1 -1
- package/dist/protocol/v1/deriveEntropy.js +2 -2
- package/dist/protocol/v1/devicePermission.d.ts +1 -1
- package/dist/protocol/v1/devicePermission.js +3 -2
- package/dist/protocol/v1/feature.d.ts +1 -1
- package/dist/protocol/v1/feature.js +3 -2
- package/dist/protocol/v1/handshake.d.ts +1 -1
- package/dist/protocol/v1/handshake.js +3 -2
- package/dist/protocol/v1/localStorage.d.ts +10 -3
- package/dist/protocol/v1/localStorage.js +10 -4
- package/dist/protocol/v1/locale.d.ts +8 -0
- package/dist/protocol/v1/locale.js +7 -0
- package/dist/protocol/v1/navigation.d.ts +1 -1
- package/dist/protocol/v1/navigation.js +3 -2
- package/dist/protocol/v1/notification.d.ts +2 -2
- package/dist/protocol/v1/notification.js +4 -3
- package/dist/protocol/v1/payments.d.ts +8 -8
- package/dist/protocol/v1/payments.js +4 -3
- package/dist/protocol/v1/preimage.d.ts +1 -1
- package/dist/protocol/v1/preimage.js +3 -2
- package/dist/protocol/v1/remotePermission.d.ts +1 -1
- package/dist/protocol/v1/remotePermission.js +3 -2
- package/dist/protocol/v1/resourceAllocation.d.ts +1 -1
- package/dist/protocol/v1/resourceAllocation.js +3 -2
- package/dist/protocol/v1/sign.d.ts +4 -4
- package/dist/protocol/v1/sign.js +6 -5
- package/dist/protocol/v1/statementStore.d.ts +3 -3
- package/dist/protocol/v1/statementStore.js +5 -4
- package/dist/protocol/v1/system.d.ts +23 -0
- package/dist/protocol/v1/system.js +21 -0
- package/dist/protocol/v1/worker.d.ts +37 -0
- package/dist/protocol/v1/worker.js +20 -0
- package/dist/transport.js +16 -2
- package/dist/transport.spec.js +18 -0
- package/package.json +3 -3
package/dist/hostApi.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { errAsync, fromPromise, okAsync } from 'neverthrow';
|
|
2
2
|
import { extractErrorMessage } from './helpers.js';
|
|
3
|
+
import { CALL_ERROR_FAILURE } from './protocol/callError.js';
|
|
3
4
|
import { GenericError } from './protocol/commonCodecs.js';
|
|
4
5
|
import { CreateProofErr, GetAliasErr, GetUserIdErr, ListRingVrfKeysErr, LoginErr, RegisterRingVrfKeyErr, RequestCredentialsErr, RingVrfSignErr, SignVrfErr, } from './protocol/v1/accounts.js';
|
|
6
|
+
import { ChainInfoErr } from './protocol/v1/chainInteraction.js';
|
|
5
7
|
import { ChatBotRegistrationErr, ChatMessagePostingErr, ChatRoomRegistrationErr } from './protocol/v1/chat.js';
|
|
8
|
+
import { CoinPaymentErr } from './protocol/v1/coinPayment.js';
|
|
6
9
|
import { CreateTransactionErr } from './protocol/v1/createTransaction.js';
|
|
7
10
|
import { DeriveEntropyErr } from './protocol/v1/deriveEntropy.js';
|
|
8
11
|
import { HandshakeErr } from './protocol/v1/handshake.js';
|
|
@@ -14,6 +17,7 @@ import { PreimageSubmitErr } from './protocol/v1/preimage.js';
|
|
|
14
17
|
import { ResourceAllocationErr } from './protocol/v1/resourceAllocation.js';
|
|
15
18
|
import { SigningErr } from './protocol/v1/sign.js';
|
|
16
19
|
import { StatementProofErr } from './protocol/v1/statementStore.js';
|
|
20
|
+
import { WorkerErr } from './protocol/v1/worker.js';
|
|
17
21
|
export function createHostApi(transport) {
|
|
18
22
|
return {
|
|
19
23
|
handshake(payload) {
|
|
@@ -31,6 +35,21 @@ export function createHostApi(transport) {
|
|
|
31
35
|
themeSubscribe(args, callback) {
|
|
32
36
|
return transport.subscribe('host_theme_subscribe', args, callback);
|
|
33
37
|
},
|
|
38
|
+
localeSubscribe(args, callback) {
|
|
39
|
+
return transport.subscribe('host_locale_subscribe', args, callback);
|
|
40
|
+
},
|
|
41
|
+
getProductContext(payload) {
|
|
42
|
+
return makeRequest(transport.request('host_get_product_context', payload), reason => ({
|
|
43
|
+
tag: payload.tag,
|
|
44
|
+
value: new GenericError({ reason }),
|
|
45
|
+
}));
|
|
46
|
+
},
|
|
47
|
+
info(payload) {
|
|
48
|
+
return makeRequest(transport.request('host_info', payload), reason => ({
|
|
49
|
+
tag: payload.tag,
|
|
50
|
+
value: new GenericError({ reason }),
|
|
51
|
+
}));
|
|
52
|
+
},
|
|
34
53
|
devicePermission(payload) {
|
|
35
54
|
return makeRequest(transport.request('host_device_permission', payload), reason => ({
|
|
36
55
|
tag: payload.tag,
|
|
@@ -85,6 +104,21 @@ export function createHostApi(transport) {
|
|
|
85
104
|
value: new StorageErr.Unknown({ reason }),
|
|
86
105
|
}));
|
|
87
106
|
},
|
|
107
|
+
localStorageSubscribe(args, callback) {
|
|
108
|
+
return transport.subscribe('host_local_storage_subscribe', args, callback);
|
|
109
|
+
},
|
|
110
|
+
workerBeginOperation(payload) {
|
|
111
|
+
return makeRequest(transport.request('host_worker_begin_operation', payload), reason => ({
|
|
112
|
+
tag: payload.tag,
|
|
113
|
+
value: new WorkerErr.Unknown({ reason }),
|
|
114
|
+
}));
|
|
115
|
+
},
|
|
116
|
+
workerEndOperation(payload) {
|
|
117
|
+
return makeRequest(transport.request('host_worker_end_operation', payload), reason => ({
|
|
118
|
+
tag: payload.tag,
|
|
119
|
+
value: new WorkerErr.Unknown({ reason }),
|
|
120
|
+
}));
|
|
121
|
+
},
|
|
88
122
|
accountConnectionStatusSubscribe(args, callback) {
|
|
89
123
|
return transport.subscribe('host_account_connection_status_subscribe', args, callback);
|
|
90
124
|
},
|
|
@@ -265,6 +299,46 @@ export function createHostApi(transport) {
|
|
|
265
299
|
value: new ResourceAllocationErr.Unknown({ reason }),
|
|
266
300
|
}));
|
|
267
301
|
},
|
|
302
|
+
// coin payment (RFC 0017)
|
|
303
|
+
coinPaymentCreatePurse(payload) {
|
|
304
|
+
return makeRequest(transport.request('host_coin_payment_create_purse', payload), () => ({
|
|
305
|
+
tag: payload.tag,
|
|
306
|
+
value: new CoinPaymentErr.Internal(),
|
|
307
|
+
}));
|
|
308
|
+
},
|
|
309
|
+
coinPaymentQueryPurse(payload) {
|
|
310
|
+
return makeRequest(transport.request('host_coin_payment_query_purse', payload), () => ({
|
|
311
|
+
tag: payload.tag,
|
|
312
|
+
value: new CoinPaymentErr.Internal(),
|
|
313
|
+
}));
|
|
314
|
+
},
|
|
315
|
+
coinPaymentRebalancePurse(args, callback) {
|
|
316
|
+
return transport.subscribe('host_coin_payment_rebalance_purse', args, callback);
|
|
317
|
+
},
|
|
318
|
+
coinPaymentDeletePurse(args, callback) {
|
|
319
|
+
return transport.subscribe('host_coin_payment_delete_purse', args, callback);
|
|
320
|
+
},
|
|
321
|
+
coinPaymentCreateReceivable(payload) {
|
|
322
|
+
return makeRequest(transport.request('host_coin_payment_create_receivable', payload), () => ({
|
|
323
|
+
tag: payload.tag,
|
|
324
|
+
value: new CoinPaymentErr.Internal(),
|
|
325
|
+
}));
|
|
326
|
+
},
|
|
327
|
+
coinPaymentCreateCheque(payload) {
|
|
328
|
+
return makeRequest(transport.request('host_coin_payment_create_cheque', payload), () => ({
|
|
329
|
+
tag: payload.tag,
|
|
330
|
+
value: new CoinPaymentErr.Internal(),
|
|
331
|
+
}));
|
|
332
|
+
},
|
|
333
|
+
coinPaymentDeposit(args, callback) {
|
|
334
|
+
return transport.subscribe('host_coin_payment_deposit', args, callback);
|
|
335
|
+
},
|
|
336
|
+
coinPaymentRefund(args, callback) {
|
|
337
|
+
return transport.subscribe('host_coin_payment_refund', args, callback);
|
|
338
|
+
},
|
|
339
|
+
coinPaymentListenForPayment(args, callback) {
|
|
340
|
+
return transport.subscribe('host_coin_payment_listen_for_payment', args, callback);
|
|
341
|
+
},
|
|
268
342
|
// chain interaction
|
|
269
343
|
chainHeadFollowSubscribe(args, callback) {
|
|
270
344
|
return transport.subscribe('remote_chain_head_follow_subscribe', args, callback);
|
|
@@ -311,6 +385,12 @@ export function createHostApi(transport) {
|
|
|
311
385
|
value: new GenericError({ reason }),
|
|
312
386
|
}));
|
|
313
387
|
},
|
|
388
|
+
chainGetChainInfo(payload) {
|
|
389
|
+
return makeRequest(transport.request('remote_chain_get_chain_info', payload), reason => ({
|
|
390
|
+
tag: payload.tag,
|
|
391
|
+
value: new ChainInfoErr.Unknown({ reason }),
|
|
392
|
+
}));
|
|
393
|
+
},
|
|
314
394
|
chainSpecGenesisHash(payload) {
|
|
315
395
|
return makeRequest(transport.request('remote_chain_spec_genesis_hash', payload), reason => ({
|
|
316
396
|
tag: payload.tag,
|
|
@@ -343,10 +423,29 @@ export function createHostApi(transport) {
|
|
|
343
423
|
},
|
|
344
424
|
};
|
|
345
425
|
}
|
|
426
|
+
/** Human-readable reason for a transport-level `CallError`, for the domain fallback. */
|
|
427
|
+
function describeCallErrorFailure(failure) {
|
|
428
|
+
switch (failure.tag) {
|
|
429
|
+
case 'Denied':
|
|
430
|
+
return 'call denied by host';
|
|
431
|
+
case 'Unsupported':
|
|
432
|
+
return 'method unsupported by host';
|
|
433
|
+
case 'MalformedFrame':
|
|
434
|
+
return `malformed frame: ${failure.value.reason}`;
|
|
435
|
+
case 'HostFailure':
|
|
436
|
+
return `host failure: ${failure.value.reason}`;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
346
439
|
function makeRequest(promise, mapErr) {
|
|
347
440
|
return fromPromise(promise, e => mapErr(extractErrorMessage(e))).andThen(r => {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
441
|
+
const value = r.value;
|
|
442
|
+
// A transport-level CallError carries no domain answer; fold it into the
|
|
443
|
+
// method's domain error so products keep a single error type.
|
|
444
|
+
if (CALL_ERROR_FAILURE in value) {
|
|
445
|
+
return errAsync(mapErr(describeCallErrorFailure(value[CALL_ERROR_FAILURE])));
|
|
446
|
+
}
|
|
447
|
+
if (value.success)
|
|
448
|
+
return okAsync({ tag: r.tag, value: value.value });
|
|
449
|
+
return errAsync({ tag: r.tag, value: value.value });
|
|
351
450
|
});
|
|
352
451
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { createTransport } from './transport.js';
|
|
|
8
8
|
export { createDefaultLogger } from './logger.js';
|
|
9
9
|
export type { HostApiProtocol, VersionedProtocolRequest, VersionedProtocolSubscription } from './protocol/impl.js';
|
|
10
10
|
export { hostApiProtocol } from './protocol/impl.js';
|
|
11
|
+
export { CALL_ERROR_FAILURE, isCallErrorFailure } from './protocol/callError.js';
|
|
12
|
+
export type { CallErrorTransportFailure } from './protocol/callError.js';
|
|
11
13
|
export type { Codec, CodecType } from 'scale-ts';
|
|
12
14
|
export type { HexString } from '@novasamatech/scale';
|
|
13
15
|
export { assertEnumVariant, enumValue, fromHex, isEnumVariant, resultErr, resultOk, toHex, unwrapResultOrThrow, } from '@novasamatech/scale';
|
|
@@ -22,6 +24,7 @@ export { HandshakeErr } from './protocol/v1/handshake.js';
|
|
|
22
24
|
export { SigningErr, SigningPayload, SigningPayloadWithoutAccount, SigningRawPayload, SigningRawPayloadWithoutAccount, SigningResult, } from './protocol/v1/sign.js';
|
|
23
25
|
export { SignedStatement, SignedStatementsPage, Statement, StatementProofErr, Topic, TopicFilter, } from './protocol/v1/statementStore.js';
|
|
24
26
|
export { StorageErr } from './protocol/v1/localStorage.js';
|
|
27
|
+
export { OperationId, WorkerErr } from './protocol/v1/worker.js';
|
|
25
28
|
export { DevicePermission } from './protocol/v1/devicePermission.js';
|
|
26
29
|
export { RemotePermission } from './protocol/v1/remotePermission.js';
|
|
27
30
|
export { NotificationId, PushNotification, PushNotificationError } from './protocol/v1/notification.js';
|
|
@@ -30,5 +33,8 @@ export { PreimageKey, PreimageSubmitErr, PreimageValue } from './protocol/v1/pre
|
|
|
30
33
|
export { AllocatableResource, AllocationOutcome, ResourceAllocationErr } from './protocol/v1/resourceAllocation.js';
|
|
31
34
|
export { PaymentBalance, PaymentBalanceErr, PaymentId, PaymentReceipt, PaymentRequestErr, PaymentStatus, PaymentStatusErr, PaymentTopUpErr, PaymentTopUpSource, } from './protocol/v1/payments.js';
|
|
32
35
|
export { Arrangement, BorderStyle, ButtonVariant, ColorToken, ContentAlignment, CustomRendererNode, Dimensions, HorizontalAlignment, Modifier, Shape, Size, TypographyStyle, VerticalAlignment, } from './protocol/v1/customRenderer.js';
|
|
33
|
-
export { ChainHeadEvent, ChainHeadFollowV1_start, OperationStartedResult, RuntimeType, StorageQueryItem, StorageQueryType, StorageResultItem, TransactionBroadcastV1_request, TransactionBroadcastV1_response, TransactionStopV1_request, TransactionStopV1_response, } from './protocol/v1/chainInteraction.js';
|
|
36
|
+
export { ChainHeadEvent, ChainHeadFollowV1_start, ChainIdentifier, ChainInfoErr, OperationStartedResult, RuntimeType, StorageQueryItem, StorageQueryType, StorageResultItem, TransactionBroadcastV1_request, TransactionBroadcastV1_response, TransactionStopV1_request, TransactionStopV1_response, } from './protocol/v1/chainInteraction.js';
|
|
37
|
+
export { CoinPaymentBalance, CoinPaymentCheque, CoinPaymentErr, CoinPaymentListenForItem, CoinPaymentPurseId, CoinPaymentPurseInfo, CoinPaymentReceivable, CoinPaymentStatus, CoinPaymentTransmissionChannel, } from './protocol/v1/coinPayment.js';
|
|
38
|
+
export { HostLocale } from './protocol/v1/locale.js';
|
|
39
|
+
export { HostInfo, HostPlatform, ProductContext } from './protocol/v1/system.js';
|
|
34
40
|
export { Theme, ThemeName, ThemeVariant } from './protocol/v1/theme.js';
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { createHostApi } from './hostApi.js';
|
|
|
3
3
|
export { createTransport } from './transport.js';
|
|
4
4
|
export { createDefaultLogger } from './logger.js';
|
|
5
5
|
export { hostApiProtocol } from './protocol/impl.js';
|
|
6
|
+
export { CALL_ERROR_FAILURE, isCallErrorFailure } from './protocol/callError.js';
|
|
6
7
|
export { assertEnumVariant, enumValue, fromHex, isEnumVariant, resultErr, resultOk, toHex, unwrapResultOrThrow, } from '@novasamatech/scale';
|
|
7
8
|
// Codecs
|
|
8
9
|
export { GenericError } from './protocol/commonCodecs.js';
|
|
@@ -15,6 +16,7 @@ export { HandshakeErr } from './protocol/v1/handshake.js';
|
|
|
15
16
|
export { SigningErr, SigningPayload, SigningPayloadWithoutAccount, SigningRawPayload, SigningRawPayloadWithoutAccount, SigningResult, } from './protocol/v1/sign.js';
|
|
16
17
|
export { SignedStatement, SignedStatementsPage, Statement, StatementProofErr, Topic, TopicFilter, } from './protocol/v1/statementStore.js';
|
|
17
18
|
export { StorageErr } from './protocol/v1/localStorage.js';
|
|
19
|
+
export { OperationId, WorkerErr } from './protocol/v1/worker.js';
|
|
18
20
|
export { DevicePermission } from './protocol/v1/devicePermission.js';
|
|
19
21
|
export { RemotePermission } from './protocol/v1/remotePermission.js';
|
|
20
22
|
export { NotificationId, PushNotification, PushNotificationError } from './protocol/v1/notification.js';
|
|
@@ -23,5 +25,8 @@ export { PreimageKey, PreimageSubmitErr, PreimageValue } from './protocol/v1/pre
|
|
|
23
25
|
export { AllocatableResource, AllocationOutcome, ResourceAllocationErr } from './protocol/v1/resourceAllocation.js';
|
|
24
26
|
export { PaymentBalance, PaymentBalanceErr, PaymentId, PaymentReceipt, PaymentRequestErr, PaymentStatus, PaymentStatusErr, PaymentTopUpErr, PaymentTopUpSource, } from './protocol/v1/payments.js';
|
|
25
27
|
export { Arrangement, BorderStyle, ButtonVariant, ColorToken, ContentAlignment, CustomRendererNode, Dimensions, HorizontalAlignment, Modifier, Shape, Size, TypographyStyle, VerticalAlignment, } from './protocol/v1/customRenderer.js';
|
|
26
|
-
export { ChainHeadEvent, ChainHeadFollowV1_start, OperationStartedResult, RuntimeType, StorageQueryItem, StorageQueryType, StorageResultItem, TransactionBroadcastV1_request, TransactionBroadcastV1_response, TransactionStopV1_request, TransactionStopV1_response, } from './protocol/v1/chainInteraction.js';
|
|
28
|
+
export { ChainHeadEvent, ChainHeadFollowV1_start, ChainIdentifier, ChainInfoErr, OperationStartedResult, RuntimeType, StorageQueryItem, StorageQueryType, StorageResultItem, TransactionBroadcastV1_request, TransactionBroadcastV1_response, TransactionStopV1_request, TransactionStopV1_response, } from './protocol/v1/chainInteraction.js';
|
|
29
|
+
export { CoinPaymentBalance, CoinPaymentCheque, CoinPaymentErr, CoinPaymentListenForItem, CoinPaymentPurseId, CoinPaymentPurseInfo, CoinPaymentReceivable, CoinPaymentStatus, CoinPaymentTransmissionChannel, } from './protocol/v1/coinPayment.js';
|
|
30
|
+
export { HostLocale } from './protocol/v1/locale.js';
|
|
31
|
+
export { HostInfo, HostPlatform, ProductContext } from './protocol/v1/system.js';
|
|
27
32
|
export { Theme, ThemeName, ThemeVariant } from './protocol/v1/theme.js';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Codec, ResultPayload } from 'scale-ts';
|
|
2
|
+
/** The transport-level failure variants (everything except `Domain`). */
|
|
3
|
+
export type CallErrorTransportFailure = {
|
|
4
|
+
tag: 'Denied';
|
|
5
|
+
} | {
|
|
6
|
+
tag: 'Unsupported';
|
|
7
|
+
} | {
|
|
8
|
+
tag: 'MalformedFrame';
|
|
9
|
+
value: {
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
} | {
|
|
13
|
+
tag: 'HostFailure';
|
|
14
|
+
value: {
|
|
15
|
+
reason: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
/** SCALE codec for `CallError<D>`, discriminants pinned to the truapi order. */
|
|
19
|
+
export declare const CallError: <D>(domain: Codec<D>) => Codec<{
|
|
20
|
+
tag: "Denied";
|
|
21
|
+
value: undefined;
|
|
22
|
+
} | {
|
|
23
|
+
tag: "Unsupported";
|
|
24
|
+
value: undefined;
|
|
25
|
+
} | {
|
|
26
|
+
tag: "MalformedFrame";
|
|
27
|
+
value: {
|
|
28
|
+
reason: string;
|
|
29
|
+
};
|
|
30
|
+
} | {
|
|
31
|
+
tag: "HostFailure";
|
|
32
|
+
value: {
|
|
33
|
+
reason: string;
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
tag: "Domain";
|
|
37
|
+
value: D;
|
|
38
|
+
}>;
|
|
39
|
+
/** A decoded transport failure carries this brand so the transport can spot it. */
|
|
40
|
+
export declare const CALL_ERROR_FAILURE: unique symbol;
|
|
41
|
+
/** Business (present) shape of a response: a plain scale-ts `Result`. */
|
|
42
|
+
type Business<OK, ERR> = ResultPayload<OK, ERR>;
|
|
43
|
+
/** True when a decoded response is a transport-level `CallError`, not a domain answer. */
|
|
44
|
+
export declare const isCallErrorFailure: <OK, ERR>(value: CallResultValue<OK, ERR>) => value is {
|
|
45
|
+
[CALL_ERROR_FAILURE]: CallErrorTransportFailure;
|
|
46
|
+
};
|
|
47
|
+
export type CallResultValue<OK, ERR> = Business<OK, ERR> | {
|
|
48
|
+
[CALL_ERROR_FAILURE]: CallErrorTransportFailure;
|
|
49
|
+
};
|
|
50
|
+
export declare const CallResult: <OK, ERR>(ok: Codec<OK>, domainErr: Codec<ERR>) => Codec<CallResultValue<OK, ERR>>;
|
|
51
|
+
/** A decoded subscription interrupt: the domain reason, or a transport failure. */
|
|
52
|
+
export type CallInterruptValue<ERR> = ERR | {
|
|
53
|
+
[CALL_ERROR_FAILURE]: CallErrorTransportFailure;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Interrupt codec counterpart to `Result`. A subscription's interrupt reason is
|
|
57
|
+
* `CallError(V1(err))` on the wire (byte-identical to truapi); its value form is
|
|
58
|
+
* the plain domain reason for the `Domain` case, and a `CALL_ERROR_FAILURE`
|
|
59
|
+
* marker for a transport-level interrupt. The transport assembly applies this to
|
|
60
|
+
* typed interrupts, so interrupt codec definitions stay the plain domain error.
|
|
61
|
+
*/
|
|
62
|
+
export declare const interruptError: <ERR>(domainErr: Codec<ERR>) => Codec<CallInterruptValue<ERR>>;
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Enum } from '@novasamatech/scale';
|
|
2
|
+
import { Result as ScaleResult, Struct, _void, enhanceCodec, str } from 'scale-ts';
|
|
3
|
+
/** Wraps a domain error codec into a `V1`-versioned enum, as truapi does. */
|
|
4
|
+
const versioned = (domain) => Enum({ v1: domain }, [0]);
|
|
5
|
+
/** SCALE codec for `CallError<D>`, discriminants pinned to the truapi order. */
|
|
6
|
+
export const CallError = (domain) => Enum({
|
|
7
|
+
Domain: domain,
|
|
8
|
+
Denied: _void,
|
|
9
|
+
Unsupported: _void,
|
|
10
|
+
MalformedFrame: Struct({ reason: str }),
|
|
11
|
+
HostFailure: Struct({ reason: str }),
|
|
12
|
+
}, [0, 1, 2, 3, 4]);
|
|
13
|
+
/** A decoded transport failure carries this brand so the transport can spot it. */
|
|
14
|
+
export const CALL_ERROR_FAILURE = Symbol('callErrorFailure');
|
|
15
|
+
/** True when a decoded response is a transport-level `CallError`, not a domain answer. */
|
|
16
|
+
export const isCallErrorFailure = (value) => CALL_ERROR_FAILURE in value;
|
|
17
|
+
export const CallResult = (ok, domainErr) => {
|
|
18
|
+
const wire = ScaleResult(ok, CallError(versioned(domainErr)));
|
|
19
|
+
return enhanceCodec(wire, value => {
|
|
20
|
+
if (CALL_ERROR_FAILURE in value) {
|
|
21
|
+
// Re-encoding a decoded transport failure (rare): pass it straight back.
|
|
22
|
+
return { success: false, value: value[CALL_ERROR_FAILURE] };
|
|
23
|
+
}
|
|
24
|
+
if (value.success)
|
|
25
|
+
return { success: true, value: value.value };
|
|
26
|
+
return { success: false, value: { tag: 'Domain', value: { tag: 'v1', value: value.value } } };
|
|
27
|
+
}, decoded => {
|
|
28
|
+
if (decoded.success)
|
|
29
|
+
return { success: true, value: decoded.value };
|
|
30
|
+
const callError = decoded.value;
|
|
31
|
+
if (callError.tag === 'Domain') {
|
|
32
|
+
return { success: false, value: callError.value.value };
|
|
33
|
+
}
|
|
34
|
+
return { [CALL_ERROR_FAILURE]: callError };
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Interrupt codec counterpart to `Result`. A subscription's interrupt reason is
|
|
39
|
+
* `CallError(V1(err))` on the wire (byte-identical to truapi); its value form is
|
|
40
|
+
* the plain domain reason for the `Domain` case, and a `CALL_ERROR_FAILURE`
|
|
41
|
+
* marker for a transport-level interrupt. The transport assembly applies this to
|
|
42
|
+
* typed interrupts, so interrupt codec definitions stay the plain domain error.
|
|
43
|
+
*/
|
|
44
|
+
export const interruptError = (domainErr) => {
|
|
45
|
+
const wire = CallError(versioned(domainErr));
|
|
46
|
+
return enhanceCodec(wire, value => {
|
|
47
|
+
if (typeof value === 'object' && value !== null && CALL_ERROR_FAILURE in value) {
|
|
48
|
+
const failure = value[CALL_ERROR_FAILURE];
|
|
49
|
+
return { tag: failure.tag, value: 'value' in failure ? failure.value : undefined };
|
|
50
|
+
}
|
|
51
|
+
return { tag: 'Domain', value: { tag: 'v1', value } };
|
|
52
|
+
}, decoded => {
|
|
53
|
+
if (decoded.tag === 'Domain')
|
|
54
|
+
return decoded.value.value;
|
|
55
|
+
return { [CALL_ERROR_FAILURE]: decoded };
|
|
56
|
+
});
|
|
57
|
+
};
|