diff --git a/.smartconfig.json b/.smartconfig.json new file mode 100644 index 0000000..6dd6c19 --- /dev/null +++ b/.smartconfig.json @@ -0,0 +1,11 @@ +{ + "@git.zone/cli": { + "release": { + "registries": [ + "https://verdaccio.lossless.digital", + "https://registry.npmjs.org" + ], + "accessLevel": "public" + } + } +} \ No newline at end of file diff --git a/changelog.md b/changelog.md index 6aa347d..b4873e3 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-05-08 - 4.1.3 - fix(typedsocket) +initialize correlation ids for requests without pre-existing correlation metadata + +- Generate a correlation id and request phase before tracking pending requests to avoid failures for stream control messages such as ##VirtualStream##. +- Add test coverage for processing virtual stream control messages when no correlation data is present. +- Add release registry configuration for package publishing. + ## 2026-02-26 - 4.1.2 - fix(ci) update npmextra.json to rename keys, add release registries and add CI entry; remove legacy npmci configuration diff --git a/test/test.ts b/test/test.ts index 5c47ba5..01515ef 100644 --- a/test/test.ts +++ b/test/test.ts @@ -89,6 +89,20 @@ tap.test('should process messages from client to server', async () => { expect(response.answer).toContain('ok, got it'); }); +tap.test('should process stream control messages without pre-existing correlation', async () => { + const response = await (testTypedSocketClient as any).sendRequest({ + method: '##VirtualStream##', + request: { + streamId: 'unknown-stream', + cycleId: 'unknown-cycle', + cycle: 'request', + mainPurpose: 'feedback', + }, + response: null, + }); + expect(response.correlation.id).toBeTruthy(); +}); + tap.test('should find connections by tag', async () => { console.log('Finding connections by tag...'); const connections = await testTypedSocketServer.findAllTargetConnectionsByTag('testTag'); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 65c3341..032e534 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@api.global/typedsocket', - version: '4.1.2', + version: '4.1.3', description: 'A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.' } diff --git a/ts/typedsocket.classes.typedsocket.ts b/ts/typedsocket.classes.typedsocket.ts index 11ca995..e4fdc97 100644 --- a/ts/typedsocket.classes.typedsocket.ts +++ b/ts/typedsocket.classes.typedsocket.ts @@ -383,13 +383,19 @@ export class TypedSocket { throw new Error('WebSocket not connected'); } + request.correlation ||= { + id: plugins.smartstring.create.createCryptoRandomString(), + phase: 'request', + }; + const correlationId = request.correlation.id; + return new Promise((resolve, reject) => { const timeout = setTimeout(() => { - this.pendingRequests.delete(request.correlation.id); + this.pendingRequests.delete(correlationId); reject(new Error('Request timeout')); }, 30000); - this.pendingRequests.set(request.correlation.id, { + this.pendingRequests.set(correlationId, { resolve: (response) => { clearTimeout(timeout); resolve(response);