GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11.3k stars 386 forks source link

Add support for async transferHandle serializer/deserializer #646

Open poesterlin opened 12 months ago

poesterlin commented 12 months ago

Im trying to create a transferHandle for Origin Private File System (OPFS) file handles since they are not cloneable in all browsers. This is the approach I tried:


/**
 * Check if the given value is a FileHandle and if it needs to be serialized.
 * @param value 
 * @returns 
 */
function canHandle(value: unknown): value is FileSystemFileHandle {
    const isFileHandle = value instanceof FileSystemFileHandle
    if (!isFileHandle) {
        return false;
    }

    try {
        // if we can clone the value, there is no need to serialize it
        structuredClone(value);
        return false;
    } catch {
        // if we can't clone the value, we need to serialize it
    }

    return true;
}
transferHandlers.set('FileHandle', {
    canHandle,
    serialize: async (ev) => {
        const root = await navigator.storage.getDirectory();
        return [await root.resolve(ev), []];
    },
    deserialize: async (path) => {
        let directory = await navigator.storage.getDirectory();
        const fileName = path.pop();

        for (const part of path) {
            directory = await directory.getDirectoryHandle(part, { create: true });
        }

        return directory.getDirectoryHandle(fileName, { create: true });
    }
} satisfies TransferHandler<FileSystemFileHandle, string[]>);

However, I've run into an issue where the serializer and deserializer functions are not compatible with Promises. This is causing the transferHandle to not work as expected.

I'm wondering if there is another way to solve this issue or if I need to do the serialization manually. Any help or suggestions would be greatly appreciated.

benjamind commented 9 months ago

When you say not compatible with Promises what do you mean exactly? Can you post an example somewhere to test out?

taro-28 commented 5 months ago

Hi! We encountered the same issue and forked to enable the use of async functions with serialize/deserialization. I hope this will be helpful to you.