PHP WebShell
Текущая директория: /opt/BitGoJS/node_modules/@polkadot-api/observable-client/dist
Просмотр файла: index.mjs
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/utils/shareLatest.ts
import { ReplaySubject, share } from "rxjs";
var shareLatest = share({
connector: () => new ReplaySubject(1),
resetOnError: true,
resetOnComplete: true,
resetOnRefCountZero: true
});
// src/utils/concatMapEager.ts
import { defer, Observable as Observable2 } from "rxjs";
var concatMapEager = (mapper, concurrent = Infinity) => (source$) => new Observable2((observer) => {
let topSubscription;
const queues = /* @__PURE__ */ new Map();
const innerSubscriptions = /* @__PURE__ */ new Map();
const results = /* @__PURE__ */ new Map();
let mapperIdx = 0;
let subscriptionIdx = 0;
let observerIdx = 0;
const nextSubscription = () => {
const inner$ = queues.get(subscriptionIdx);
if (!inner$) {
if (innerSubscriptions.size === 0 && (typeof topSubscription === "undefined" || topSubscription.closed)) {
observer.complete();
}
return;
}
const idx = subscriptionIdx++;
queues.delete(idx);
if (observerIdx !== idx) {
results.set(idx, []);
}
innerSubscriptions.set(
idx,
inner$.subscribe({
next(x) {
if (observerIdx === idx) {
observer.next(x);
} else {
results.get(idx).push(x);
}
},
complete() {
innerSubscriptions.delete(idx);
if (idx === observerIdx) {
observerIdx++;
while (results.has(observerIdx)) {
results.get(observerIdx).forEach((x) => observer.next(x));
results.delete(observerIdx);
if (innerSubscriptions.has(observerIdx)) {
break;
}
observerIdx++;
}
}
nextSubscription();
},
error(e) {
observer.error(e);
}
})
);
};
topSubscription = source$.subscribe({
next(outterValue) {
const idx = mapperIdx++;
queues.set(
idx,
defer(() => mapper(outterValue, idx))
);
if (innerSubscriptions.size < concurrent) {
nextSubscription();
}
},
error(e) {
observer.error(e);
},
complete() {
if (innerSubscriptions.size === 0) {
observer.complete();
}
}
});
return () => {
innerSubscriptions.forEach((subscription) => subscription.unsubscribe());
topSubscription.unsubscribe();
queues.clear();
results.clear();
};
});
// src/utils/with-default-value.ts
import { Observable as Observable3 } from "rxjs";
var withDefaultValue = (defaultValue) => (source$) => new Observable3((observer) => {
let hasEmited = false;
const subscription = source$.subscribe({
next(v) {
hasEmited = true;
observer.next(v);
},
error(e) {
observer.error(e);
},
complete() {
observer.complete();
}
});
if (!hasEmited) observer.next(defaultValue);
return subscription;
});
// src/chainHead/chainHead.ts
import { blockHeader } from "@polkadot-api/substrate-bindings";
import {
DisjointError
} from "@polkadot-api/substrate-client";
import {
Observable as Observable17,
ReplaySubject as ReplaySubject2,
Subject as Subject2,
defer as defer2,
distinctUntilChanged as distinctUntilChanged2,
map as map6,
merge as merge2,
mergeMap as mergeMap5,
of as of5,
scan as scan2,
share as share3,
switchMap as switchMap3,
take as take5,
tap
} from "rxjs";
// src/chainHead/enhancers/operationLimitRecovery.ts
import { OperationLimitError } from "@polkadot-api/substrate-client";
import { Observable as Observable4 } from "rxjs";
var PendingTaskQueue = class {
constructor() {
__publicField(this, "first");
__publicField(this, "last");
}
getRemoveFn(node) {
return () => {
if (node.prev) {
node.prev.next = node.next;
} else {
this.first = node.next;
}
if (node.next) {
node.next.prev = node.prev;
} else {
this.last = node.prev;
}
delete node.prev;
delete node.next;
};
}
push(value) {
const newNode = { value };
if (this.last === void 0) {
this.last = this.first = newNode;
} else {
this.last.next = newNode;
newNode.prev = this.last;
this.last = newNode;
}
return this.getRemoveFn(newNode);
}
unshift(value) {
this.first = { value, next: this.first };
this.first.next && (this.first.next.prev = this.first);
this.last || (this.last = this.first);
return this.getRemoveFn(this.first);
}
pop() {
const result = this.first?.value;
if (this.first) {
this.first = this.first.next;
if (!this.first) {
this.last = void 0;
} else {
delete this.first.prev?.next;
delete this.first.prev;
}
}
return result;
}
isEmpty() {
return !this.first;
}
};
var getWithRecovery = () => {
const tearDownOperations = /* @__PURE__ */ new Map();
const setTeardown = (observable, cb) => {
tearDownOperations.set(observable, () => {
tearDownOperations.delete(observable);
cb();
});
};
const teardown = (observable) => {
tearDownOperations.get(observable)?.();
};
const pendingTasks = new PendingTaskQueue();
const unshift = pendingTasks.unshift.bind(pendingTasks);
const push = pendingTasks.push.bind(pendingTasks);
const addTask = (task, topPriority) => {
const fn = topPriority ? unshift : push;
setTeardown(task.source$, fn(task));
};
const onEmptySlot = () => {
const data = pendingTasks.pop();
if (!data) return;
tearDownOperations.delete(data.source$);
process(data);
};
const process = (data) => {
const { source$, observer } = data;
let isOperationLimit = false;
const subscription = source$.subscribe({
next(x) {
observer.next(x);
},
error(e) {
;
(isOperationLimit = e instanceof OperationLimitError) ? addTask(data, true) : observer.error(e);
},
complete() {
observer.complete();
}
});
if (!subscription.closed) {
setTeardown(source$, () => {
subscription.unsubscribe();
onEmptySlot();
});
} else if (!isOperationLimit) onEmptySlot();
};
const withRecovery = (topPriority = false) => (source$) => new Observable4((observer) => {
const pendingTask = { observer, source$ };
if (pendingTasks.isEmpty()) {
process(pendingTask);
} else {
addTask(pendingTask, topPriority);
}
return () => {
teardown(source$);
};
});
const withNormalRecovery = withRecovery();
const withRecoveryFn = (fn) => (...args) => withNormalRecovery(fn(...args));
return { withRecovery, withRecoveryFn };
};
// src/chainHead/enhancers/optionalHash.ts
import { mergeMap, of, take } from "rxjs";
var getWithOptionalhash$ = (finalized$, best$) => {
return (fn) => (hash, ...args) => {
const hash$ = hash === null || hash === "finalized" ? finalized$ : hash === "best" ? best$ : of(hash);
return hash$.pipe(
take(1),
mergeMap((h) => fn(h, ...args))
);
};
};
// src/chainHead/enhancers/fromAbortControllerFn.ts
import { Observable as Observable6 } from "rxjs";
var fromAbortControllerFn = (fn) => (...args) => new Observable6((observer) => {
let aborter = new AbortController();
fn(...[...args, aborter.signal]).then(
(value) => {
observer.next(value);
observer.complete();
},
(error) => {
observer.error(error);
}
);
return () => {
observer.unsubscribe();
aborter.abort();
aborter = void 0;
};
});
// src/chainHead/enhancers/lazyFollower.ts
var withLazyFollower = (getFollower) => (key) => (...args) => getFollower()[key](...args);
// src/chainHead/enhancers/whileBestBlock.ts
import {
Observable as Observable11,
filter as filter3,
mergeMap as mergeMap3,
pipe,
switchMap as switchMap2,
take as take3,
throwError
} from "rxjs";
// src/chainHead/errors.ts
var BlockNotPinnedError = class extends Error {
constructor() {
super("Block is not pinned");
this.name = "BlockNotPinnedError";
}
};
var BlockPrunedError = class extends Error {
constructor() {
super("Block pruned");
this.name = "BlockPrunedError";
}
};
var NotBestBlockError = class extends Error {
constructor() {
super("Block is not best block or finalized");
this.name = "NotBestBlockError";
}
};
// src/chainHead/streams/follow.ts
import {
StopError
} from "@polkadot-api/substrate-client";
import { Observable as Observable7, Subscription as Subscription2, noop, share as share2 } from "rxjs";
var getFollow$ = (chainHead) => {
let follower = null;
let unfollow = noop;
const follow$ = new Observable7((observer) => {
follower = chainHead(
true,
(e) => {
observer.next(e);
},
(e) => {
follower = null;
observer.error(e);
}
);
unfollow = () => {
observer.complete();
follower?.unfollow();
};
}).pipe(share2());
return {
getFollower: () => {
if (!follower) throw new Error("Missing chainHead subscription");
return follower;
},
unfollow: () => {
unfollow();
},
follow$
};
};
var retryOnStopError = () => (source$) => new Observable7((observer) => {
const subscription = new Subscription2();
const subscribe = () => source$.subscribe({
next: (v) => observer.next(v),
error: (e) => {
if (e instanceof StopError) {
observer.next({ type: "stop-error" });
subscription.add(subscribe());
} else {
observer.error(e);
}
},
complete: () => observer.complete()
});
subscription.add(subscribe());
return subscription;
});
// src/chainHead/streams/get-runtime-creator.ts
import {
getChecksumBuilder,
getDynamicBuilder,
getLookupFn
} from "@polkadot-api/metadata-builders";
import {
AccountId,
Option,
u32,
_void,
Bytes,
metadata as metadataCodec,
Vector,
Tuple,
compact
} from "@polkadot-api/substrate-bindings";
import { toHex } from "@polkadot-api/utils";
import {
catchError,
map,
mergeMap as mergeMap2,
of as of2,
shareReplay,
switchMap,
take as take2
} from "rxjs";
var v15Args = toHex(u32.enc(15));
var opaqueMeta14 = Tuple(compact, Bytes());
var opaqueMeta15 = Option(Bytes());
var u32ListDecoder = Vector(u32).dec;
var getRuntimeCreator = (call$, finalized$) => {
const getMetadata$ = (hash) => {
const recoverCall$ = (hash2, method, args) => call$(hash2, method, args).pipe(
catchError((e) => {
if (e instanceof BlockNotPinnedError) {
return finalized$.pipe(
take2(1),
switchMap((newHash) => recoverCall$(newHash, method, args))
);
}
throw e;
})
);
const versions = recoverCall$(hash, "Metadata_metadata_versions", "").pipe(
map(u32ListDecoder)
);
const v14 = recoverCall$(hash, "Metadata_metadata", "").pipe(
map((x) => {
const [, metadataRaw] = opaqueMeta14.dec(x);
const metadata = metadataCodec.dec(metadataRaw);
return { metadata: metadata.metadata.value, metadataRaw };
})
);
const v15 = recoverCall$(
hash,
"Metadata_metadata_at_version",
v15Args
).pipe(
map((x) => {
const metadataRaw = opaqueMeta15.dec(x);
const metadata = metadataCodec.dec(metadataRaw);
return { metadata: metadata.metadata.value, metadataRaw };
})
);
return versions.pipe(
catchError(() => of2([14])),
mergeMap2((v) => v.includes(15) ? v15 : v14)
);
};
return (hash) => {
const usages = /* @__PURE__ */ new Set([hash]);
const runtimeContext$ = getMetadata$(hash).pipe(
map(({ metadata, metadataRaw }) => {
const checksumBuilder = getChecksumBuilder(metadata);
const dynamicBuilder = getDynamicBuilder(metadata);
const events = dynamicBuilder.buildStorage("System", "Events");
const assetPayment = metadata.extrinsic.signedExtensions.find(
(x) => x.identifier === "ChargeAssetTxPayment"
);
let _assetId = null;
if (assetPayment) {
const assetTxPayment = getLookupFn(metadata.lookup)(assetPayment.type);
if (assetTxPayment.type === "struct") {
const optionalAssetId = assetTxPayment.value.asset_id;
if (optionalAssetId.type === "option")
_assetId = optionalAssetId.value.id;
}
}
const asset = _assetId === null ? [_void.enc, null] : [
dynamicBuilder.buildDefinition(_assetId).enc,
checksumBuilder.buildDefinition(_assetId)
];
return {
asset,
metadataRaw,
metadata,
checksumBuilder,
dynamicBuilder,
events: {
key: events.enc(),
dec: events.dec
},
accountId: AccountId(dynamicBuilder.ss58Prefix)
};
}),
shareReplay(1)
);
const result = {
at: hash,
runtime: runtimeContext$,
addBlock: (block) => {
usages.add(block);
return result;
},
deleteBlocks: (blocks) => {
blocks.forEach((block) => {
usages.delete(block);
});
return usages.size;
},
usages
};
runtimeContext$.subscribe();
return result;
};
};
// src/chainHead/streams/pinned-blocks.ts
import {
concatMap,
filter,
map as map2,
merge,
of as of3,
scan
} from "rxjs";
var deleteBlock = (blocks, blockHash) => {
blocks.get(blocks.get(blockHash).parent)?.children.delete(blockHash);
blocks.delete(blockHash);
};
var getBlocksToUnpin = (blocks, pruned) => {
const result = [...pruned];
let current = blocks.blocks.get(blocks.blocks.get(blocks.finalized).parent);
const trail = [];
while (current) {
trail.push(current.hash);
if (current.refCount === 0 && !current.unpinned) {
result.push(current.hash);
current.unpinned = true;
}
current = blocks.blocks.get(current.parent);
}
const deletedBlocks = [...pruned];
for (let i = trail.length - 1; i >= 0; i--) {
current = blocks.blocks.get(trail[i]);
if (!current.unpinned) return result;
deletedBlocks.push(current.hash);
}
deletedBlocks.forEach((hash) => {
deleteBlock(blocks.blocks, hash);
});
Object.entries(blocks.runtimes).map(([key, value]) => ({
key,
usages: value.deleteBlocks(deletedBlocks)
})).filter((x) => x.usages === 0).map((x) => x.key).forEach((unusedRuntime) => {
delete blocks.runtimes[unusedRuntime];
});
return result;
};
var getPinnedBlocks$ = (follow$, getHeader, call$, blockUsage$, onUnpin) => {
const pinnedBlocks$ = merge(
blockUsage$,
follow$.pipe(withInitializedNumber(getHeader), retryOnStopError())
).pipe(
scan((acc, event) => {
switch (event.type) {
case "initialized":
if (acc.recovering) {
const isConnected = event.finalizedBlockHashes.some(
(hash) => acc.blocks.has(hash)
);
if (!isConnected) {
acc = getInitialPinnedBlocks();
}
}
const [finalizedHash] = event.finalizedBlockHashes.slice(-1);
acc.finalized = acc.best = finalizedHash;
const lastIdx = event.finalizedBlockHashes.length - 1;
event.finalizedBlockHashes.forEach((hash, i) => {
if (acc.blocks.has(hash)) {
acc.blocks.get(hash).recovering = false;
} else {
acc.blocks.set(hash, {
hash,
parent: i === 0 ? event.parentHash : event.finalizedBlockHashes[i - 1],
children: new Set(
i === lastIdx ? [] : [event.finalizedBlockHashes[i + 1]]
),
runtime: hash,
refCount: 0,
number: event.number + i,
recovering: false
});
}
});
const finalizedRuntime = Object.values(acc.runtimes).find(
(runtime) => runtime.usages.has(finalizedHash)
);
acc.finalizedRuntime = finalizedRuntime ?? (acc.runtimes[finalizedHash] = getRuntime(finalizedHash));
return acc;
case "stop-error":
for (const block of acc.blocks.values()) {
block.recovering = true;
}
acc.recovering = true;
return acc;
case "newBlock": {
const { parentBlockHash: parent, blockHash: hash } = event;
if (acc.blocks.has(hash)) {
acc.blocks.get(hash).recovering = false;
} else {
const parentNode = acc.blocks.get(parent);
parentNode.children.add(hash);
if (event.newRuntime) {
acc.runtimes[hash] = getRuntime(hash);
acc.runtimes[hash].runtime.subscribe();
}
const block = {
hash,
number: parentNode.number + 1,
parent,
children: /* @__PURE__ */ new Set(),
runtime: event.newRuntime ? hash : parentNode.runtime,
refCount: 0,
recovering: false
};
acc.blocks.set(hash, block);
acc.runtimes[block.runtime].addBlock(hash);
}
return acc;
}
case "bestBlockChanged": {
if (acc.recovering) {
for (const [hash, block] of acc.blocks) {
if (block.recovering) {
deleteBlock(acc.blocks, hash);
}
}
acc.recovering = false;
}
acc.best = event.bestBlockHash;
return acc;
}
case "finalized": {
acc.finalized = event.finalizedBlockHashes.slice(-1)[0];
acc.finalizedRuntime = acc.runtimes[acc.blocks.get(acc.finalized).runtime];
const actuallyPruned = [...new Set(event.prunedBlockHashes)];
onUnpin(getBlocksToUnpin(acc, actuallyPruned));
return acc;
}
case "blockUsage": {
if (!acc.blocks.has(event.value.hash)) return acc;
const block = acc.blocks.get(event.value.hash);
block.refCount += event.value.type === "hold" ? 1 : -1;
if (block.refCount === 0 && block.number < acc.blocks.get(acc.finalized).number && !block.recovering) {
block.unpinned = true;
onUnpin([block.hash]);
}
return acc;
}
}
}, getInitialPinnedBlocks()),
filter((x) => !!x.finalizedRuntime.runtime),
map2((x) => ({ ...x })),
shareLatest
);
const getRuntime = getRuntimeCreator(
withStopRecovery(pinnedBlocks$, call$),
pinnedBlocks$.pipe(map2((v) => v.finalized))
);
return pinnedBlocks$;
};
var getInitialPinnedBlocks = () => ({
best: "",
finalized: "",
runtimes: {},
blocks: /* @__PURE__ */ new Map(),
finalizedRuntime: {},
recovering: false
});
var withInitializedNumber = (getHeader) => (source$) => source$.pipe(
concatMap((event) => {
return event.type !== "initialized" ? of3(event) : getHeader(event.finalizedBlockHashes[0]).then((header) => ({
...event,
number: header.number,
parentHash: header.parentHash
}));
})
);
// src/chainHead/streams/block-operations.ts
import { distinctUntilChanged, filter as filter2, map as map3, takeWhile } from "rxjs";
var isBestOrFinalizedBlock = (blocks$, blockHash) => blocks$.pipe(
takeWhile((b) => b.blocks.has(blockHash)),
distinctUntilChanged(
(a, b) => a.finalized === b.finalized && a.best === b.best
),
filter2(
(x) => x.blocks.get(x.best).number >= x.blocks.get(blockHash).number
),
map3((pinned) => {
const { number } = pinned.blocks.get(blockHash);
let current = pinned.blocks.get(pinned.best);
let isFinalized = pinned.finalized === current.hash;
while (current.number > number) {
current = pinned.blocks.get(current.parent);
isFinalized = isFinalized || pinned.finalized === current.hash;
}
if (isFinalized) return "finalized";
return current.hash === blockHash ? "best" : null;
}),
distinctUntilChanged(),
takeWhile((x) => x !== "finalized", true)
);
// src/chainHead/enhancers/whileBestBlock.ts
function withEnsureCanonicalChain(blocks$, follow$, fn) {
return (hash, ensureCanonical, ...args) => {
const enhancer = ensureCanonical ? pipe(
throwWhenPrune(
hash,
follow$.pipe(
retryOnStopError(),
filter3((evt) => evt.type === "finalized"),
mergeMap3((evt) => evt.prunedBlockHashes)
)
),
onlyIfIsBestOrFinalized(hash, blocks$)
) : (x) => x;
return enhancer(fn(hash, ...args));
};
}
var onlyIfIsBestOrFinalized = (hash, blocks$) => (source$) => isBestOrFinalizedBlock(blocks$, hash).pipe(
take3(1),
switchMap2(
(isBest) => isBest ? source$ : throwError(() => new NotBestBlockError())
)
);
var throwWhenPrune = (hash, pruned$) => (source$) => new Observable11((subscriber) => {
const prunedSubscription = pruned$.pipe(filter3((h) => h === hash)).subscribe(() => {
subscriber.error(new BlockPrunedError());
});
const sourceSubscription = source$.subscribe(subscriber);
return () => {
prunedSubscription.unsubscribe();
sourceSubscription.unsubscribe();
};
});
// src/chainHead/enhancers/withStopRecovery.ts
import { Observable as Observable12 } from "rxjs";
function withStopRecovery(blocks$, fn) {
return (hash, ...args) => {
const source$ = fn(hash, ...args);
return new Observable12((observer) => {
let sourceSub = null;
let isSubscribed = false;
const performSourceSub = () => {
if (isSubscribed) return;
isSubscribed = true;
sourceSub = source$.subscribe({
next: (v) => observer.next(v),
error: (e) => observer.error(e),
complete: () => observer.complete()
});
sourceSub.add(() => {
isSubscribed = false;
sourceSub = null;
});
};
let isRecovering = false;
const blockSub = blocks$.subscribe({
next: (v) => {
const block = v.blocks.get(hash);
if (!block) {
if (isRecovering) {
observer.error(new BlockNotPinnedError());
}
} else if (block.recovering) {
sourceSub?.unsubscribe();
} else {
performSourceSub();
}
isRecovering = v.recovering;
},
error: (e) => observer.error(e)
});
return () => {
blockSub.unsubscribe();
sourceSub?.unsubscribe();
};
});
};
}
// src/chainHead/enhancers/operationInaccessibleRecovery.ts
import { OperationInaccessibleError } from "@polkadot-api/substrate-client";
import { catchError as catchError2, concatMap as concatMap2, throwError as throwError2, timer } from "rxjs";
var operable = (source$) => {
const result = source$.pipe(
catchError2(
(e) => e instanceof OperationInaccessibleError ? timer(750).pipe(concatMap2(() => result)) : throwError2(() => e)
)
);
return result;
};
var withOperationInaccessibleRecovery = (fn) => (...args) => operable(fn(...args));
// src/chainHead/storage-queries.ts
import { Observable as Observable14, mergeAll } from "rxjs";
var getRecoveralStorage$ = (getFollower, withRecovery) => {
const recoveralStorage$ = (hash, queries, childTrie, isHighPriority) => new Observable14(
(observer) => getFollower().storageSubscription(
hash,
queries,
childTrie ?? null,
(items) => {
observer.next(items);
},
(error) => {
observer.error(error);
},
() => {
observer.complete();
},
(nDiscarded) => {
if (nDiscarded === 0) return;
observer.next(
recoveralStorage$(
hash,
queries.slice(-nDiscarded),
childTrie,
true
)
);
}
)
).pipe(mergeAll(), withRecovery(isHighPriority));
return recoveralStorage$;
};
// src/chainHead/track-tx.ts
import {
distinct,
filter as filter4,
map as map4,
mergeMap as mergeMap4,
of as of4,
take as take4,
takeUntil
} from "rxjs";
var getTrackTx = (blocks$, getBody, getIsValid, getEvents) => {
const whileBlockPresent = (hash) => takeUntil(blocks$.pipe(filter4(({ blocks }) => !blocks.has(hash))));
const analyzeBlock = (hash, tx, alreadyPresent) => {
if (alreadyPresent)
return of4({ hash, found: { type: false, isValid: true } });
const whilePresent = whileBlockPresent(hash);
return getBody(hash).pipe(
mergeMap4((txs) => {
const index = txs.indexOf(tx);
return index > -1 ? whilePresent(getEvents(hash)).pipe(
map4((events) => ({
hash,
found: {
type: true,
index,
events
}
}))
) : getIsValid(hash, tx).pipe(
map4((isValid) => ({
hash,
found: { type: false, isValid }
}))
);
}),
whilePresent
);
};
const findInBranch = (hash, tx, alreadyPresent) => analyzeBlock(hash, tx, alreadyPresent.has(hash)).pipe(
mergeMap4((analyzed) => {
const { found } = analyzed;
return found.type || !found.isValid ? of4(analyzed) : blocks$.pipe(
whileBlockPresent(hash),
mergeMap4((x) => x.blocks.get(hash).children),
distinct(),
mergeMap4((hash2) => findInBranch(hash2, tx, alreadyPresent))
);
})
);
return (tx) => blocks$.pipe(
take4(1),
mergeMap4((x) => findInBranch(x.finalized, tx, new Set(x.blocks.keys())))
);
};
// src/chainHead/validate-tx.ts
import { map as map5 } from "rxjs";
import { fromHex, mergeUint8, toHex as toHex2 } from "@polkadot-api/utils";
var external = new Uint8Array([2]);
var getValidateTxArgs = (tx, hash) => toHex2(mergeUint8(external, fromHex(tx), fromHex(hash)));
var getValidateTx = (call$) => (blockHash, tx) => call$(
blockHash,
"TaggedTransactionQueue_validate_transaction",
getValidateTxArgs(tx, blockHash)
).pipe(map5((x) => x.startsWith("0x00")));
// src/chainHead/chainHead.ts
var toBlockInfo = ({ hash, number, parent }) => ({
hash,
number,
parent
});
var getChainHead$ = (chainHead) => {
const { getFollower, unfollow, follow$ } = getFollow$(chainHead);
const lazyFollower = withLazyFollower(getFollower);
const { withRecovery, withRecoveryFn } = getWithRecovery();
const blockUsage$ = new Subject2();
const withRefcount = (fn) => (hash, ...args) => new Observable17((observer) => {
blockUsage$.next({ type: "blockUsage", value: { type: "hold", hash } });
const subscription = fn(hash, ...args).subscribe(observer);
return () => {
setTimeout(() => {
blockUsage$.next({
type: "blockUsage",
value: { type: "release", hash }
});
}, 0);
subscription.unsubscribe();
};
});
const withInMemory = (fn) => (hash, ...args) => new Observable17((observer) => {
let isPresent = false;
pinnedBlocks$.pipe(take5(1)).subscribe((blocks) => {
const block = blocks.blocks.get(hash);
isPresent = !!block && !block.unpinned;
});
return isPresent ? fn(hash, ...args).subscribe(observer) : observer.error(new BlockNotPinnedError());
});
const getHeader = (hash) => getFollower().header(hash).then(blockHeader.dec);
const unpin = (hashes) => getFollower().unpin(hashes).catch((e) => {
if (e instanceof DisjointError) return;
throw e;
});
const commonEnhancer = (fn) => {
const canonicalChain = (_fn) => withEnsureCanonicalChain(pinnedBlocks$, follow$, _fn);
return withInMemory(
withRefcount(
canonicalChain(
withStopRecovery(
pinnedBlocks$,
withOperationInaccessibleRecovery(
withRecoveryFn(fromAbortControllerFn(fn))
)
)
)
)
);
};
const withCanonicalChain = (fn, withCanonicalChain2 = true) => (hash, ...args) => fn(hash, withCanonicalChain2, ...args);
const _call$ = withOperationInaccessibleRecovery(
withRecoveryFn(fromAbortControllerFn(lazyFollower("call")))
);
const cache = /* @__PURE__ */ new Map();
const pinnedBlocks$ = getPinnedBlocks$(
follow$,
getHeader,
withRefcount(_call$),
blockUsage$,
(blocks) => {
unpin(blocks);
blocks.forEach((hash) => {
cache.delete(hash);
});
}
);
const getRuntimeContext$ = withRefcount(
(hash) => pinnedBlocks$.pipe(
take5(1),
mergeMap5(
(pinned) => pinned.runtimes[pinned.blocks.get(hash).runtime].runtime
)
)
);
const withRuntime = (mapper) => (source$) => source$.pipe(
concatMapEager(
(x) => getRuntimeContext$(mapper(x)).pipe(map6((runtime) => [x, runtime]))
)
);
const upsertCachedStream = (hash, key, stream) => {
const hashCache = cache.get(hash) ?? /* @__PURE__ */ new Map();
const cached = hashCache.get(key);
if (cached) return cached;
cache.set(hash, hashCache);
const connector = new ReplaySubject2();
const result = stream.pipe(
share3({
connector: () => connector
}),
tap({
complete() {
hashCache.set(key, connector);
}
})
);
hashCache.set(key, result);
return result;
};
const finalized$ = pinnedBlocks$.pipe(
distinctUntilChanged2((a, b) => a.finalized === b.finalized),
map6((pinned) => toBlockInfo(pinned.blocks.get(pinned.finalized))),
shareLatest
);
const best$ = pinnedBlocks$.pipe(
distinctUntilChanged2((a, b) => a.best === b.best),
map6((pinned) => toBlockInfo(pinned.blocks.get(pinned.best))),
shareLatest
);
const bestBlocks$ = pinnedBlocks$.pipe(
distinctUntilChanged2(
(prev, current) => prev.finalized === current.finalized && prev.best === current.best
),
scan2((acc, pinned) => {
const getBlockInfo = (hash) => acc.get(hash) || toBlockInfo(pinned.blocks.get(hash));
const best = getBlockInfo(pinned.best);
const finalized = getBlockInfo(pinned.finalized);
const len = best.number - finalized.number + 1;
const result = new Array(len);
for (let i = 0, hash = best.hash; i < len; i++) {
result[i] = getBlockInfo(hash);
hash = result[i].parent;
}
return new Map(result.map((b) => [b.hash, b]));
}, /* @__PURE__ */ new Map()),
map6((x) => [...x.values()]),
shareLatest
);
const runtime$ = pinnedBlocks$.pipe(
distinctUntilChanged2((a, b) => a.finalizedRuntime === b.finalizedRuntime),
switchMap3(
({ finalizedRuntime: { runtime } }) => runtime.pipe(withDefaultValue(null))
),
shareLatest
);
const metadata$ = runtime$.pipe(map6((x) => x?.metadata ?? null));
const withOptionalHash$ = getWithOptionalhash$(
finalized$.pipe(map6((b) => b.hash)),
best$.pipe(map6((b) => b.hash))
);
const _body$ = commonEnhancer(lazyFollower("body"));
const body$ = (hash) => upsertCachedStream(hash, "body", _body$(hash, true));
const _storage$ = commonEnhancer(lazyFollower("storage"));
const storage$ = withOptionalHash$(
(hash, withCanonicalChain2, type, keyMapper, childTrie = null, mapper) => pinnedBlocks$.pipe(
take5(1),
mergeMap5(
(pinned) => pinned.runtimes[pinned.blocks.get(hash).runtime].runtime
),
mergeMap5((ctx) => {
const key = keyMapper(ctx);
const unMapped$ = upsertCachedStream(
hash,
`storage-${type}-${key}-${childTrie ?? ""}`,
_storage$(hash, withCanonicalChain2, type, key, childTrie)
);
return mapper ? upsertCachedStream(
hash,
`storage-${type}-${key}-${childTrie ?? ""}-dec`,
unMapped$.pipe(map6((x) => mapper(x, ctx)))
) : unMapped$;
})
)
);
const recoveralStorage$ = getRecoveralStorage$(getFollower, withRecovery);
const storageQueries$ = withOperationInaccessibleRecovery(
withOptionalHash$(
withRefcount(
withStopRecovery(
pinnedBlocks$,
(hash, queries, childTrie) => recoveralStorage$(hash, queries, childTrie ?? null, false)
)
)
)
);
const header$ = withOptionalHash$(
withRefcount(
withStopRecovery(
pinnedBlocks$,
(hash) => defer2(() => getHeader(hash))
)
)
);
merge2(runtime$, bestBlocks$).subscribe();
const eventsAt$ = (hash, canonical = false) => storage$(
hash,
canonical,
"value",
(ctx) => ctx.events.key,
null,
(x, ctx) => ctx.events.dec(x)
);
const __call$ = commonEnhancer(lazyFollower("call"));
const call$ = withOptionalHash$(
(hash, canonical, fn, args) => upsertCachedStream(
hash,
`call-${fn}-${args}`,
__call$(hash, canonical, fn, args)
)
);
const validateTx$ = getValidateTx(withCanonicalChain(call$, false));
const innerBody$ = (hash) => upsertCachedStream(hash, "body", _body$(hash, false));
const trackTx$ = getTrackTx(pinnedBlocks$, innerBody$, validateTx$, eventsAt$);
const trackTxWithoutEvents$ = getTrackTx(
pinnedBlocks$,
innerBody$,
validateTx$,
() => of5()
);
return {
follow$,
finalized$,
best$,
bestBlocks$,
runtime$,
metadata$,
header$,
body$,
call$: withCanonicalChain(call$),
storage$: withCanonicalChain(storage$),
storageQueries$,
eventsAt$: withCanonicalChain(eventsAt$),
trackTx$,
trackTxWithoutEvents$,
validateTx$,
pinnedBlocks$,
withRuntime,
getRuntimeContext$: withOptionalHash$(getRuntimeContext$),
unfollow
};
};
// src/tx.ts
import { Observable as Observable18 } from "rxjs";
var tx_default = (baseTransaction) => (transaction) => new Observable18(
(observer) => baseTransaction(transaction, (e) => {
observer.error(e);
})
);
// src/getObservableClient.ts
var getObservableClient = ({
chainHead,
transaction,
destroy
}) => ({
chainHead$: () => getChainHead$(chainHead),
broadcastTx$: tx_default(transaction),
destroy
});
export {
BlockNotPinnedError,
BlockPrunedError,
NotBestBlockError,
getObservableClient
};
//# sourceMappingURL=index.mjs.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!