mirror of
https://github.com/pezkuwichain/pezkuwi-api.git
synced 2026-04-22 18:27:57 +00:00
Rebrand: polkadot → pezkuwi, substrate → bizinikiwi, kusama → dicle
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@pezkuwi/dev-test/globals.d.ts" />
|
||||
|
||||
import type { ApprovalFlag } from '@pezkuwi/types/interfaces';
|
||||
|
||||
import { TypeRegistry } from '@pezkuwi/types/create';
|
||||
|
||||
import { approvalFlagsToBools } from './approvalFlagsToBools.js';
|
||||
|
||||
describe('approvalFlagsToBools', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('translates and empty array to empty', (): void => {
|
||||
expect(
|
||||
approvalFlagsToBools([] as ApprovalFlag[])
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('translates a single input', (): void => {
|
||||
expect(
|
||||
approvalFlagsToBools([
|
||||
registry.createType('ApprovalFlag', 0b1010)
|
||||
])
|
||||
).toEqual([false, true, false, true]);
|
||||
});
|
||||
|
||||
it('translates multiple inputs', (): void => {
|
||||
expect(
|
||||
approvalFlagsToBools([
|
||||
registry.createType('ApprovalFlag', 0b0000),
|
||||
registry.createType('ApprovalFlag', 0b1100)
|
||||
])
|
||||
).toEqual([false, false, false, true, true]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Vec } from '@pezkuwi/types';
|
||||
import type { ApprovalFlag } from '@pezkuwi/types/interfaces/elections';
|
||||
|
||||
/** @internal */
|
||||
export function approvalFlagsToBools (flags: Vec<ApprovalFlag> | ApprovalFlag[]): boolean[] {
|
||||
const bools: boolean[] = [];
|
||||
|
||||
for (let i = 0, count = flags.length; i < count; i++) {
|
||||
const str = flags[i].toString(2);
|
||||
|
||||
// read from lowest bit to highest
|
||||
for (const bit of str.split('').reverse()) {
|
||||
bools.push(!!parseInt(bit, 10));
|
||||
}
|
||||
}
|
||||
|
||||
// slice off trailing "false" values, as in bizinikiwi
|
||||
const lastApproval = bools.lastIndexOf(true);
|
||||
|
||||
return lastApproval >= 0
|
||||
? bools.slice(0, lastApproval + 1)
|
||||
: [];
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Compact } from '@pezkuwi/types';
|
||||
import type { BlockNumber } from '@pezkuwi/types/interfaces';
|
||||
|
||||
import { isCompact } from '@pezkuwi/util';
|
||||
|
||||
interface CompatHeader { number: Compact<BlockNumber> | BlockNumber }
|
||||
|
||||
export function unwrapBlockNumber (hdr: CompatHeader): BlockNumber {
|
||||
return isCompact<BlockNumber>(hdr.number)
|
||||
? hdr.number.unwrap()
|
||||
: hdr.number;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { DeriveCache } from './types.js';
|
||||
|
||||
import { deriveNoopCache } from './cacheImpl.js';
|
||||
|
||||
interface CacheValue<T> {
|
||||
v: T;
|
||||
x: number;
|
||||
}
|
||||
|
||||
const CACHE_EXPIRY = 7 * (24 * 60) * (60 * 1000);
|
||||
|
||||
let deriveCache: DeriveCache;
|
||||
|
||||
function wrapCache (keyStart: string, cache: DeriveCache): DeriveCache {
|
||||
return {
|
||||
del: (partial: string): void => cache.del(`${keyStart}${partial}`),
|
||||
forEach: cache.forEach,
|
||||
get: <T> (partial: string): T | undefined => {
|
||||
const key = `${keyStart}${partial}`;
|
||||
const cached = cache.get<CacheValue<T>>(key);
|
||||
|
||||
if (cached) {
|
||||
cached.x = Date.now();
|
||||
cache.set(key, cached);
|
||||
|
||||
return cached.v;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
set: (partial: string, v: unknown): void => {
|
||||
cache.set(`${keyStart}${partial}`, { v, x: Date.now() });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function clearCache (cache: DeriveCache): void {
|
||||
// clear all expired values
|
||||
const now = Date.now();
|
||||
const all: string[] = [];
|
||||
|
||||
cache.forEach((key: string, { x }: CacheValue<any>): void => {
|
||||
((now - x) > CACHE_EXPIRY) && all.push(key);
|
||||
});
|
||||
|
||||
// don't do delete inside loop, just in-case
|
||||
all.forEach((key) => cache.del(key));
|
||||
}
|
||||
|
||||
export function setDeriveCache (prefix = '', cache?: DeriveCache): void {
|
||||
deriveCache = cache
|
||||
? wrapCache(`derive:${prefix}:`, cache)
|
||||
: deriveNoopCache;
|
||||
|
||||
if (cache) {
|
||||
clearCache(cache);
|
||||
}
|
||||
}
|
||||
|
||||
setDeriveCache();
|
||||
|
||||
export { deriveCache };
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { DeriveCache } from './types.js';
|
||||
|
||||
const mapCache = new Map<string, any>();
|
||||
|
||||
export const deriveMapCache: DeriveCache = {
|
||||
del: (key: string): void => {
|
||||
mapCache.delete(key);
|
||||
},
|
||||
forEach: (cb: (key: string, value: any) => void): void => {
|
||||
for (const [k, v] of mapCache.entries()) {
|
||||
cb(k, v);
|
||||
}
|
||||
},
|
||||
get: <T = any> (key: string): T | undefined => {
|
||||
return mapCache.get(key) as T;
|
||||
},
|
||||
set: (key: string, value: any): void => {
|
||||
mapCache.set(key, value);
|
||||
}
|
||||
};
|
||||
|
||||
export const deriveNoopCache: DeriveCache = {
|
||||
del: (): void => undefined,
|
||||
forEach: () => undefined,
|
||||
get: (): undefined => undefined,
|
||||
set: (_: string, value: unknown): unknown => value
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { DeriveApi } from '../types.js';
|
||||
|
||||
import { map } from 'rxjs';
|
||||
|
||||
import { memo } from '@pezkuwi/rpc-core';
|
||||
|
||||
export function firstObservable <T> (obs: Observable<T[]>): Observable<T> {
|
||||
return obs.pipe(map(([a]) => a));
|
||||
}
|
||||
|
||||
export function firstMemo <T, A extends any[]> (fn: (api: DeriveApi, ...args: A) => Observable<T[]>): (instanceId: string, api: DeriveApi) => (...args: A) => Observable<T> {
|
||||
return (instanceId: string, api: DeriveApi) =>
|
||||
memo(instanceId, (...args: A) =>
|
||||
firstObservable<T>(fn(api, ...args))
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// all named
|
||||
export { drr, memo } from '@pezkuwi/rpc-core';
|
||||
|
||||
// all starred
|
||||
export * from './approvalFlagsToBools.js';
|
||||
export * from './blockNumber.js';
|
||||
export * from './cache.js';
|
||||
export * from './cacheImpl.js';
|
||||
export * from './first.js';
|
||||
export * from './lazy.js';
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { lazyMethod, lazyMethods } from '@pezkuwi/util';
|
||||
|
||||
type LazySection <T> = Record<string, T>;
|
||||
|
||||
type LazyRecord <T> = Record<string, LazySection<T>>;
|
||||
|
||||
export function lazyDeriveSection <T> (result: LazyRecord<T>, section: string, getKeys: (s: string) => string[], creator: (s: string, m: string) => T): void {
|
||||
lazyMethod(result, section, () =>
|
||||
lazyMethods({}, getKeys(section), (method: string) =>
|
||||
creator(section, method)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2017-2025 @pezkuwi/api-derive authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export interface DeriveCache {
|
||||
del: (key: string) => void;
|
||||
forEach: (cb: (key: string, value: any) => void) => void;
|
||||
get: <T = any> (key: string) => T | undefined;
|
||||
set: (key: string, value: any) => void;
|
||||
}
|
||||
Reference in New Issue
Block a user