@platformatic/itc 3.13.1 → 3.15.0
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/lib/index.js +75 -22
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -97,43 +97,89 @@ export function sanitize (data, transferList) {
|
|
|
97
97
|
return data
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
let sanitized
|
|
101
|
-
|
|
102
100
|
if (Buffer.isBuffer(data) || data instanceof Uint8Array) {
|
|
103
101
|
// This will convert as Uint8Array
|
|
104
102
|
return data
|
|
105
|
-
}
|
|
106
|
-
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (Array.isArray(data)) {
|
|
106
|
+
let sanitized = null
|
|
107
|
+
let needsSanitization = false
|
|
107
108
|
|
|
108
|
-
for (
|
|
109
|
+
for (let i = 0; i < data.length; i++) {
|
|
110
|
+
const value = data[i]
|
|
109
111
|
const valueType = typeof value
|
|
110
112
|
|
|
111
113
|
/* c8 ignore next 3 */
|
|
112
114
|
if (valueType === 'function' || valueType === 'symbol') {
|
|
115
|
+
if (!needsSanitization) {
|
|
116
|
+
sanitized = data.slice(0, i)
|
|
117
|
+
needsSanitization = true
|
|
118
|
+
}
|
|
113
119
|
continue
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
|
|
122
|
+
let sanitizedValue = value
|
|
123
|
+
if (value && typeof value === 'object') {
|
|
124
|
+
sanitizedValue = sanitize(value, transferList)
|
|
125
|
+
if (sanitizedValue !== value && !needsSanitization) {
|
|
126
|
+
sanitized = data.slice(0, i)
|
|
127
|
+
needsSanitization = true
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (needsSanitization) {
|
|
132
|
+
sanitized.push(sanitizedValue)
|
|
133
|
+
}
|
|
117
134
|
}
|
|
118
|
-
} else {
|
|
119
|
-
sanitized = {}
|
|
120
135
|
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
return needsSanitization ? sanitized : data
|
|
137
|
+
}
|
|
123
138
|
|
|
124
|
-
|
|
125
|
-
|
|
139
|
+
// Handle plain objects
|
|
140
|
+
let sanitized = null
|
|
141
|
+
let needsSanitization = false
|
|
142
|
+
|
|
143
|
+
for (const [key, value] of Object.entries(data)) {
|
|
144
|
+
const valueType = typeof value
|
|
145
|
+
|
|
146
|
+
if (valueType === 'function' || valueType === 'symbol') {
|
|
147
|
+
if (!needsSanitization) {
|
|
148
|
+
sanitized = {}
|
|
149
|
+
// Copy all previous properties
|
|
150
|
+
for (const [k] of Object.entries(data)) {
|
|
151
|
+
if (k === key) break
|
|
152
|
+
sanitized[k] = data[k]
|
|
153
|
+
}
|
|
154
|
+
needsSanitization = true
|
|
155
|
+
}
|
|
156
|
+
continue
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let sanitizedValue = value
|
|
160
|
+
if (value && typeof value === 'object') {
|
|
161
|
+
sanitizedValue = sanitize(value, transferList)
|
|
162
|
+
if (sanitizedValue !== value && !needsSanitization) {
|
|
163
|
+
sanitized = {}
|
|
164
|
+
// Copy all previous properties
|
|
165
|
+
for (const [k] of Object.entries(data)) {
|
|
166
|
+
if (k === key) break
|
|
167
|
+
sanitized[k] = data[k]
|
|
168
|
+
}
|
|
169
|
+
needsSanitization = true
|
|
126
170
|
}
|
|
171
|
+
}
|
|
127
172
|
|
|
128
|
-
|
|
173
|
+
if (needsSanitization) {
|
|
174
|
+
sanitized[key] = sanitizedValue
|
|
129
175
|
}
|
|
130
176
|
}
|
|
131
177
|
|
|
132
|
-
return sanitized
|
|
178
|
+
return needsSanitization ? sanitized : data
|
|
133
179
|
}
|
|
134
180
|
|
|
135
181
|
export class ITC extends EventEmitter {
|
|
136
|
-
#
|
|
182
|
+
#waitingRequests
|
|
137
183
|
#handlers
|
|
138
184
|
#listening
|
|
139
185
|
#handling
|
|
@@ -154,16 +200,13 @@ export class ITC extends EventEmitter {
|
|
|
154
200
|
// Without it, it's impossible to know which "side" of the ITC is being used.
|
|
155
201
|
this.name = name
|
|
156
202
|
this.port = port
|
|
157
|
-
this.#
|
|
203
|
+
this.#waitingRequests = new Map()
|
|
158
204
|
this.#handlers = new Map()
|
|
159
205
|
this.#listening = false
|
|
160
206
|
this.#handling = false
|
|
161
207
|
this.#closeAfterCurrentRequest = false
|
|
162
208
|
this.#throwOnMissingHandler = throwOnMissingHandler ?? true
|
|
163
209
|
|
|
164
|
-
// Make sure the emitter handle a lot of listeners at once before raising a warning
|
|
165
|
-
this.#requestEmitter.setMaxListeners(1e3)
|
|
166
|
-
|
|
167
210
|
/*
|
|
168
211
|
There some contexts in which a message is sent and the event loop empties up while waiting for a response.
|
|
169
212
|
For instance @platformatic/astro when doing build with custom commands.
|
|
@@ -197,19 +240,24 @@ export class ITC extends EventEmitter {
|
|
|
197
240
|
throw new SendBeforeListen()
|
|
198
241
|
}
|
|
199
242
|
|
|
243
|
+
let reqId
|
|
200
244
|
try {
|
|
201
245
|
this._enableKeepAlive()
|
|
202
246
|
|
|
203
247
|
const request = generateRequest(name, message)
|
|
204
248
|
this._send(request, options)
|
|
205
249
|
|
|
206
|
-
const
|
|
250
|
+
const promiseWithResolvers = Promise.withResolvers()
|
|
251
|
+
reqId = request.reqId
|
|
252
|
+
this.#waitingRequests.set(request.reqId, promiseWithResolvers)
|
|
207
253
|
|
|
208
|
-
const { error, data } = await Unpromise.race([
|
|
254
|
+
const { error, data } = await Unpromise.race([promiseWithResolvers.promise, this.#closePromise])
|
|
209
255
|
|
|
210
256
|
if (error !== null) throw error
|
|
211
257
|
return data
|
|
212
258
|
} finally {
|
|
259
|
+
// Clean up the waiting requests map even if an error occurred
|
|
260
|
+
this.#waitingRequests.delete(reqId)
|
|
213
261
|
this._manageKeepAlive()
|
|
214
262
|
}
|
|
215
263
|
}
|
|
@@ -342,7 +390,12 @@ export class ITC extends EventEmitter {
|
|
|
342
390
|
}
|
|
343
391
|
|
|
344
392
|
_emitResponse (response) {
|
|
345
|
-
this.#
|
|
393
|
+
const pending = this.#waitingRequests.get(response.reqId)
|
|
394
|
+
if (!pending) {
|
|
395
|
+
return
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
pending.resolve(response)
|
|
346
399
|
}
|
|
347
400
|
|
|
348
401
|
_enableKeepAlive () {
|