async-call-rpc
Advanced tools
Comparing version 6.1.5 to 6.2.0
{ | ||
"name": "async-call-rpc", | ||
"packageManager": "pnpm@7.9.0", | ||
"version": "6.1.5", | ||
"packageManager": "pnpm@8.3.1", | ||
"version": "6.2.0", | ||
"description": "A lightweight JSON RPC server & client", | ||
@@ -53,5 +53,19 @@ "main": "out/base.js", | ||
}, | ||
"scripts": { | ||
"publish": "pnpm run clean && pnpm run build && pnpm run doc:api && pnpm test && npx changeset publish", | ||
"clean": "rimraf ./out ./utils/web ./utils/node ./es ./coverage ./dist", | ||
"watch:tsc": "tsc -b -w", | ||
"build:tsc": "tsc -b", | ||
"watch:rollup": "rollup -c -w", | ||
"build:rollup": "rollup -c", | ||
"build": "pnpm run build:tsc && pnpm run build:rollup", | ||
"doc:api": "api-extractor run --local --verbose && api-extractor run --local -c ./api-extractor-base.json", | ||
"doc:md": "api-documenter markdown -o docs -i dist/api-extractor", | ||
"doc": "run-s doc:api doc:md", | ||
"start": "run-p watch:rollup watch:tsc watch:test", | ||
"test": "vitest --coverage" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Jack-Works/async-call.git" | ||
"url": "git+https://github.com/Jack-Works/async-call-rpc" | ||
}, | ||
@@ -68,26 +82,26 @@ "keywords": [ | ||
"devDependencies": { | ||
"@changesets/cli": "^2.24.2", | ||
"@microsoft/api-documenter": "^7.19.4", | ||
"@microsoft/api-extractor": "^7.29.2", | ||
"@msgpack/msgpack": "^2.7.2", | ||
"@rollup/plugin-sucrase": "^4.0.4", | ||
"@types/node": "^18.7.1", | ||
"@types/ws": "^8.5.3", | ||
"@vitest/ui": "^0.21.1", | ||
"@changesets/cli": "^2.26.1", | ||
"@microsoft/api-documenter": "^7.21.7", | ||
"@microsoft/api-extractor": "^7.34.4", | ||
"@msgpack/msgpack": "3.0.0-beta2", | ||
"@swc/core": "^1.3.52", | ||
"@types/node": "^18.15.11", | ||
"@types/ws": "^8.5.4", | ||
"@vitest/coverage-c8": "^0.30.1", | ||
"@vitest/ui": "^0.30.1", | ||
"async-call-rpc": "link:", | ||
"bson": "^4.6.5", | ||
"c8": "^7.12.0", | ||
"bson": "^5.2.0", | ||
"c8": "^7.13.0", | ||
"jest-file-snapshot": "^0.5.0", | ||
"npm-run-all": "^4.1.5", | ||
"prettier": "^2.7.1", | ||
"pretty-format": "^28.1.3", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.77.3", | ||
"rollup-plugin-dts": "^4.2.2", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"tslib": "^2.4.0", | ||
"typescript": "^4.7.4", | ||
"vite": "^3.0.6", | ||
"vitest": "^0.21.1", | ||
"ws": "^8.8.1" | ||
"prettier": "^2.8.7", | ||
"pretty-format": "^29.5.0", | ||
"rimraf": "^5.0.0", | ||
"rollup": "^3.20.6", | ||
"rollup-plugin-swc3": "^0.8.1", | ||
"serve": "^14.2.0", | ||
"typescript": "^5.0.4", | ||
"vite": "^4.2.2", | ||
"vitest": "^0.30.1", | ||
"ws": "^8.13.0" | ||
}, | ||
@@ -101,16 +115,3 @@ "files": [ | ||
"!src/package.json" | ||
], | ||
"scripts": { | ||
"clean": "rimraf ./out ./utils/web ./utils/node ./es ./coverage ./dist", | ||
"watch:tsc": "tsc -b -w", | ||
"build:tsc": "tsc -b", | ||
"watch:rollup": "rollup -c -w", | ||
"build:rollup": "rollup -c", | ||
"build": "pnpm run build:tsc && pnpm run build:rollup", | ||
"doc:api": "api-extractor run --local --verbose && api-extractor run --local -c ./api-extractor-base.json", | ||
"doc:md": "api-documenter markdown -o docs -i dist/api-extractor", | ||
"doc": "run-s doc:api doc:md", | ||
"start": "run-p watch:rollup watch:tsc watch:test", | ||
"test": "vitest --coverage --ui" | ||
} | ||
} | ||
] | ||
} |
@@ -7,9 +7,7 @@ export * from './types.js' | ||
import { NoSerialization } from './utils/serialization.js' | ||
import { | ||
Request, | ||
Response, | ||
type Response, | ||
ErrorResponseMapped, | ||
SuccessResponse, | ||
hasKey, | ||
isJSONRPCObject, | ||
@@ -81,3 +79,3 @@ isObject, | ||
const { | ||
serializer = NoSerialization, | ||
serializer, | ||
key: logKey = 'rpc', | ||
@@ -112,4 +110,4 @@ strict = true, | ||
} = (logger || console) as ConsoleInterface | ||
type PromiseParam = [resolve: (value?: any) => void, reject: (reason?: any) => void] | ||
const requestContext = new Map<string | number, { f: PromiseParam; stack: string }>() | ||
type PromiseParam = [resolve: (value?: any) => void, reject: (reason?: any) => void, stack?: string] | ||
const requestContext = new Map<string | number, PromiseParam>() | ||
const onRequest = async (data: Request): Promise<Response | undefined> => { | ||
@@ -164,3 +162,3 @@ if (isThisSideImplementationPending) await awaitThisSideImplementation() | ||
if (result === AsyncCallIgnoreResponse) return | ||
return SuccessResponse(req_id, await promise) | ||
return SuccessResponse(req_id, result) | ||
} catch (e) { | ||
@@ -175,4 +173,4 @@ return makeErrorObject(e, frameworkStack, data) | ||
errorType = ERROR | ||
if (hasKey(data, 'error')) { | ||
const e = data.error as any | ||
if ('error' in data) { | ||
const e = data.error | ||
errorMessage = e.message | ||
@@ -182,6 +180,6 @@ errorCode = e.code | ||
if (isObject(detail) && hasKey(detail, 'stack') && isString(detail.stack)) remoteErrorStack = detail.stack | ||
if (isObject(detail) && 'stack' in detail && isString(detail.stack)) remoteErrorStack = detail.stack | ||
else remoteErrorStack = '<remote stack not available>' | ||
if (isObject(detail) && hasKey(detail, 'type') && isString(detail.type)) errorType = detail.type | ||
if (isObject(detail) && 'type' in detail && isString(detail.type)) errorType = detail.type | ||
else errorType = ERROR | ||
@@ -198,7 +196,7 @@ | ||
} | ||
if (data.id === null || data.id === undefined) return | ||
const { f: [resolve, reject] = [null, null], stack: localErrorStack = '' } = requestContext.get(data.id) || {} | ||
if (!resolve || !reject) return // drop this response | ||
requestContext.delete(data.id) | ||
if (hasKey(data, 'error')) { | ||
const { id } = data | ||
if (id === null || id === undefined || !requestContext.has(id)) return | ||
const [resolve, reject, localErrorStack = ''] = requestContext.get(id)! | ||
requestContext.delete(id) | ||
if ('error' in data) { | ||
reject( | ||
@@ -246,3 +244,3 @@ RecoverError( | ||
if (isArray(res)) { | ||
const reply = res.filter((x) => x && hasKey(x, 'id')) | ||
const reply = res.filter((x) => x && 'id' in x) | ||
if (reply.length === 0) return | ||
@@ -254,7 +252,6 @@ return serialization(reply) | ||
} | ||
const serialization = (x: unknown) => serializer.serialization(x) | ||
const deserialization = (x: unknown) => serializer.deserialization(x) | ||
const isEventBasedChannel = (x: typeof channel): x is EventBasedChannel => hasKey(x, 'send') && isFunction(x.send) | ||
const isCallbackBasedChannel = (x: typeof channel): x is CallbackBasedChannel => | ||
hasKey(x, 'setup') && isFunction(x.setup) | ||
const serialization = serializer ? (x: unknown) => serializer.serialization(x) : Object | ||
const deserialization = serializer ? (x: unknown) => serializer.deserialization(x) : Object | ||
const isEventBasedChannel = (x: typeof channel): x is EventBasedChannel => 'send' in x && isFunction(x.send) | ||
const isCallbackBasedChannel = (x: typeof channel): x is CallbackBasedChannel => 'setup' in x && isFunction(x.setup) | ||
@@ -280,4 +277,4 @@ if (isCallbackBasedChannel(channel)) { | ||
} | ||
function makeErrorObject(e: any, frameworkStack: string, data: Request) { | ||
if (isObject(e) && hasKey(e, 'stack')) | ||
const makeErrorObject = (e: any, frameworkStack: string, data: Request) => { | ||
if (isObject(e) && 'stack' in e) | ||
e.stack = frameworkStack | ||
@@ -290,3 +287,3 @@ .split('\n') | ||
async function sendPayload(payload: unknown, removeQueueR = false) { | ||
const sendPayload = async (payload: unknown, removeQueueR = false) => { | ||
if (removeQueueR) payload = [...(payload as BatchQueue)] | ||
@@ -296,7 +293,7 @@ const data = await serialization(payload) | ||
} | ||
function rejectsQueue(queue: BatchQueue, error: unknown) { | ||
const rejectsQueue = (queue: BatchQueue, error: unknown) => { | ||
for (const x of queue) { | ||
if (hasKey(x, 'id')) { | ||
if ('id' in x) { | ||
const ctx = requestContext.get(x.id!) | ||
ctx && ctx.f[1](error) | ||
ctx && ctx[1](error) | ||
} | ||
@@ -308,5 +305,5 @@ } | ||
): Promise<SuccessResponse | ErrorResponse | undefined> => { | ||
if (hasKey(data, 'method')) { | ||
if ('method' in data) { | ||
const r = onRequest(data) | ||
if (hasKey(data, 'id')) return r | ||
if ('id' in data) return r | ||
try { | ||
@@ -355,6 +352,3 @@ await r | ||
if (notify) return resolve() | ||
requestContext.set(id, { | ||
f: [resolve, reject], | ||
stack, | ||
}) | ||
requestContext.set(id, [resolve, reject, stack]) | ||
}) | ||
@@ -361,0 +355,0 @@ } |
@@ -6,7 +6,7 @@ class CustomError extends Error { | ||
} | ||
export const Err_Cannot_find_a_running_iterator_with_given_ID = {} as Symbol | ||
export const Err_Only_string_can_be_the_RPC_method_name = {} as Symbol | ||
export const Err_Cannot_call_method_starts_with_rpc_dot_directly = {} as Symbol | ||
export const Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options = | ||
{} as Symbol | ||
export const Err_Cannot_find_a_running_iterator_with_given_ID: unique symbol = {} as any | ||
export const Err_Only_string_can_be_the_RPC_method_name: unique symbol = {} as any | ||
export const Err_Cannot_call_method_starts_with_rpc_dot_directly: unique symbol = {} as any | ||
export const Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options: unique symbol = | ||
{} as any | ||
const Messages = [ | ||
@@ -17,5 +17,5 @@ Err_Cannot_find_a_running_iterator_with_given_ID, | ||
Err_Then_is_accessed_on_local_implementation_Please_explicitly_mark_if_it_is_thenable_in_the_options, | ||
] | ||
] as const | ||
// https://github.com/Jack-Works/async-call-rpc/wiki/Error-messages | ||
export function makeHostedMessage(id: Symbol, error: Error) { | ||
export const makeHostedMessage = (id: typeof Messages[number], error: Error) => { | ||
const n = Messages.indexOf(id) | ||
@@ -22,0 +22,0 @@ error.message += `Error ${n}: https://github.com/Jack-Works/async-call-rpc/wiki/Errors#` + n |
@@ -108,6 +108,6 @@ import { globalDOMException as DOMException, DOMExceptionHeader } from './error.js' | ||
if (!isObject(data)) return false | ||
if (!hasKey(data, 'jsonrpc')) return false | ||
if (!('jsonrpc' in data)) return false | ||
if (data.jsonrpc !== jsonrpc) return false | ||
if (hasKey(data, 'params')) { | ||
const params = (data as Request).params | ||
if ('params' in data) { | ||
const params = data.params | ||
if (!isArray(params) && !isObject(params)) return false | ||
@@ -120,12 +120,2 @@ } | ||
export type hasKey = { | ||
(obj: SuccessResponse | ErrorResponse | Request, key: 'result'): obj is SuccessResponse | ||
(obj: SuccessResponse | ErrorResponse | Request, key: 'error'): obj is ErrorResponse | ||
(obj: SuccessResponse | ErrorResponse | Request, key: 'method'): obj is Request | ||
<T, Q extends string>(obj: T, key: Q): obj is T & { | ||
[key in Q]: unknown | ||
} | ||
} | ||
export const hasKey: hasKey = (obj: any, key: any): obj is any => key in obj | ||
const toString = (_default: string, val: () => any) => { | ||
@@ -132,0 +122,0 @@ try { |
//#region Serialization | ||
import { isObject, hasKey } from './jsonrpc.js' | ||
import { isObject } from './jsonrpc.js' | ||
import { undefined } from './constants.js' | ||
@@ -11,2 +11,3 @@ import type { Serialization } from '../types.js' | ||
* @public | ||
* @deprecated Will be removed in next major version | ||
*/ | ||
@@ -47,3 +48,3 @@ export const NoSerialization: Serialization = { | ||
serialization(from) { | ||
if (undefinedKeepingBehavior && isObject(from) && hasKey(from, 'result') && from.result === undefined) { | ||
if (undefinedKeepingBehavior && isObject(from) && 'result' in from && from.result === undefined) { | ||
const alt = { ...from } | ||
@@ -60,5 +61,5 @@ alt.result = null | ||
isObject(result) && | ||
hasKey(result, 'result') && | ||
'result' in result && | ||
result.result === null && | ||
hasKey(result, 'undef') && | ||
'undef' in result && | ||
result.undef === true | ||
@@ -65,0 +66,0 @@ ) { |
@@ -9,3 +9,3 @@ import type { Server } from 'ws' | ||
const f = (ws: WebSocket) => { | ||
ws.on('message', (data) => callback(data).then((x) => x && ws.send(x))) | ||
ws.on('message', (data) => callback(data).then((x) => x && ws.send(x as any))) | ||
} | ||
@@ -12,0 +12,0 @@ this.server.on('connection', f) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
82928
26
1470
1
1