@webpieces/ipc-bridge 0.4.960 → 0.4.962
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/ipc-bridge",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.962",
|
|
4
4
|
"description": "Portable typed duplex IPC client and server factories for browser, React Native and Node",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@webpieces/core-util": "0.4.
|
|
25
|
+
"@webpieces/core-util": "0.4.962"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/src/IpcClientFactory.js
CHANGED
|
@@ -54,10 +54,10 @@ class IpcClientFactory {
|
|
|
54
54
|
// webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation
|
|
55
55
|
request) {
|
|
56
56
|
const context = this.connection.newContext(this.parent);
|
|
57
|
-
return ipc_1.IpcCallLogger.execute(this.logging, context, 'client', apiId, methodId, (0, ipc_1.getIpcMaskSpec)(apiClass, key) ?? new ipc_1.MaskSpec({}), request, async () => {
|
|
57
|
+
return ipc_1.IpcCallLogger.execute(this.logging, context, 'client', apiClass, apiId, methodId, (0, ipc_1.getIpcMaskSpec)(apiClass, key) ?? new ipc_1.MaskSpec({}), request, async () => {
|
|
58
58
|
if (request === null || request === undefined)
|
|
59
59
|
throw new errors_1.ApiImplementationError('IPC requests require one non-null DTO');
|
|
60
|
-
const reply = await this.connection.request(new ipc_1.IpcRequest(apiId, methodId, context, request));
|
|
60
|
+
const reply = await this.connection.request(new ipc_1.IpcRequest(apiId, methodId, context, request), apiClass);
|
|
61
61
|
// EVERY reply passes the seam, success included, so an app can turn an
|
|
62
62
|
// apparently-successful reply into a throw. `asserts reply is IpcSuccess`
|
|
63
63
|
// is what leaves no `type === 'failure'` branch behind here.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IpcClientFactory.js","sourceRoot":"","sources":["../../../../../packages/core/ipc-bridge/src/IpcClientFactory.ts"],"names":[],"mappings":";;;AAAA,wDAAkF;AAClF,kDAakC;AAElC,gGAAgG;AAChG,MAAa,gBAAgB;IASJ;IACA;IACA;IACA;IAXrB;;;;;;OAMG;IACH,YACqB,UAAyB,EACzB,OAAmB,EACnB,IAAgB,EAChB,MAAuB;QAHvB,eAAU,GAAV,UAAU,CAAe;QACzB,YAAO,GAAP,OAAO,CAAY;QACnB,SAAI,GAAJ,IAAI,CAAY;QAChB,WAAM,GAAN,MAAM,CAAiB;IACzC,CAAC;IAEJ,0FAA0F;IAC1F,WAAW,CAAC,OAAuB;QAC/B,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnF,CAAC;IAED,YAAY,CAAmB,QAAuB;QAClD,MAAM,KAAK,GAAG,IAAA,uBAAiB,EAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAA,qBAAe,EAAC,QAAQ,CAAC,CAAC;QAC5C,0IAA0I;QAC1I,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuD,CAAC;QAC/E,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACtD,yFAAyF;YACzF,mEAAmE;YACnE,0IAA0I;YAC1I,MAAM,YAAY,GAAG,CAAC,OAAgB,EAAoB,EAAE;gBACxD,MAAM,QAAQ,GAAG,oBAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;gBACjE,6EAA6E;gBAC7E,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,OAAgB,EAAE,EAAE;oBACjF,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBAC3B,6GAA6G;oBAC7G,MAAM,OAAO,CAAC;gBAClB,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAM,EAAE,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,oFAAoF;IAC5E,KAAK,CAAC,IAAI,CACd,QAAuB,EACvB,KAAa,EACb,QAAgB,EAChB,GAAW;IACX,0IAA0I;IAC1I,OAAgB;QAGhB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxD,OAAO,mBAAa,CAAC,OAAO,CACxB,IAAI,CAAC,OAAO,EACZ,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAA,oBAAc,EAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,cAAQ,CAAC,EAAE,CAAC,EACjD,OAAO,EACP,KAAK,IAAI,EAAE;YACP,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS;gBACzC,MAAM,IAAI,+BAAsB,CAC5B,uCAAuC,CAC1C,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CACvC,IAAI,gBAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"IpcClientFactory.js","sourceRoot":"","sources":["../../../../../packages/core/ipc-bridge/src/IpcClientFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiCallSite, ApiImplementationError } from '@webpieces/core-util/errors';\nimport {\n ClientRole,\n IpcCallContext,\n IpcClientErrorTranslator,\n IpcConnection,\n IpcApiType,\n IpcLogging,\n IpcRequest,\n IpcCallLogger,\n assertInternalApi,\n getIpcEndpoints,\n getIpcMaskSpec,\n MaskSpec,\n} from '@webpieces/core-util/ipc';\n\n/** Typed proxies on one trusted duplex connection; no HTTP decorators or container required. */\nexport class IpcClientFactory {\n /**\n * @param role - WHO receives this factory's replies (see {@link ClientRole}). REQUIRED, with no\n * default (#1173): it decides what an `unauthorized` reply means. An end-user client (the\n * WebView or app shell acting for the person) decodes it as `ApiUnauthorizedError` (\"log in\n * again\"); a server decodes it as `ApiImplementationError`, because the credential it presented\n * was its own.\n */\n constructor(\n private readonly connection: IpcConnection,\n private readonly logging: IpcLogging,\n private readonly role: ClientRole,\n private readonly parent?: IpcCallContext,\n ) {}\n\n /** Explicit scope propagation is safe across concurrent async calls in browser and RN. */\n withContext(context: IpcCallContext): IpcClientFactory {\n return new IpcClientFactory(this.connection, this.logging, this.role, context);\n }\n\n createClient<T extends object>(apiClass: IpcApiType<T>): T {\n const apiId = assertInternalApi(apiClass);\n const endpoints = getIpcEndpoints(apiClass);\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n const methods = new Map<PropertyKey, (request: unknown) => Promise<unknown>>();\n const apiName = apiClass.name || apiId;\n for (const [key, methodId] of Object.entries(endpoints)) {\n // Same call-site capture as the HTTP clients (#1175): synchronous on the CALLER's stack,\n // trimmed at `clientMethod`, parked on the SAME rejected instance.\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n const clientMethod = (request: unknown): Promise<unknown> => {\n const callSite = ApiCallSite.capture(apiName, key, clientMethod);\n // webpieces-disable no-any-unknown -- a rejection value is genuinely unknown\n return this.call(apiClass, apiId, methodId, key, request).catch((failure: unknown) => {\n callSite.attachTo(failure);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- rethrows the caller's own failure unchanged\n throw failure;\n });\n };\n methods.set(key, clientMethod);\n }\n return new Proxy(Object.create(null) as T, new IpcProxyHandler(methods));\n }\n\n /** One IPC request/reply, logged; the body of every generated IPC client method. */\n private async call<T extends object>(\n apiClass: IpcApiType<T>,\n apiId: string,\n methodId: string,\n key: string,\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n request: unknown,\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n ): Promise<unknown> {\n const context = this.connection.newContext(this.parent);\n return IpcCallLogger.execute(\n this.logging,\n context,\n 'client',\n apiClass,\n apiId,\n methodId,\n getIpcMaskSpec(apiClass, key) ?? new MaskSpec({}),\n request,\n async () => {\n if (request === null || request === undefined)\n throw new ApiImplementationError(\n 'IPC requests require one non-null DTO',\n );\n const reply = await this.connection.request(\n new IpcRequest(apiId, methodId, context, request),\n apiClass,\n );\n // EVERY reply passes the seam, success included, so an app can turn an\n // apparently-successful reply into a throw. `asserts reply is IpcSuccess`\n // is what leaves no `type === 'failure'` branch behind here.\n IpcClientErrorTranslator.throwIfFailure(reply, this.role);\n return reply.body === null ? undefined : reply.body;\n },\n );\n }\n}\n\nclass IpcProxyHandler<T extends object> implements ProxyHandler<T> {\n constructor(\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n private readonly methods: ReadonlyMap<PropertyKey, (request: unknown) => Promise<unknown>>,\n ) {}\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n get(_target: T, key: string | symbol): unknown {\n // Promise assimilation, inspection, symbols and framework instrumentation aren't RPC methods.\n return this.methods.get(key);\n }\n has(_target: T, key: string | symbol): boolean {\n return this.methods.has(key);\n }\n}\n"]}
|
package/src/IpcServerFactory.js
CHANGED
|
@@ -31,7 +31,7 @@ class IpcServerFactory {
|
|
|
31
31
|
for (const [key, methodId] of Object.entries((0, ipc_1.getIpcEndpoints)(apiClass))) {
|
|
32
32
|
methods.set(methodId, new IpcRegistration(async (request) => {
|
|
33
33
|
// Logging wraps validation and invocation; only handle() below encodes exceptions.
|
|
34
|
-
return ipc_1.IpcCallLogger.execute(this.logging, request.context, 'server', apiId, methodId, (0, ipc_1.getIpcMaskSpec)(apiClass, key) ?? new ipc_1.MaskSpec({}), request.body, async () => {
|
|
34
|
+
return ipc_1.IpcCallLogger.execute(this.logging, request.context, 'server', apiClass, apiId, methodId, (0, ipc_1.getIpcMaskSpec)(apiClass, key) ?? new ipc_1.MaskSpec({}), request.body, async () => {
|
|
35
35
|
if (request.body === null || request.body === undefined)
|
|
36
36
|
throw new errors_1.ApiImplementationError('IPC requests require one non-null DTO');
|
|
37
37
|
const instance = controller(request.context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IpcServerFactory.js","sourceRoot":"","sources":["../../../../../packages/core/ipc-bridge/src/IpcServerFactory.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"IpcServerFactory.js","sourceRoot":"","sources":["../../../../../packages/core/ipc-bridge/src/IpcServerFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiEndpointNotFoundError, ApiImplementationError } from '@webpieces/core-util/errors';\nimport {\n IpcCallContext,\n IpcApiType,\n IpcRegistry,\n IpcFailure,\n IpcLogging,\n IpcReply,\n IpcRequest,\n IpcSuccess,\n IpcCallLogger,\n toError,\n assertInternalApi,\n getIpcEndpoints,\n getIpcMaskSpec,\n MaskSpec,\n} from '@webpieces/core-util/ipc';\n\n/** Construct a receiver using explicit call context when it needs to make nested outbound calls. */\nexport interface IpcControllerScope<T> {\n create(context: IpcCallContext): T;\n}\nclass IpcRegistration {\n // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n constructor(readonly invoke: (request: IpcRequest) => Promise<unknown>) {}\n}\n\n/** One dispatcher hosts multiple explicitly registered APIs and never enumerates controller members. */\nexport class IpcServerFactory {\n private readonly registrations = new Map<string, Map<string, IpcRegistration>>();\n constructor(private readonly logging: IpcLogging) {}\n\n create<T extends object>(apiClass: IpcApiType<T>, controller: T): void {\n this.register(apiClass, () => controller);\n }\n\n createScoped<T extends object>(apiClass: IpcApiType<T>, scope: IpcControllerScope<T>): void {\n this.register(apiClass, (context: IpcCallContext) => scope.create(context));\n }\n\n private register<T extends object>(\n apiClass: IpcApiType<T>,\n controller: (context: IpcCallContext) => T,\n ): void {\n const apiId = assertInternalApi(apiClass);\n if (this.registrations.has(apiId))\n throw new ApiImplementationError(`Duplicate IPC API registration: ${apiId}`);\n const methods = new Map<string, IpcRegistration>();\n for (const [key, methodId] of Object.entries(getIpcEndpoints(apiClass))) {\n methods.set(\n methodId,\n new IpcRegistration(async (request) => {\n // Logging wraps validation and invocation; only handle() below encodes exceptions.\n return IpcCallLogger.execute(\n this.logging,\n request.context,\n 'server',\n apiClass,\n apiId,\n methodId,\n getIpcMaskSpec(apiClass, key) ?? new MaskSpec({}),\n request.body,\n async () => {\n if (request.body === null || request.body === undefined)\n throw new ApiImplementationError(\n 'IPC requests require one non-null DTO',\n );\n const instance = controller(request.context);\n const invoke = instance[key as keyof T];\n if (typeof invoke !== 'function')\n throw new ApiImplementationError(\n `IPC implementation is missing ${apiId}.${methodId}`,\n );\n const result =\n await // webpieces-disable no-any-unknown -- untrusted IPC data is schema-validated; generic dispatch cannot assume a DTO type before validation\n (invoke as (request: unknown) => Promise<unknown>).call(\n instance,\n request.body,\n );\n return result;\n },\n );\n }),\n );\n }\n this.registrations.set(apiId, methods);\n }\n\n /** Bootstrap passes this function to the ONE connection's setHandler before sending calls. */\n readonly handle = async (request: IpcRequest): Promise<IpcReply> => {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- receiver translates to a failure reply; the generated client reconstructs and throws it\n try {\n const method = this.registrations.get(request.apiId)?.get(request.methodId);\n if (!method) throw new ApiEndpointNotFoundError('Unknown IPC API or method');\n const body = await method.invoke(request);\n return new IpcSuccess(request.context, body === undefined ? null : body);\n } catch (err: unknown) {\n const error = toError(err);\n // This receiver OWNS the reply, so it publishes through the app-reachable IPC seam. The\n // webpieces default there is the shared `ApiErrorBoundary` rule, not the raw codec.\n return new IpcFailure(request.context, IpcRegistry.getErrorTranslator().toWire(error));\n }\n };\n}\n"]}
|