@platformatic/itc 3.0.0-alpha.4 → 3.0.0-alpha.6
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/eslint.config.js +2 -2
- package/lib/errors.js +30 -22
- package/lib/{itc.js → index.js} +40 -37
- package/package.json +7 -4
- package/index.js +0 -3
- package/index.test-d.ts +0 -33
- /package/{index.d.ts → lib/index.d.ts} +0 -0
package/eslint.config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import neostandard from 'neostandard'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export default neostandard({ ts: true })
|
package/lib/errors.js
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
import createError from '@fastify/error'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
export const ERROR_PREFIX = 'PLT_ITC'
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
5
|
+
export const HandlerFailed = createError(`${ERROR_PREFIX}_HANDLER_FAILED`, 'Handler failed with error: %s')
|
|
6
|
+
export const HandlerNotFound = createError(`${ERROR_PREFIX}_HANDLER_NOT_FOUND`, 'Handler not found for request: "%s"')
|
|
7
|
+
export const PortAlreadyListening = createError(`${ERROR_PREFIX}_ALREADY_LISTENING`, 'ITC is already listening')
|
|
8
|
+
export const SendBeforeListen = createError(
|
|
9
|
+
`${ERROR_PREFIX}_SEND_BEFORE_LISTEN`,
|
|
10
|
+
'ITC cannot send requests before listening'
|
|
11
|
+
)
|
|
12
|
+
export const InvalidRequestVersion = createError(
|
|
13
|
+
`${ERROR_PREFIX}_INVALID_REQUEST_VERSION`,
|
|
14
|
+
'Invalid ITC request version: "%s"'
|
|
15
|
+
)
|
|
16
|
+
export const InvalidResponseVersion = createError(
|
|
17
|
+
`${ERROR_PREFIX}_INVALID_RESPONSE_VERSION`,
|
|
18
|
+
'Invalid ITC response version: "%s"'
|
|
19
|
+
)
|
|
20
|
+
export const MissingRequestName = createError(`${ERROR_PREFIX}_MISSING_REQUEST_NAME`, 'ITC request name is missing')
|
|
21
|
+
export const MissingResponseName = createError(`${ERROR_PREFIX}_MISSING_RESPONSE_NAME`, 'ITC response name is missing')
|
|
22
|
+
export const MissingRequestReqId = createError(`${ERROR_PREFIX}_MISSING_REQUEST_REQ_ID`, 'ITC request reqId is missing')
|
|
23
|
+
export const MissingResponseReqId = createError(
|
|
24
|
+
`${ERROR_PREFIX}_MISSING_RESPONSE_REQ_ID`,
|
|
25
|
+
'ITC response reqId is missing'
|
|
26
|
+
)
|
|
27
|
+
export const RequestNameIsNotString = createError(
|
|
28
|
+
`${ERROR_PREFIX}_REQUEST_NAME_IS_NOT_STRING`,
|
|
29
|
+
'ITC request name is not a string: "%s"'
|
|
30
|
+
)
|
|
31
|
+
export const MessagePortClosed = createError(`${ERROR_PREFIX}_MESSAGE_PORT_CLOSED`, 'ITC MessagePort is closed')
|
|
32
|
+
export const MissingName = createError(`${ERROR_PREFIX}_MISSING_NAME`, 'ITC name is missing')
|
package/lib/{itc.js → index.js}
RENAMED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { Unpromise } from '@watchable/unpromise'
|
|
2
|
+
import { randomUUID } from 'node:crypto'
|
|
3
|
+
import { EventEmitter, once } from 'node:events'
|
|
4
|
+
import {
|
|
5
|
+
HandlerFailed,
|
|
6
|
+
HandlerNotFound,
|
|
7
|
+
InvalidRequestVersion,
|
|
8
|
+
InvalidResponseVersion,
|
|
9
|
+
MessagePortClosed,
|
|
10
|
+
MissingName,
|
|
11
|
+
MissingRequestName,
|
|
12
|
+
MissingRequestReqId,
|
|
13
|
+
MissingResponseName,
|
|
14
|
+
MissingResponseReqId,
|
|
15
|
+
PortAlreadyListening,
|
|
16
|
+
RequestNameIsNotString,
|
|
17
|
+
SendBeforeListen
|
|
18
|
+
} from './errors.js'
|
|
7
19
|
|
|
8
20
|
const PLT_ITC_REQUEST_TYPE = 'PLT_ITC_REQUEST'
|
|
9
21
|
const PLT_ITC_RESPONSE_TYPE = 'PLT_ITC_RESPONSE'
|
|
@@ -11,35 +23,35 @@ const PLT_ITC_NOTIFICATION_TYPE = 'PLT_ITC_NOTIFICATION'
|
|
|
11
23
|
const PLT_ITC_UNHANDLED_ERROR_TYPE = 'PLT_ITC_UNHANDLED_ERROR'
|
|
12
24
|
const PLT_ITC_VERSION = '1.0.0'
|
|
13
25
|
|
|
14
|
-
function parseRequest (request) {
|
|
26
|
+
export function parseRequest (request) {
|
|
15
27
|
if (request.reqId === undefined) {
|
|
16
|
-
throw new
|
|
28
|
+
throw new MissingRequestReqId()
|
|
17
29
|
}
|
|
18
30
|
if (request.version !== PLT_ITC_VERSION) {
|
|
19
|
-
throw new
|
|
31
|
+
throw new InvalidRequestVersion(request.version)
|
|
20
32
|
}
|
|
21
33
|
if (request.name === undefined) {
|
|
22
|
-
throw new
|
|
34
|
+
throw new MissingRequestName()
|
|
23
35
|
}
|
|
24
36
|
return request
|
|
25
37
|
}
|
|
26
38
|
|
|
27
|
-
function parseResponse (response) {
|
|
39
|
+
export function parseResponse (response) {
|
|
28
40
|
if (response.reqId === undefined) {
|
|
29
|
-
throw new
|
|
41
|
+
throw new MissingResponseReqId()
|
|
30
42
|
}
|
|
31
43
|
if (response.version !== PLT_ITC_VERSION) {
|
|
32
|
-
throw new
|
|
44
|
+
throw new InvalidResponseVersion(response.version)
|
|
33
45
|
}
|
|
34
46
|
if (response.name === undefined) {
|
|
35
|
-
throw new
|
|
47
|
+
throw new MissingResponseName()
|
|
36
48
|
}
|
|
37
49
|
return response
|
|
38
50
|
}
|
|
39
51
|
|
|
40
|
-
function generateRequest (name, data) {
|
|
52
|
+
export function generateRequest (name, data) {
|
|
41
53
|
if (typeof name !== 'string') {
|
|
42
|
-
throw new
|
|
54
|
+
throw new RequestNameIsNotString(name.toString())
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
return {
|
|
@@ -51,7 +63,7 @@ function generateRequest (name, data) {
|
|
|
51
63
|
}
|
|
52
64
|
}
|
|
53
65
|
|
|
54
|
-
function generateResponse (request, error, data) {
|
|
66
|
+
export function generateResponse (request, error, data) {
|
|
55
67
|
return {
|
|
56
68
|
type: PLT_ITC_RESPONSE_TYPE,
|
|
57
69
|
version: PLT_ITC_VERSION,
|
|
@@ -62,7 +74,7 @@ function generateResponse (request, error, data) {
|
|
|
62
74
|
}
|
|
63
75
|
}
|
|
64
76
|
|
|
65
|
-
function generateNotification (name, data) {
|
|
77
|
+
export function generateNotification (name, data) {
|
|
66
78
|
return {
|
|
67
79
|
type: PLT_ITC_NOTIFICATION_TYPE,
|
|
68
80
|
version: PLT_ITC_VERSION,
|
|
@@ -71,7 +83,7 @@ function generateNotification (name, data) {
|
|
|
71
83
|
}
|
|
72
84
|
}
|
|
73
85
|
|
|
74
|
-
function generateUnhandledErrorResponse (error) {
|
|
86
|
+
export function generateUnhandledErrorResponse (error) {
|
|
75
87
|
return {
|
|
76
88
|
type: PLT_ITC_UNHANDLED_ERROR_TYPE,
|
|
77
89
|
version: PLT_ITC_VERSION,
|
|
@@ -80,7 +92,7 @@ function generateUnhandledErrorResponse (error) {
|
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
94
|
|
|
83
|
-
function sanitize (data, transferList) {
|
|
95
|
+
export function sanitize (data, transferList) {
|
|
84
96
|
if (!data || typeof data !== 'object' || transferList?.includes(data) || data instanceof Error) {
|
|
85
97
|
return data
|
|
86
98
|
}
|
|
@@ -120,7 +132,7 @@ function sanitize (data, transferList) {
|
|
|
120
132
|
return sanitized
|
|
121
133
|
}
|
|
122
134
|
|
|
123
|
-
class ITC extends EventEmitter {
|
|
135
|
+
export class ITC extends EventEmitter {
|
|
124
136
|
#requestEmitter
|
|
125
137
|
#handlers
|
|
126
138
|
#listening
|
|
@@ -135,7 +147,7 @@ class ITC extends EventEmitter {
|
|
|
135
147
|
super()
|
|
136
148
|
|
|
137
149
|
if (!name) {
|
|
138
|
-
throw new
|
|
150
|
+
throw new MissingName()
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
// The name property is useful only for debugging purposes.
|
|
@@ -182,7 +194,7 @@ class ITC extends EventEmitter {
|
|
|
182
194
|
|
|
183
195
|
async send (name, message, options) {
|
|
184
196
|
if (!this.#listening) {
|
|
185
|
-
throw new
|
|
197
|
+
throw new SendBeforeListen()
|
|
186
198
|
}
|
|
187
199
|
|
|
188
200
|
try {
|
|
@@ -212,7 +224,7 @@ class ITC extends EventEmitter {
|
|
|
212
224
|
|
|
213
225
|
listen () {
|
|
214
226
|
if (this.#listening) {
|
|
215
|
-
throw new
|
|
227
|
+
throw new PortAlreadyListening()
|
|
216
228
|
}
|
|
217
229
|
this.#listening = true
|
|
218
230
|
|
|
@@ -238,7 +250,7 @@ class ITC extends EventEmitter {
|
|
|
238
250
|
|
|
239
251
|
this.#closePromise = this._createClosePromise().then(() => {
|
|
240
252
|
this.#listening = false
|
|
241
|
-
const error = new
|
|
253
|
+
const error = new MessagePortClosed()
|
|
242
254
|
clearInterval(this.#keepAlive)
|
|
243
255
|
this.#keepAliveCount = -1000
|
|
244
256
|
return { error, data: null }
|
|
@@ -288,7 +300,7 @@ class ITC extends EventEmitter {
|
|
|
288
300
|
response = generateResponse(request, null, result)
|
|
289
301
|
} else {
|
|
290
302
|
if (this.#throwOnMissingHandler) {
|
|
291
|
-
throw new
|
|
303
|
+
throw new HandlerNotFound(request.name)
|
|
292
304
|
}
|
|
293
305
|
|
|
294
306
|
response = generateResponse(request, null)
|
|
@@ -299,7 +311,7 @@ class ITC extends EventEmitter {
|
|
|
299
311
|
} else if (!handler) {
|
|
300
312
|
response = generateResponse(request, error, null)
|
|
301
313
|
} else {
|
|
302
|
-
const failedError = new
|
|
314
|
+
const failedError = new HandlerFailed(error.message)
|
|
303
315
|
failedError.handlerError = error
|
|
304
316
|
// This is needed as the code might be lost when sending the message over the port
|
|
305
317
|
failedError.handlerErrorCode = error.code
|
|
@@ -351,13 +363,4 @@ class ITC extends EventEmitter {
|
|
|
351
363
|
}
|
|
352
364
|
}
|
|
353
365
|
|
|
354
|
-
|
|
355
|
-
ITC,
|
|
356
|
-
parseRequest,
|
|
357
|
-
parseResponse,
|
|
358
|
-
generateRequest,
|
|
359
|
-
generateResponse,
|
|
360
|
-
generateNotification,
|
|
361
|
-
generateUnhandledErrorResponse,
|
|
362
|
-
sanitize
|
|
363
|
-
}
|
|
366
|
+
export * as errors from './errors.js'
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/itc",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.6",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
6
8
|
"author": "Platformatic Inc. <oss@platformatic.dev> (https://platformatic.dev)",
|
|
7
9
|
"repository": {
|
|
8
10
|
"type": "git",
|
|
@@ -15,7 +17,7 @@
|
|
|
15
17
|
"homepage": "https://github.com/platformatic/platformatic#readme",
|
|
16
18
|
"devDependencies": {
|
|
17
19
|
"@types/node": "^22.5.0",
|
|
18
|
-
"
|
|
20
|
+
"cleaner-spec-reporter": "^0.5.0",
|
|
19
21
|
"eslint": "9",
|
|
20
22
|
"neostandard": "^0.12.0",
|
|
21
23
|
"tsd": "^0.32.0",
|
|
@@ -29,7 +31,8 @@
|
|
|
29
31
|
"node": ">=22.18.0"
|
|
30
32
|
},
|
|
31
33
|
"scripts": {
|
|
32
|
-
"test": "
|
|
34
|
+
"test": "node --test --test-reporter=cleaner-spec-reporter --test-concurrency=1 --test-timeout=2000000 test/*.test.js",
|
|
35
|
+
"posttest": "tsd -t index.test-d.ts test",
|
|
33
36
|
"lint": "eslint"
|
|
34
37
|
}
|
|
35
38
|
}
|
package/index.js
DELETED
package/index.test-d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { MessagePort } from 'node:worker_threads'
|
|
2
|
-
import { expectError, expectType } from 'tsd'
|
|
3
|
-
import { ITC, ITCConstructorOptions } from './index'
|
|
4
|
-
|
|
5
|
-
const mockPort = {} as MessagePort
|
|
6
|
-
|
|
7
|
-
const options: ITCConstructorOptions = { port: mockPort }
|
|
8
|
-
expectType<ITCConstructorOptions>(options)
|
|
9
|
-
|
|
10
|
-
const itc = new ITC({ port: mockPort })
|
|
11
|
-
expectType<ITC>(itc)
|
|
12
|
-
|
|
13
|
-
expectType<Promise<any>>(itc.send('testMessage', { key: 'value' }))
|
|
14
|
-
expectType<void>(itc.notify('testMessage', { key: 'value' }))
|
|
15
|
-
expectType<void>(
|
|
16
|
-
itc.handle('testMessage', async data => {
|
|
17
|
-
return { key: 'value' }
|
|
18
|
-
})
|
|
19
|
-
)
|
|
20
|
-
expectType<void>(itc.listen())
|
|
21
|
-
expectType<void>(itc.close())
|
|
22
|
-
|
|
23
|
-
expectError(itc.send(123, { key: 'value' })) // send name must be a string
|
|
24
|
-
expectError(itc.notify(123, { key: 'value' })) // send name must be a string
|
|
25
|
-
expectError(
|
|
26
|
-
itc.handle(123, async data => {
|
|
27
|
-
return { key: 'value' }
|
|
28
|
-
})
|
|
29
|
-
) // handle message must be a string
|
|
30
|
-
|
|
31
|
-
itc.on('unhandledError', (error: Error) => {
|
|
32
|
-
expectType<Error>(error)
|
|
33
|
-
})
|
|
File without changes
|