Skip to content

Commit

Permalink
chore: export extractProperties (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin committed Apr 2, 2022
1 parent 818dc97 commit e7393f1
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/tasty-maps-smoke.md
@@ -0,0 +1,5 @@
---
"synckit": patch
---

chore: export extractProperties
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -105,7 +105,7 @@
]
},
"typeCoverage": {
"atLeast": 99.5,
"atLeast": 99.67,
"cache": true,
"detail": true,
"ignoreAsAssertion": true,
Expand Down
30 changes: 7 additions & 23 deletions src/index.ts
Expand Up @@ -48,31 +48,14 @@ export interface SynckitOptions {
// MessagePort doesn't copy the properties of Error objects. We still want
// error objects to have extra properties such as "warnings" so implement the
// property copying manually.
const extractProperties = (object: unknown): Record<string, unknown> => {
const properties: Record<string, unknown> = {}
export const extractProperties = <T>(object?: T): T | undefined => {
if (object && typeof object === 'object') {
const properties = {} as T
for (const key in object) {
properties[key] = (object as Record<string, unknown>)[key]
properties[key as keyof T] = object[key]
}
return properties
}
return properties
}

// MessagePort doesn't copy the properties of Error objects. We still want
// error objects to have extra properties such as "warnings" so implement the
// property copying manually.
const applyProperties = <T>(
object: T,
properties?: Record<string, unknown>,
): T => {
if (!properties) {
return object
}
// eslint-disable-next-line sonar/for-in
for (const key in properties) {
;(object as Record<string, unknown>)[key] = properties[key]
}
return object
}

export function createSyncFn<T extends AnyAsyncFn>(
Expand Down Expand Up @@ -166,15 +149,16 @@ function startWorkerThread<R, T extends AnyAsyncFn<R>>(
result,
error,
properties,
} = receiveMessageOnPort(mainPort)!.message as WorkerToMainMessage<R>
} = (receiveMessageOnPort(mainPort) as { message: WorkerToMainMessage<R> })
.message

/* istanbul ignore if */
if (id !== id2) {
throw new Error(`Internal error: Expected id ${id} but got id ${id2}`)
}

if (error) {
throw applyProperties(error, properties)
throw Object.assign(error, properties)
}

return result!
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Expand Up @@ -32,7 +32,7 @@ export interface WorkerData {
export interface DataMessage<T> {
result?: T
error?: unknown
properties?: Record<string, unknown>
properties?: unknown
}

export interface WorkerToMainMessage<T = unknown> extends DataMessage<T> {
Expand Down
20 changes: 18 additions & 2 deletions test/fn.spec.ts
Expand Up @@ -2,12 +2,13 @@ import { createRequire } from 'module'

import { jest } from '@jest/globals'

import { createSyncFn } from 'synckit'
import { createSyncFn, extractProperties } from 'synckit'

type AsyncWorkerFn<T = number> = (result: T, timeout?: number) => Promise<T>

beforeEach(() => {
jest.resetModules()

delete process.env.SYNCKIT_BUFFER_SIZE
delete process.env.SYNCKIT_TIMEOUT

Expand Down Expand Up @@ -45,7 +46,7 @@ test('createSyncFn', () => {
expect(syncFn3(2)).toBe(2)
expect(syncFn3(5, 0)).toBe(5)

expect(() => errSyncFn()).toThrow('Worker Error')
expect(() => errSyncFn()).toThrowErrorMatchingInlineSnapshot(`"Worker Error"`)

const syncFn4 = createSyncFn<AsyncWorkerFn>(workerCjsPath)

Expand All @@ -66,3 +67,18 @@ test('timeout', async () => {
'Internal error: Atomics.wait() failed: timed-out',
)
})

test('extractProperties', () => {
expect(extractProperties()).toBeUndefined()
expect(extractProperties({})).toEqual({})
expect(extractProperties(new Error('message'))).toEqual({})
expect(
extractProperties(
Object.assign(new Error('message'), {
code: 'CODE',
}),
),
).toEqual({
code: 'CODE',
})
})

0 comments on commit e7393f1

Please sign in to comment.