@novasamatech/host-api 0.5.5 → 0.6.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/README.md CHANGED
@@ -109,3 +109,28 @@ subscription.onInterrupt(() => {
109
109
 
110
110
  subscription.unsubscribe();
111
111
  ```
112
+
113
+ ### Custom Renderer
114
+
115
+ The protocol includes a custom renderer system for building UI component trees that can be serialized and sent across the transport. This is used for rendering custom chat messages.
116
+
117
+ Available components: `Box`, `Column`, `Row`, `Spacer`, `Text`, `Button`, `TextField`. Each component supports optional `Modifiers` (margin, padding, background, border, dimensions) and can contain children.
118
+
119
+ ```typescript
120
+ import { CustomRendererNode } from '@novasamatech/host-api';
121
+ ```
122
+
123
+ ### Account Connection Status
124
+
125
+ Products can subscribe to account connection status changes:
126
+
127
+ ```typescript
128
+ const subscription = hostApi.accountConnectionStatusSubscribe(undefined, (status) => {
129
+ // status: 'connected' | 'disconnected'
130
+ console.log('connection status:', status);
131
+ });
132
+ ```
133
+
134
+ ### Custom Chat Messages
135
+
136
+ Chat messages now support a `Custom` content type that carries an arbitrary payload identified by `messageType`. Products can handle rendering of custom messages via the `productChatCustomMessageRenderSubscribe` subscription, which receives the message type and payload and expects a `CustomRendererNode` tree in response.
package/dist/hostApi.js CHANGED
@@ -174,6 +174,9 @@ export function createHostApi(transport) {
174
174
  });
175
175
  });
176
176
  },
177
+ accountConnectionStatusSubscribe(args, callback) {
178
+ return transport.subscribe('host_account_connection_status_subscribe', args, callback);
179
+ },
177
180
  accountGet(payload) {
178
181
  const response = fromPromise(transport.request('host_account_get', payload), e => ({
179
182
  tag: payload.tag,
@@ -378,6 +381,9 @@ export function createHostApi(transport) {
378
381
  chatActionSubscribe(args, callback) {
379
382
  return transport.subscribe('host_chat_action_subscribe', args, callback);
380
383
  },
384
+ productChatCustomMessageRenderSubscribe(args, callback) {
385
+ return transport.subscribe('product_chat_custom_message_render_subscribe', args, callback);
386
+ },
381
387
  statementStoreSubscribe(args, callback) {
382
388
  return transport.subscribe('remote_statement_store_subscribe', args, callback);
383
389
  },
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export type { HexString } from '@novasamatech/scale';
12
12
  export { assertEnumVariant, enumValue, fromHex, isEnumVariant, resultErr, resultOk, toHex, unwrapResultOrThrow, } from '@novasamatech/scale';
13
13
  export { GenericError } from './protocol/commonCodecs.js';
14
14
  export { CreateTransactionErr, VersionedPublicTxPayload } from './protocol/v1/createTransaction.js';
15
- export { Account, AccountId, CreateProofErr, ProductAccountId, RequestCredentialsErr, RingLocation, } from './protocol/v1/accounts.js';
15
+ export { Account, AccountConnectionStatus, AccountId, CreateProofErr, ProductAccountId, RequestCredentialsErr, RingLocation, } from './protocol/v1/accounts.js';
16
16
  export { ChatActionPayload, ChatBotRegistrationErr, ChatBotRegistrationStatus, ChatMessageContent, ChatMessagePostingErr, ChatRoom, ChatRoomRegistrationErr, ChatRoomRegistrationResult, ChatRoomRegistrationStatus, ReceivedChatAction, } from './protocol/v1/chat.js';
17
17
  export { HandshakeErr } from './protocol/v1/handshake.js';
18
18
  export { SigningErr } from './protocol/v1/sign.js';
@@ -23,3 +23,4 @@ export { RemotePermissionRequest } from './protocol/v1/remotePermission.js';
23
23
  export { PushNotification } from './protocol/v1/notification.js';
24
24
  export { NavigateToErr } from './protocol/v1/navigation.js';
25
25
  export { PreimageKey, PreimageSubmitErr, PreimageValue } from './protocol/v1/preimage.js';
26
+ export { CustomRendererNode } from './protocol/v1/customRenderer.js';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ export { assertEnumVariant, enumValue, fromHex, isEnumVariant, resultErr, result
7
7
  // Codecs
8
8
  export { GenericError } from './protocol/commonCodecs.js';
9
9
  export { CreateTransactionErr, VersionedPublicTxPayload } from './protocol/v1/createTransaction.js';
10
- export { Account, AccountId, CreateProofErr, ProductAccountId, RequestCredentialsErr, RingLocation, } from './protocol/v1/accounts.js';
10
+ export { Account, AccountConnectionStatus, AccountId, CreateProofErr, ProductAccountId, RequestCredentialsErr, RingLocation, } from './protocol/v1/accounts.js';
11
11
  export { ChatActionPayload, ChatBotRegistrationErr, ChatBotRegistrationStatus, ChatMessageContent, ChatMessagePostingErr, ChatRoom, ChatRoomRegistrationErr, ChatRoomRegistrationResult, ChatRoomRegistrationStatus, ReceivedChatAction, } from './protocol/v1/chat.js';
12
12
  export { HandshakeErr } from './protocol/v1/handshake.js';
13
13
  export { SigningErr } from './protocol/v1/sign.js';
@@ -18,3 +18,4 @@ export { RemotePermissionRequest } from './protocol/v1/remotePermission.js';
18
18
  export { PushNotification } from './protocol/v1/notification.js';
19
19
  export { NavigateToErr } from './protocol/v1/navigation.js';
20
20
  export { PreimageKey, PreimageSubmitErr, PreimageValue } from './protocol/v1/preimage.js';
21
+ export { CustomRendererNode } from './protocol/v1/customRenderer.js';
@@ -73,6 +73,9 @@ export declare const hostApiProtocol: {
73
73
  reason: string;
74
74
  }, "StorageErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "StorageErr::Full">>>];
75
75
  }>;
76
+ readonly host_account_connection_status_subscribe: VersionedProtocolSubscription<{
77
+ readonly v1: [Codec<undefined>, Codec<"disconnected" | "connected">];
78
+ }>;
76
79
  readonly host_account_get: VersionedProtocolRequest<{
77
80
  readonly v1: [Codec<[string, number]>, Codec<import("scale-ts").ResultPayload<{
78
81
  publicKey: Uint8Array<ArrayBufferLike>;
@@ -233,6 +236,12 @@ export declare const hostApiProtocol: {
233
236
  messageId: string;
234
237
  emoji: string;
235
238
  };
239
+ } | {
240
+ tag: "Custom";
241
+ value: {
242
+ messageType: string;
243
+ payload: Uint8Array<ArrayBufferLike>;
244
+ };
236
245
  };
237
246
  }>, Codec<import("scale-ts").ResultPayload<{
238
247
  messageId: string;
@@ -288,6 +297,12 @@ export declare const hostApiProtocol: {
288
297
  messageId: string;
289
298
  emoji: string;
290
299
  };
300
+ } | {
301
+ tag: "Custom";
302
+ value: {
303
+ messageType: string;
304
+ payload: Uint8Array<ArrayBufferLike>;
305
+ };
291
306
  };
292
307
  } | {
293
308
  tag: "ActionTriggered";
@@ -305,6 +320,12 @@ export declare const hostApiProtocol: {
305
320
  };
306
321
  }>];
307
322
  }>;
323
+ readonly product_chat_custom_message_render_subscribe: VersionedProtocolSubscription<{
324
+ readonly v1: [Codec<{
325
+ messageType: string;
326
+ payload: Uint8Array<ArrayBufferLike>;
327
+ }>, Codec<import("./v1/customRenderer.js").CustomRendererNodeType>];
328
+ }>;
308
329
  readonly remote_statement_store_subscribe: VersionedProtocolSubscription<{
309
330
  readonly v1: [Codec<Uint8Array<ArrayBufferLike>[]>, Codec<{
310
331
  proof: {
@@ -1,6 +1,6 @@
1
1
  import { Enum } from '@novasamatech/scale';
2
- import { AccountCreateProofV1_request, AccountCreateProofV1_response, AccountGetAliasV1_request, AccountGetAliasV1_response, AccountGetV1_request, AccountGetV1_response, GetNonProductAccountsV1_request, GetNonProductAccountsV1_response, } from './v1/accounts.js';
3
- import { ChatActionSubscribeV1_receive, ChatActionSubscribeV1_start, ChatCreateRoomV1_request, ChatCreateRoomV1_response, ChatListSubscribeV1_receive, ChatListSubscribeV1_start, ChatPostMessageV1_request, ChatPostMessageV1_response, ChatRegisterBotV1_request, ChatRegisterBotV1_response, } from './v1/chat.js';
2
+ import { AccountConnectionStatusV1_receive, AccountConnectionStatusV1_start, AccountCreateProofV1_request, AccountCreateProofV1_response, AccountGetAliasV1_request, AccountGetAliasV1_response, AccountGetV1_request, AccountGetV1_response, GetNonProductAccountsV1_request, GetNonProductAccountsV1_response, } from './v1/accounts.js';
3
+ import { ChatActionSubscribeV1_receive, ChatActionSubscribeV1_start, ChatCreateRoomV1_request, ChatCreateRoomV1_response, ChatCustomMessageRenderingV1_receive, ChatCustomMessageRenderingV1_start, ChatListSubscribeV1_receive, ChatListSubscribeV1_start, ChatPostMessageV1_request, ChatPostMessageV1_response, ChatRegisterBotV1_request, ChatRegisterBotV1_response, } from './v1/chat.js';
4
4
  import { CreateTransactionV1_request, CreateTransactionV1_response, CreateTransactionWithNonProductAccountV1_request, CreateTransactionWithNonProductAccountV1_response, } from './v1/createTransaction.js';
5
5
  import { DevicePermissionV1_request, DevicePermissionV1_response } from './v1/devicePermission.js';
6
6
  import { FeatureV1_request, FeatureV1_response } from './v1/feature.js';
@@ -62,6 +62,9 @@ export const hostApiProtocol = {
62
62
  v1: [StorageClearV1_request, StorageClearV1_response],
63
63
  }),
64
64
  // Account management
65
+ host_account_connection_status_subscribe: versionedSubscription({
66
+ v1: [AccountConnectionStatusV1_start, AccountConnectionStatusV1_receive],
67
+ }),
65
68
  host_account_get: versionedRequest({
66
69
  v1: [AccountGetV1_request, AccountGetV1_response],
67
70
  }),
@@ -103,6 +106,9 @@ export const hostApiProtocol = {
103
106
  host_chat_action_subscribe: versionedSubscription({
104
107
  v1: [ChatActionSubscribeV1_start, ChatActionSubscribeV1_receive],
105
108
  }),
109
+ product_chat_custom_message_render_subscribe: versionedSubscription({
110
+ v1: [ChatCustomMessageRenderingV1_start, ChatCustomMessageRenderingV1_receive],
111
+ }),
106
112
  // Statement store (remote namespace)
107
113
  remote_statement_store_subscribe: versionedSubscription({
108
114
  v1: [StatementStoreSubscribeV1_start, StatementStoreSubscribeV1_receive],
@@ -75,7 +75,11 @@ export declare const MessagePayload: EnumCodec<Record<"host_handshake_request",
75
75
  readonly v1: Codec<import("scale-ts").ResultPayload<undefined, import("@novasamatech/scale").CodecError<{
76
76
  reason: string;
77
77
  }, "StorageErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "StorageErr::Full">>>;
78
- }>> & Record<"host_account_get_request", EnumCodec<{
78
+ }>> & Record<"host_account_connection_status_subscribe_start", EnumCodec<{
79
+ readonly v1: Codec<undefined>;
80
+ }>> & Record<"host_account_connection_status_subscribe_receive", EnumCodec<{
81
+ readonly v1: Codec<"disconnected" | "connected">;
82
+ }>> & Record<"host_account_connection_status_subscribe_interrupt", Codec<undefined>> & Record<"host_account_connection_status_subscribe_stop", Codec<undefined>> & Record<"host_account_get_request", EnumCodec<{
79
83
  readonly v1: Codec<[string, number]>;
80
84
  }>> & Record<"host_account_get_response", EnumCodec<{
81
85
  readonly v1: Codec<import("scale-ts").ResultPayload<{
@@ -246,6 +250,12 @@ export declare const MessagePayload: EnumCodec<Record<"host_handshake_request",
246
250
  messageId: string;
247
251
  emoji: string;
248
252
  };
253
+ } | {
254
+ tag: "Custom";
255
+ value: {
256
+ messageType: string;
257
+ payload: Uint8Array<ArrayBufferLike>;
258
+ };
249
259
  };
250
260
  }>;
251
261
  }>> & Record<"host_chat_post_message_response", EnumCodec<{
@@ -304,6 +314,12 @@ export declare const MessagePayload: EnumCodec<Record<"host_handshake_request",
304
314
  messageId: string;
305
315
  emoji: string;
306
316
  };
317
+ } | {
318
+ tag: "Custom";
319
+ value: {
320
+ messageType: string;
321
+ payload: Uint8Array<ArrayBufferLike>;
322
+ };
307
323
  };
308
324
  } | {
309
325
  tag: "ActionTriggered";
@@ -320,7 +336,14 @@ export declare const MessagePayload: EnumCodec<Record<"host_handshake_request",
320
336
  };
321
337
  };
322
338
  }>;
323
- }>> & Record<"host_chat_action_subscribe_interrupt", Codec<undefined>> & Record<"host_chat_action_subscribe_stop", Codec<undefined>> & Record<"remote_statement_store_subscribe_start", EnumCodec<{
339
+ }>> & Record<"host_chat_action_subscribe_interrupt", Codec<undefined>> & Record<"host_chat_action_subscribe_stop", Codec<undefined>> & Record<"product_chat_custom_message_render_subscribe_start", EnumCodec<{
340
+ readonly v1: Codec<{
341
+ messageType: string;
342
+ payload: Uint8Array<ArrayBufferLike>;
343
+ }>;
344
+ }>> & Record<"product_chat_custom_message_render_subscribe_receive", EnumCodec<{
345
+ readonly v1: Codec<import("./v1/customRenderer.js").CustomRendererNodeType>;
346
+ }>> & Record<"product_chat_custom_message_render_subscribe_interrupt", Codec<undefined>> & Record<"product_chat_custom_message_render_subscribe_stop", Codec<undefined>> & Record<"remote_statement_store_subscribe_start", EnumCodec<{
324
347
  readonly v1: Codec<Uint8Array<ArrayBufferLike>[]>;
325
348
  }>> & Record<"remote_statement_store_subscribe_receive", EnumCodec<{
326
349
  readonly v1: Codec<{
@@ -618,6 +641,24 @@ export declare const Message: Codec<{
618
641
  reason: string;
619
642
  }, "StorageErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "StorageErr::Full">>;
620
643
  };
644
+ } | {
645
+ tag: "host_account_connection_status_subscribe_start";
646
+ value: {
647
+ tag: "v1";
648
+ value: undefined;
649
+ };
650
+ } | {
651
+ tag: "host_account_connection_status_subscribe_receive";
652
+ value: {
653
+ tag: "v1";
654
+ value: "disconnected" | "connected";
655
+ };
656
+ } | {
657
+ tag: "host_account_connection_status_subscribe_interrupt";
658
+ value: undefined;
659
+ } | {
660
+ tag: "host_account_connection_status_subscribe_stop";
661
+ value: undefined;
621
662
  } | {
622
663
  tag: "host_account_get_request";
623
664
  value: {
@@ -886,6 +927,12 @@ export declare const Message: Codec<{
886
927
  messageId: string;
887
928
  emoji: string;
888
929
  };
930
+ } | {
931
+ tag: "Custom";
932
+ value: {
933
+ messageType: string;
934
+ payload: Uint8Array<ArrayBufferLike>;
935
+ };
889
936
  };
890
937
  };
891
938
  };
@@ -956,6 +1003,12 @@ export declare const Message: Codec<{
956
1003
  messageId: string;
957
1004
  emoji: string;
958
1005
  };
1006
+ } | {
1007
+ tag: "Custom";
1008
+ value: {
1009
+ messageType: string;
1010
+ payload: Uint8Array<ArrayBufferLike>;
1011
+ };
959
1012
  };
960
1013
  } | {
961
1014
  tag: "ActionTriggered";
@@ -979,6 +1032,27 @@ export declare const Message: Codec<{
979
1032
  } | {
980
1033
  tag: "host_chat_action_subscribe_stop";
981
1034
  value: undefined;
1035
+ } | {
1036
+ tag: "product_chat_custom_message_render_subscribe_start";
1037
+ value: {
1038
+ tag: "v1";
1039
+ value: {
1040
+ messageType: string;
1041
+ payload: Uint8Array<ArrayBufferLike>;
1042
+ };
1043
+ };
1044
+ } | {
1045
+ tag: "product_chat_custom_message_render_subscribe_receive";
1046
+ value: {
1047
+ tag: "v1";
1048
+ value: import("./v1/customRenderer.js").CustomRendererNodeType;
1049
+ };
1050
+ } | {
1051
+ tag: "product_chat_custom_message_render_subscribe_interrupt";
1052
+ value: undefined;
1053
+ } | {
1054
+ tag: "product_chat_custom_message_render_subscribe_stop";
1055
+ value: undefined;
982
1056
  } | {
983
1057
  tag: "remote_statement_store_subscribe_start";
984
1058
  value: {
@@ -60,6 +60,9 @@ export declare const CreateProofErr: [import("scale-ts").Encoder<import("@novasa
60
60
  reason: string;
61
61
  }, "CreateProofErr::Unknown">;
62
62
  };
63
+ export declare const AccountConnectionStatus: import("scale-ts").Codec<"disconnected" | "connected">;
64
+ export declare const AccountConnectionStatusV1_start: import("scale-ts").Codec<undefined>;
65
+ export declare const AccountConnectionStatusV1_receive: import("scale-ts").Codec<"disconnected" | "connected">;
63
66
  export declare const AccountGetV1_request: import("scale-ts").Codec<[string, number]>;
64
67
  export declare const AccountGetV1_response: import("scale-ts").Codec<import("scale-ts").ResultPayload<{
65
68
  publicKey: Uint8Array<ArrayBufferLike>;
@@ -1,4 +1,4 @@
1
- import { ErrEnum, Hex } from '@novasamatech/scale';
1
+ import { ErrEnum, Hex, Status } from '@novasamatech/scale';
2
2
  import { Bytes, Option, Result, Struct, Tuple, Vector, _void, str, u32 } from 'scale-ts';
3
3
  import { GenericErr, GenesisHash } from '../commonCodecs.js';
4
4
  // common types
@@ -38,6 +38,10 @@ export const CreateProofErr = ErrEnum('CreateProofErr', {
38
38
  Rejected: [_void, 'CreateProof: rejected'],
39
39
  Unknown: [GenericErr, 'CreateProof: unknown error'],
40
40
  });
41
+ // account connection status
42
+ export const AccountConnectionStatus = Status('disconnected', 'connected');
43
+ export const AccountConnectionStatusV1_start = _void;
44
+ export const AccountConnectionStatusV1_receive = AccountConnectionStatus;
41
45
  // account_get
42
46
  export const AccountGetV1_request = ProductAccountId;
43
47
  export const AccountGetV1_response = Result(Account, RequestCredentialsErr);
@@ -1,3 +1,5 @@
1
+ import type { Codec } from 'scale-ts';
2
+ import type { CustomRendererNodeType } from './customRenderer.js';
1
3
  export declare const ChatRoomRegistrationErr: [import("scale-ts").Encoder<import("@novasamatech/scale").CodecError<{
2
4
  reason: string;
3
5
  }, "ChatRoomRegistrationErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "ChatRoomRegistrationErr::PermissionDenied">>, import("scale-ts").Decoder<import("@novasamatech/scale").CodecError<{
@@ -15,21 +17,21 @@ export declare const ChatRoomRegistrationErr: [import("scale-ts").Encoder<import
15
17
  reason: string;
16
18
  }, "ChatRoomRegistrationErr::Unknown">;
17
19
  };
18
- export declare const ChatRoomRequest: import("scale-ts").Codec<{
20
+ export declare const ChatRoomRequest: Codec<{
19
21
  roomId: string;
20
22
  name: string;
21
23
  icon: string;
22
24
  }>;
23
- export declare const ChatRoomRegistrationStatus: import("scale-ts").Codec<"New" | "Exists">;
24
- export declare const ChatRoomRegistrationResult: import("scale-ts").Codec<{
25
+ export declare const ChatRoomRegistrationStatus: Codec<"New" | "Exists">;
26
+ export declare const ChatRoomRegistrationResult: Codec<{
25
27
  status: "New" | "Exists";
26
28
  }>;
27
- export declare const ChatCreateRoomV1_request: import("scale-ts").Codec<{
29
+ export declare const ChatCreateRoomV1_request: Codec<{
28
30
  roomId: string;
29
31
  name: string;
30
32
  icon: string;
31
33
  }>;
32
- export declare const ChatCreateRoomV1_response: import("scale-ts").Codec<import("scale-ts").ResultPayload<{
34
+ export declare const ChatCreateRoomV1_response: Codec<import("scale-ts").ResultPayload<{
33
35
  status: "New" | "Exists";
34
36
  }, import("@novasamatech/scale").CodecError<{
35
37
  reason: string;
@@ -51,41 +53,41 @@ export declare const ChatBotRegistrationErr: [import("scale-ts").Encoder<import(
51
53
  reason: string;
52
54
  }, "ChatBotRegistrationErr::Unknown">;
53
55
  };
54
- export declare const ChatBotRequest: import("scale-ts").Codec<{
56
+ export declare const ChatBotRequest: Codec<{
55
57
  botId: string;
56
58
  name: string;
57
59
  icon: string;
58
60
  }>;
59
- export declare const ChatBotRegistrationStatus: import("scale-ts").Codec<"New" | "Exists">;
60
- export declare const ChatBotRegistrationResult: import("scale-ts").Codec<{
61
+ export declare const ChatBotRegistrationStatus: Codec<"New" | "Exists">;
62
+ export declare const ChatBotRegistrationResult: Codec<{
61
63
  status: "New" | "Exists";
62
64
  }>;
63
- export declare const ChatRegisterBotV1_request: import("scale-ts").Codec<{
65
+ export declare const ChatRegisterBotV1_request: Codec<{
64
66
  botId: string;
65
67
  name: string;
66
68
  icon: string;
67
69
  }>;
68
- export declare const ChatRegisterBotV1_response: import("scale-ts").Codec<import("scale-ts").ResultPayload<{
70
+ export declare const ChatRegisterBotV1_response: Codec<import("scale-ts").ResultPayload<{
69
71
  status: "New" | "Exists";
70
72
  }, import("@novasamatech/scale").CodecError<{
71
73
  reason: string;
72
74
  }, "ChatBotRegistrationErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "ChatBotRegistrationErr::PermissionDenied">>>;
73
- export declare const ChatRoomParticipation: import("scale-ts").Codec<"RoomHost" | "Bot">;
74
- export declare const ChatRoom: import("scale-ts").Codec<{
75
+ export declare const ChatRoomParticipation: Codec<"RoomHost" | "Bot">;
76
+ export declare const ChatRoom: Codec<{
75
77
  roomId: string;
76
78
  participatingAs: "RoomHost" | "Bot";
77
79
  }>;
78
- export declare const ChatListSubscribeV1_start: import("scale-ts").Codec<undefined>;
79
- export declare const ChatListSubscribeV1_receive: import("scale-ts").Codec<{
80
+ export declare const ChatListSubscribeV1_start: Codec<undefined>;
81
+ export declare const ChatListSubscribeV1_receive: Codec<{
80
82
  roomId: string;
81
83
  participatingAs: "RoomHost" | "Bot";
82
84
  }[]>;
83
- export declare const ChatAction: import("scale-ts").Codec<{
85
+ export declare const ChatAction: Codec<{
84
86
  actionId: string;
85
87
  title: string;
86
88
  }>;
87
- export declare const ChatActionLayout: import("scale-ts").Codec<"Column" | "Grid">;
88
- export declare const ChatActions: import("scale-ts").Codec<{
89
+ export declare const ChatActionLayout: Codec<"Column" | "Grid">;
90
+ export declare const ChatActions: Codec<{
89
91
  text: string | undefined;
90
92
  actions: {
91
93
  actionId: string;
@@ -93,27 +95,31 @@ export declare const ChatActions: import("scale-ts").Codec<{
93
95
  }[];
94
96
  layout: "Column" | "Grid";
95
97
  }>;
96
- export declare const ChatMedia: import("scale-ts").Codec<{
98
+ export declare const ChatMedia: Codec<{
97
99
  url: string;
98
100
  }>;
99
- export declare const ChatRichText: import("scale-ts").Codec<{
101
+ export declare const ChatRichText: Codec<{
100
102
  text: string | undefined;
101
103
  media: {
102
104
  url: string;
103
105
  }[];
104
106
  }>;
105
- export declare const ChatFile: import("scale-ts").Codec<{
107
+ export declare const ChatFile: Codec<{
106
108
  url: string;
107
109
  fileName: string;
108
110
  mimeType: string;
109
111
  sizeBytes: bigint;
110
112
  text: string | undefined;
111
113
  }>;
112
- export declare const ChatReaction: import("scale-ts").Codec<{
114
+ export declare const ChatReaction: Codec<{
113
115
  messageId: string;
114
116
  emoji: string;
115
117
  }>;
116
- export declare const ChatMessageContent: import("scale-ts").Codec<{
118
+ export declare const ChatCustomMessage: Codec<{
119
+ messageType: string;
120
+ payload: Uint8Array<ArrayBufferLike>;
121
+ }>;
122
+ export declare const ChatMessageContent: Codec<{
117
123
  tag: "Text";
118
124
  value: string;
119
125
  } | {
@@ -155,6 +161,12 @@ export declare const ChatMessageContent: import("scale-ts").Codec<{
155
161
  messageId: string;
156
162
  emoji: string;
157
163
  };
164
+ } | {
165
+ tag: "Custom";
166
+ value: {
167
+ messageType: string;
168
+ payload: Uint8Array<ArrayBufferLike>;
169
+ };
158
170
  }>;
159
171
  export declare const ChatMessagePostingErr: [import("scale-ts").Encoder<import("@novasamatech/scale").CodecError<{
160
172
  reason: string;
@@ -173,10 +185,10 @@ export declare const ChatMessagePostingErr: [import("scale-ts").Encoder<import("
173
185
  reason: string;
174
186
  }, "ChatMessagePostingErr::Unknown">;
175
187
  };
176
- export declare const ChatPostMessageResult: import("scale-ts").Codec<{
188
+ export declare const ChatPostMessageResult: Codec<{
177
189
  messageId: string;
178
190
  }>;
179
- export declare const ChatPostMessageV1_request: import("scale-ts").Codec<{
191
+ export declare const ChatPostMessageV1_request: Codec<{
180
192
  roomId: string;
181
193
  payload: {
182
194
  tag: "Text";
@@ -220,23 +232,29 @@ export declare const ChatPostMessageV1_request: import("scale-ts").Codec<{
220
232
  messageId: string;
221
233
  emoji: string;
222
234
  };
235
+ } | {
236
+ tag: "Custom";
237
+ value: {
238
+ messageType: string;
239
+ payload: Uint8Array<ArrayBufferLike>;
240
+ };
223
241
  };
224
242
  }>;
225
- export declare const ChatPostMessageV1_response: import("scale-ts").Codec<import("scale-ts").ResultPayload<{
243
+ export declare const ChatPostMessageV1_response: Codec<import("scale-ts").ResultPayload<{
226
244
  messageId: string;
227
245
  }, import("@novasamatech/scale").CodecError<{
228
246
  reason: string;
229
247
  }, "ChatMessagePostingErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "ChatMessagePostingErr::MessageTooLarge">>>;
230
- export declare const ActionTrigger: import("scale-ts").Codec<{
248
+ export declare const ActionTrigger: Codec<{
231
249
  messageId: string;
232
250
  actionId: string;
233
251
  payload: Uint8Array<ArrayBufferLike> | undefined;
234
252
  }>;
235
- export declare const ChatCommand: import("scale-ts").Codec<{
253
+ export declare const ChatCommand: Codec<{
236
254
  command: string;
237
255
  payload: string;
238
256
  }>;
239
- export declare const ChatActionPayload: import("scale-ts").Codec<{
257
+ export declare const ChatActionPayload: Codec<{
240
258
  tag: "MessagePosted";
241
259
  value: {
242
260
  tag: "Text";
@@ -280,6 +298,12 @@ export declare const ChatActionPayload: import("scale-ts").Codec<{
280
298
  messageId: string;
281
299
  emoji: string;
282
300
  };
301
+ } | {
302
+ tag: "Custom";
303
+ value: {
304
+ messageType: string;
305
+ payload: Uint8Array<ArrayBufferLike>;
306
+ };
283
307
  };
284
308
  } | {
285
309
  tag: "ActionTriggered";
@@ -295,7 +319,7 @@ export declare const ChatActionPayload: import("scale-ts").Codec<{
295
319
  payload: string;
296
320
  };
297
321
  }>;
298
- export declare const ReceivedChatAction: import("scale-ts").Codec<{
322
+ export declare const ReceivedChatAction: Codec<{
299
323
  roomId: string;
300
324
  peer: string;
301
325
  payload: {
@@ -342,6 +366,12 @@ export declare const ReceivedChatAction: import("scale-ts").Codec<{
342
366
  messageId: string;
343
367
  emoji: string;
344
368
  };
369
+ } | {
370
+ tag: "Custom";
371
+ value: {
372
+ messageType: string;
373
+ payload: Uint8Array<ArrayBufferLike>;
374
+ };
345
375
  };
346
376
  } | {
347
377
  tag: "ActionTriggered";
@@ -358,8 +388,8 @@ export declare const ReceivedChatAction: import("scale-ts").Codec<{
358
388
  };
359
389
  };
360
390
  }>;
361
- export declare const ChatActionSubscribeV1_start: import("scale-ts").Codec<undefined>;
362
- export declare const ChatActionSubscribeV1_receive: import("scale-ts").Codec<{
391
+ export declare const ChatActionSubscribeV1_start: Codec<undefined>;
392
+ export declare const ChatActionSubscribeV1_receive: Codec<{
363
393
  roomId: string;
364
394
  peer: string;
365
395
  payload: {
@@ -406,6 +436,12 @@ export declare const ChatActionSubscribeV1_receive: import("scale-ts").Codec<{
406
436
  messageId: string;
407
437
  emoji: string;
408
438
  };
439
+ } | {
440
+ tag: "Custom";
441
+ value: {
442
+ messageType: string;
443
+ payload: Uint8Array<ArrayBufferLike>;
444
+ };
409
445
  };
410
446
  } | {
411
447
  tag: "ActionTriggered";
@@ -422,3 +458,8 @@ export declare const ChatActionSubscribeV1_receive: import("scale-ts").Codec<{
422
458
  };
423
459
  };
424
460
  }>;
461
+ export declare const ChatCustomMessageRenderingV1_start: Codec<{
462
+ messageType: string;
463
+ payload: Uint8Array<ArrayBufferLike>;
464
+ }>;
465
+ export declare const ChatCustomMessageRenderingV1_receive: Codec<CustomRendererNodeType>;
@@ -1,6 +1,7 @@
1
1
  import { Enum, ErrEnum, Status } from '@novasamatech/scale';
2
2
  import { Bytes, Option, Result, Struct, Vector, _void, str, u64 } from 'scale-ts';
3
3
  import { GenericErr } from '../commonCodecs.js';
4
+ import { CustomRendererNode } from './customRenderer.js';
4
5
  // room registration
5
6
  export const ChatRoomRegistrationErr = ErrEnum('ChatRoomRegistrationErr', {
6
7
  PermissionDenied: [_void, 'Permission denied'],
@@ -70,6 +71,10 @@ export const ChatReaction = Struct({
70
71
  messageId: str,
71
72
  emoji: str,
72
73
  });
74
+ export const ChatCustomMessage = Struct({
75
+ messageType: str,
76
+ payload: Bytes(),
77
+ });
73
78
  export const ChatMessageContent = Enum({
74
79
  Text: str,
75
80
  RichText: ChatRichText,
@@ -77,6 +82,7 @@ export const ChatMessageContent = Enum({
77
82
  File: ChatFile,
78
83
  Reaction: ChatReaction,
79
84
  ReactionRemoved: ChatReaction,
85
+ Custom: ChatCustomMessage,
80
86
  });
81
87
  // sending message
82
88
  export const ChatMessagePostingErr = ErrEnum('ChatMessagePostingErr', {
@@ -113,3 +119,6 @@ export const ReceivedChatAction = Struct({
113
119
  });
114
120
  export const ChatActionSubscribeV1_start = _void;
115
121
  export const ChatActionSubscribeV1_receive = ReceivedChatAction;
122
+ // custom message rendering
123
+ export const ChatCustomMessageRenderingV1_start = Struct({ messageType: str, payload: Bytes() });
124
+ export const ChatCustomMessageRenderingV1_receive = CustomRendererNode;
@@ -0,0 +1,143 @@
1
+ import type { Codec, CodecType } from 'scale-ts';
2
+ import { _void } from 'scale-ts';
3
+ export declare const Size: Codec<number | bigint>;
4
+ export declare const Dimensions: Codec<[number | bigint, number | bigint, number | bigint | undefined, number | bigint | undefined]>;
5
+ export declare const TypographyStyle: Codec<"titleXL" | "headline" | "bodyM" | "bodyS" | "caption">;
6
+ export declare const ButtonVariant: Codec<"primary" | "secondary" | "text">;
7
+ export declare const ColorToken: Codec<"textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning">;
8
+ export declare const ContentAlignment: Codec<"topStart" | "topCenter" | "topEnd" | "centerStart" | "center" | "centerEnd" | "bottomStart" | "bottomCenter" | "bottomEnd">;
9
+ export declare const HorizontalAlignment: Codec<"center" | "start" | "end">;
10
+ export declare const VerticalAlignment: Codec<"center" | "top" | "bottom">;
11
+ export declare const Arrangement: Codec<"center" | "start" | "end" | "spaceBetween" | "spaceAround" | "spaceEvenly">;
12
+ export declare const Shape: Codec<{
13
+ tag: "Rounded";
14
+ value: number | bigint;
15
+ } | {
16
+ tag: "Circle";
17
+ value: undefined;
18
+ }>;
19
+ export declare const BorderStyle: Codec<{
20
+ width: number | bigint;
21
+ color: "textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning";
22
+ shape: {
23
+ tag: "Rounded";
24
+ value: number | bigint;
25
+ } | {
26
+ tag: "Circle";
27
+ value: undefined;
28
+ } | undefined;
29
+ }>;
30
+ export declare const Modifiers: Codec<{
31
+ margin: [number | bigint, number | bigint, number | bigint | undefined, number | bigint | undefined] | undefined;
32
+ padding: [number | bigint, number | bigint, number | bigint | undefined, number | bigint | undefined] | undefined;
33
+ background: {
34
+ color: "textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning";
35
+ shape: {
36
+ tag: "Rounded";
37
+ value: number | bigint;
38
+ } | {
39
+ tag: "Circle";
40
+ value: undefined;
41
+ } | undefined;
42
+ } | undefined;
43
+ border: {
44
+ width: number | bigint;
45
+ color: "textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning";
46
+ shape: {
47
+ tag: "Rounded";
48
+ value: number | bigint;
49
+ } | {
50
+ tag: "Circle";
51
+ value: undefined;
52
+ } | undefined;
53
+ } | undefined;
54
+ height: number | bigint | undefined;
55
+ width: number | bigint | undefined;
56
+ minWidth: number | bigint | undefined;
57
+ minHeight: number | bigint | undefined;
58
+ fillWidth: boolean | undefined;
59
+ fillHeight: boolean | undefined;
60
+ }>;
61
+ type EnumVariants<T> = {
62
+ [K in keyof T]: {
63
+ tag: K;
64
+ value: T[K];
65
+ };
66
+ }[keyof T];
67
+ type ComponentType<Props extends Codec<any>> = CodecType<ReturnType<typeof Component<Props>>>;
68
+ declare function Component<Props extends Codec<any>>(props: Props): Codec<{
69
+ modifiers: {
70
+ margin: [number | bigint, number | bigint, number | bigint | undefined, number | bigint | undefined] | undefined;
71
+ padding: [number | bigint, number | bigint, number | bigint | undefined, number | bigint | undefined] | undefined;
72
+ background: {
73
+ color: "textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning";
74
+ shape: {
75
+ tag: "Rounded";
76
+ value: number | bigint;
77
+ } | {
78
+ tag: "Circle";
79
+ value: undefined;
80
+ } | undefined;
81
+ } | undefined;
82
+ border: {
83
+ width: number | bigint;
84
+ color: "textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning";
85
+ shape: {
86
+ tag: "Rounded";
87
+ value: number | bigint;
88
+ } | {
89
+ tag: "Circle";
90
+ value: undefined;
91
+ } | undefined;
92
+ } | undefined;
93
+ height: number | bigint | undefined;
94
+ width: number | bigint | undefined;
95
+ minWidth: number | bigint | undefined;
96
+ minHeight: number | bigint | undefined;
97
+ fillWidth: boolean | undefined;
98
+ fillHeight: boolean | undefined;
99
+ } | undefined;
100
+ props: CodecType<Props>;
101
+ children: CustomRendererNodeType[];
102
+ }>;
103
+ export declare const BoxProps: Codec<{
104
+ contentAlignment: "topStart" | "topCenter" | "topEnd" | "centerStart" | "center" | "centerEnd" | "bottomStart" | "bottomCenter" | "bottomEnd" | undefined;
105
+ }>;
106
+ export declare const ColumnProps: Codec<{
107
+ horizontalAlignment: "center" | "start" | "end" | undefined;
108
+ verticalArrangement: "center" | "start" | "end" | "spaceBetween" | "spaceAround" | "spaceEvenly" | undefined;
109
+ }>;
110
+ export declare const RowProps: Codec<{
111
+ verticalAlignment: "center" | "top" | "bottom" | undefined;
112
+ horizontalArrangement: "center" | "start" | "end" | "spaceBetween" | "spaceAround" | "spaceEvenly" | undefined;
113
+ }>;
114
+ export declare const TextProps: Codec<{
115
+ style: "titleXL" | "headline" | "bodyM" | "bodyS" | "caption" | undefined;
116
+ color: "textPrimary" | "textSecondary" | "textTertiary" | "backgroundPrimary" | "backgroundSecondary" | "backgroundTertiary" | "success" | "error" | "warning" | undefined;
117
+ }>;
118
+ export declare const ButtonProps: Codec<{
119
+ variant: "primary" | "secondary" | "text" | undefined;
120
+ enabled: boolean | undefined;
121
+ loading: boolean | undefined;
122
+ clickAction: string | undefined;
123
+ }>;
124
+ export declare const TextFieldProps: Codec<{
125
+ value: string | undefined;
126
+ placeholder: string | undefined;
127
+ label: string | undefined;
128
+ enabled: boolean | undefined;
129
+ valueChangeAction: string | undefined;
130
+ }>;
131
+ export type CustomRendererNodeType = EnumVariants<{
132
+ Nil: undefined;
133
+ String: string;
134
+ Box: ComponentType<typeof BoxProps>;
135
+ Column: ComponentType<typeof ColumnProps>;
136
+ Row: ComponentType<typeof RowProps>;
137
+ Spacer: ComponentType<typeof _void>;
138
+ Text: ComponentType<typeof TextProps>;
139
+ Button: ComponentType<typeof ButtonProps>;
140
+ TextField: ComponentType<typeof TextFieldProps>;
141
+ }>;
142
+ export declare const CustomRendererNode: Codec<CustomRendererNodeType>;
143
+ export {};
@@ -0,0 +1,82 @@
1
+ import { Enum, Status, lazy } from '@novasamatech/scale';
2
+ import { Option, Struct, Tuple, Vector, _void, bool, compact, str } from 'scale-ts';
3
+ export const Size = compact;
4
+ export const Dimensions = Tuple(Size, Size, Option(Size), Option(Size));
5
+ export const TypographyStyle = Status('titleXL', 'headline', 'bodyM', 'bodyS', 'caption');
6
+ export const ButtonVariant = Status('primary', 'secondary', 'text');
7
+ export const ColorToken = Status('textPrimary', 'textSecondary', 'textTertiary', 'backgroundPrimary', 'backgroundSecondary', 'backgroundTertiary', 'success', 'error', 'warning');
8
+ export const ContentAlignment = Status('topStart', 'topCenter', 'topEnd', 'centerStart', 'center', 'centerEnd', 'bottomStart', 'bottomCenter', 'bottomEnd');
9
+ export const HorizontalAlignment = Status('start', 'center', 'end');
10
+ export const VerticalAlignment = Status('top', 'center', 'bottom');
11
+ export const Arrangement = Status('start', 'end', 'center', 'spaceBetween', 'spaceAround', 'spaceEvenly');
12
+ export const Shape = Enum({
13
+ Rounded: Size,
14
+ Circle: _void,
15
+ });
16
+ export const BorderStyle = Struct({
17
+ width: Size,
18
+ color: ColorToken,
19
+ shape: Option(Shape),
20
+ });
21
+ export const Modifiers = Struct({
22
+ margin: Option(Dimensions),
23
+ padding: Option(Dimensions),
24
+ background: Option(Struct({
25
+ color: ColorToken,
26
+ shape: Option(Shape),
27
+ })),
28
+ border: Option(BorderStyle),
29
+ height: Option(Size),
30
+ width: Option(Size),
31
+ minWidth: Option(Size),
32
+ minHeight: Option(Size),
33
+ fillWidth: Option(bool),
34
+ fillHeight: Option(bool),
35
+ });
36
+ const Children = lazy(() => CustomRendererNode);
37
+ function Component(props) {
38
+ return Struct({
39
+ modifiers: Option(Modifiers),
40
+ props: props,
41
+ children: Vector(Children),
42
+ });
43
+ }
44
+ export const BoxProps = Struct({
45
+ contentAlignment: Option(ContentAlignment),
46
+ });
47
+ export const ColumnProps = Struct({
48
+ horizontalAlignment: Option(HorizontalAlignment),
49
+ verticalArrangement: Option(Arrangement),
50
+ });
51
+ export const RowProps = Struct({
52
+ verticalAlignment: Option(VerticalAlignment),
53
+ horizontalArrangement: Option(Arrangement),
54
+ });
55
+ export const TextProps = Struct({
56
+ style: Option(TypographyStyle),
57
+ color: Option(ColorToken),
58
+ });
59
+ export const ButtonProps = Struct({
60
+ variant: Option(ButtonVariant),
61
+ enabled: Option(bool),
62
+ loading: Option(bool),
63
+ clickAction: Option(str),
64
+ });
65
+ export const TextFieldProps = Struct({
66
+ value: Option(str),
67
+ placeholder: Option(str),
68
+ label: Option(str),
69
+ enabled: Option(bool),
70
+ valueChangeAction: Option(str),
71
+ });
72
+ export const CustomRendererNode = Enum({
73
+ Nil: _void,
74
+ String: str,
75
+ Box: Component(BoxProps),
76
+ Column: Component(ColumnProps),
77
+ Row: Component(RowProps),
78
+ Spacer: Component(_void),
79
+ Text: Component(TextProps),
80
+ Button: Component(ButtonProps),
81
+ TextField: Component(TextFieldProps),
82
+ });
@@ -13,12 +13,13 @@ export const SigningResult = Struct({
13
13
  signedTransaction: Option(Hex()),
14
14
  });
15
15
  // sign raw
16
+ const RawPayload = Enum({
17
+ Bytes: Bytes(),
18
+ Payload: str,
19
+ });
16
20
  const SigningRawPayload = Struct({
17
21
  address: str,
18
- data: Enum({
19
- Bytes: Bytes(),
20
- Payload: str,
21
- }),
22
+ data: RawPayload,
22
23
  });
23
24
  export const SignRawV1_request = SigningRawPayload;
24
25
  export const SignRawV1_response = Result(SigningResult, SigningErr);
package/dist/transport.js CHANGED
@@ -181,13 +181,21 @@ export function createTransport(provider) {
181
181
  const unsubStart = transport.listenMessages(startAction, (requestId, payload) => {
182
182
  if (subscriptions.has(requestId))
183
183
  return;
184
+ let interrupted = false;
184
185
  const unsubscribe = handler(payload.value, value => {
185
186
  const receivePayload = enumValue(receiveAction, value);
186
187
  transport.postMessage(requestId, receivePayload);
187
188
  }, () => {
189
+ interrupted = true;
190
+ subscriptions.delete(requestId);
188
191
  transport.postMessage(requestId, enumValue(interruptAction, undefined));
189
192
  });
190
- subscriptions.set(requestId, unsubscribe);
193
+ if (interrupted) {
194
+ unsubscribe();
195
+ }
196
+ else {
197
+ subscriptions.set(requestId, unsubscribe);
198
+ }
191
199
  });
192
200
  const unsubStop = transport.listenMessages(stopAction, requestId => {
193
201
  subscriptions.get(requestId)?.();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novasamatech/host-api",
3
3
  "type": "module",
4
- "version": "0.5.5",
4
+ "version": "0.6.1",
5
5
  "description": "Host API: transport implementation for host - product integration.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "README.md"
22
22
  ],
23
23
  "dependencies": {
24
- "@novasamatech/scale": "0.5.5",
24
+ "@novasamatech/scale": "0.6.1",
25
25
  "@polkadot-api/utils": "^0.2.0",
26
26
  "nanoevents": "9.1.0",
27
27
  "nanoid": "5.1.6",