@novasamatech/host-container 0.8.7 → 0.8.9

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.
@@ -12,7 +12,7 @@ export declare function createChainConnectionManager(factory: (genesisHash: HexS
12
12
  stopFollow(genesisHash: HexString, followId: string): void;
13
13
  hasActiveFollow(genesisHash: HexString): boolean;
14
14
  chainHeadOp(genesisHash: HexString, method: string, params: unknown[]): Promise<unknown>;
15
- sendRequest(genesisHash: HexString, method: string, params: unknown[]): Promise<unknown>;
15
+ sendRequest<T = unknown>(genesisHash: HexString, method: string, params: unknown[]): Promise<T>;
16
16
  releaseChain(genesisHash: HexString): void;
17
17
  dispose(): void;
18
18
  convertJsonRpcEventToTyped: typeof convertJsonRpcEventToTyped;
@@ -346,6 +346,8 @@ export function createContainer(provider, options = {}) {
346
346
  init();
347
347
  const manager = createChainConnectionManager(factory);
348
348
  const cleanups = [];
349
+ // `${genesisHash}:${operationId}` for each broadcast holding a chain ref.
350
+ const liveBroadcasts = new Set();
349
351
  // Follow subscription
350
352
  cleanups.push(transport.handleSubscription('remote_chain_head_follow_subscribe', (params, send, interrupt) => {
351
353
  if (!isEnumVariant(params, 'v1')) {
@@ -580,14 +582,25 @@ export function createContainer(provider, options = {}) {
580
582
  return enumValue('v1', resultErr(new GenericError({ reason: 'Chain not supported' })));
581
583
  }
582
584
  try {
583
- const result = await manager.sendRequest(genesisHash, 'transaction_v1_broadcast', [transaction]);
584
- return enumValue('v1', resultOk(result ?? null));
585
+ const operationId = await manager.sendRequest(genesisHash, 'transaction_v1_broadcast', [
586
+ transaction,
587
+ ]);
588
+ // `transaction_v1_broadcast` is not one-shot: the node re-broadcasts
589
+ // only while the connection lives, until a matching
590
+ // `transaction_v1_stop`. Keep the chain ref acquired above by
591
+ // recording the live operation; the stop handler releases it.
592
+ // A null operationId means nothing to stop, so release now.
593
+ if (operationId) {
594
+ liveBroadcasts.add(`${genesisHash}:${operationId}`);
595
+ }
596
+ else {
597
+ manager.releaseChain(genesisHash);
598
+ }
599
+ return enumValue('v1', resultOk(operationId));
585
600
  }
586
601
  catch (e) {
587
- return enumValue('v1', resultErr(new GenericError({ reason: String(e) })));
588
- }
589
- finally {
590
602
  manager.releaseChain(genesisHash);
603
+ return enumValue('v1', resultErr(new GenericError({ reason: String(e) })));
591
604
  }
592
605
  }));
593
606
  // Transaction stop
@@ -596,19 +609,23 @@ export function createContainer(provider, options = {}) {
596
609
  return enumValue('v1', resultErr(new GenericError({ reason: UNSUPPORTED_MESSAGE_FORMAT_ERROR })));
597
610
  }
598
611
  const { genesisHash, operationId } = message.value;
599
- const entry = manager.getOrCreateChain(genesisHash);
600
- if (!entry) {
601
- return enumValue('v1', resultErr(new GenericError({ reason: 'Chain not supported' })));
612
+ // Only a stop matching a live broadcast releases the ref that broadcast
613
+ // holds (over its still-open connection). Duplicate or unknown stops
614
+ // are no-op successes, so refCount can't be driven below what the live
615
+ // broadcasts justify.
616
+ if (!liveBroadcasts.delete(`${genesisHash}:${operationId}`)) {
617
+ return enumValue('v1', resultOk(undefined));
602
618
  }
603
619
  try {
604
620
  await manager.sendRequest(genesisHash, 'transaction_v1_stop', [operationId]);
605
- manager.releaseChain(genesisHash);
606
621
  return enumValue('v1', resultOk(undefined));
607
622
  }
608
623
  catch (e) {
609
- manager.releaseChain(genesisHash);
610
624
  return enumValue('v1', resultErr(new GenericError({ reason: String(e) })));
611
625
  }
626
+ finally {
627
+ manager.releaseChain(genesisHash);
628
+ }
612
629
  }));
613
630
  let disposed = false;
614
631
  const dispose = () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novasamatech/host-container",
3
3
  "type": "module",
4
- "version": "0.8.7",
4
+ "version": "0.8.9",
5
5
  "description": "Host container for hosting and managing products within the Polkadot ecosystem.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -28,7 +28,7 @@
28
28
  "@noble/hashes": "2.2.0",
29
29
  "polkadot-api": ">=2",
30
30
  "@polkadot-api/substrate-client": "^0.7.0",
31
- "@novasamatech/host-api": "0.8.7",
31
+ "@novasamatech/host-api": "0.8.9",
32
32
  "nanoevents": "9.1.0",
33
33
  "nanoid": "5.1.11",
34
34
  "neverthrow": "^8.2.0"