comlink icon indicating copy to clipboard operation
comlink copied to clipboard

Add support for async transferHandle serializer/deserializer

Open poesterlin opened this issue 1 year ago • 2 comments

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.

poesterlin avatar Oct 06 '23 10:10 poesterlin

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

benjamind avatar Dec 14 '23 17:12 benjamind

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.

  • https://github.com/basemachina/comlink/pull/1

taro-28 avatar Apr 11 '24 09:04 taro-28