From 96b8374542ecc07294afe94bb18c77d4e7cb0fec Mon Sep 17 00:00:00 2001 From: streamich Date: Sun, 18 Jun 2023 19:00:14 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20normalize=20adapter=20rp?= =?UTF-8?q?c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fsa-to-node/FsaNodeFs.ts | 5 +-- src/fsa-to-node/types.ts | 6 +++- .../worker/FsaNodeSyncAdapterWorker.ts | 35 +++++++------------ src/fsa-to-node/worker/FsaNodeSyncWorker.ts | 18 +++++----- src/fsa-to-node/worker/constants.ts | 2 +- src/fsa-to-node/worker/types.ts | 6 ++-- 6 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/fsa-to-node/FsaNodeFs.ts b/src/fsa-to-node/FsaNodeFs.ts index 636f83f49..f9935de94 100644 --- a/src/fsa-to-node/FsaNodeFs.ts +++ b/src/fsa-to-node/FsaNodeFs.ts @@ -765,11 +765,13 @@ export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchrono if (!adapter) throw new Error('No sync adapter'); const filename = pathToFilename(path); const location = pathToLocation(filename); - const res = adapter.stat(location); + const res = adapter.call('stat', location); const stats = new FsaNodeStats(bigint, res.size ?? 0, res.kind); return stats; }; + public readonly lstatSync: FsSynchronousApi['lstatSync'] = this.statSync; + public readonly accessSync: FsSynchronousApi['accessSync'] = noop; public readonly appendFileSync: FsSynchronousApi['appendFileSync'] = notSupported; public readonly chmodSync: FsSynchronousApi['chmodSync'] = noop; @@ -787,7 +789,6 @@ export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchrono public readonly lchmodSync: FsSynchronousApi['lchmodSync'] = noop; public readonly lchownSync: FsSynchronousApi['lchownSync'] = noop; public readonly linkSync: FsSynchronousApi['linkSync'] = notSupported; - public readonly lstatSync: FsSynchronousApi['lstatSync'] = notSupported; public readonly mkdirSync: FsSynchronousApi['mkdirSync'] = notSupported; public readonly mkdirpSync: FsSynchronousApi['mkdirpSync'] = notSupported; public readonly mkdtempSync: FsSynchronousApi['mkdtempSync'] = notSupported; diff --git a/src/fsa-to-node/types.ts b/src/fsa-to-node/types.ts index 14a006d72..57d4bc8d8 100644 --- a/src/fsa-to-node/types.ts +++ b/src/fsa-to-node/types.ts @@ -3,10 +3,14 @@ export type FsLocation = [folder: string[], file: string]; /** * Adapter which implements synchronous calls to the FSA API. */ -export interface FsaNodeSyncAdapter { +export interface FsaNodeSyncAdapterApi { stat(location: FsLocation): FsaNodeSyncAdapterStats; } +export interface FsaNodeSyncAdapter { + call(method: K, payload: Parameters[0]): ReturnType; +} + export interface FsaNodeSyncAdapterStats { kind: 'file' | 'directory'; size?: number; diff --git a/src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts b/src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts index 069868eea..7897fa108 100644 --- a/src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts +++ b/src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts @@ -3,8 +3,8 @@ import { FsaNodeWorkerMessageCode } from './constants'; import { encode, decode } from 'json-joy/es6/json-pack/msgpack/util'; import { SyncMessenger } from './SyncMessenger'; import type * as fsa from '../../fsa/types'; -import type { FsLocation, FsaNodeSyncAdapter, FsaNodeSyncAdapterStats } from '../types'; -import type { FsaNodeWorkerMsg, FsaNodeWorkerMsgInit, FsaNodeWorkerMsgRootSet, FsaNodeWorkerMsgSetRoot } from './types'; +import type { FsaNodeSyncAdapter, FsaNodeSyncAdapterApi } from '../types'; +import type { FsaNodeWorkerMsg, FsaNodeWorkerMsgInit, FsaNodeWorkerMsgRequest, FsaNodeWorkerMsgResponse, FsaNodeWorkerMsgResponseError, FsaNodeWorkerMsgRootSet, FsaNodeWorkerMsgSetRoot } from './types'; let rootId = 0; @@ -31,7 +31,7 @@ export class FsaNodeSyncAdapterWorker implements FsaNodeSyncAdapter { case FsaNodeWorkerMessageCode.RootSet: { const [, rootId] = msg as FsaNodeWorkerMsgRootSet; if (id !== rootId) return; - const adapter = new FsaNodeSyncAdapterWorker(messenger!, id, dir); + const adapter = new FsaNodeSyncAdapterWorker(messenger!, dir); future.resolve(adapter); break; } @@ -42,32 +42,21 @@ export class FsaNodeSyncAdapterWorker implements FsaNodeSyncAdapter { public constructor( protected readonly messenger: SyncMessenger, - protected readonly id: number, protected readonly root: fsa.IFileSystemDirectoryHandle, ) {} - public call(msg: FsaNodeWorkerMsg): unknown { - const request = encode(msg); - const response = this.messenger.callSync(request); - const resposeMsg = decode(response as any); - switch (resposeMsg[0]) { - case FsaNodeWorkerMessageCode.Response: { - const [, responseData] = resposeMsg; - return responseData; - break; - } - case FsaNodeWorkerMessageCode.ResponseError: { - const [, error] = resposeMsg; - throw error; - break; - } + public call(method: K, payload: Parameters[0]): ReturnType { + const request: FsaNodeWorkerMsgRequest = [FsaNodeWorkerMessageCode.Request, method, payload]; + const encoded = encode(request); + const encodedResponse = this.messenger.callSync(encoded); + type MsgBack = FsaNodeWorkerMsgResponse | FsaNodeWorkerMsgResponseError; + const [code, data] = decode(encodedResponse as any); + switch (code) { + case FsaNodeWorkerMessageCode.Response: return data as any; + case FsaNodeWorkerMessageCode.ResponseError: throw data; default: { throw new Error('Invalid response message code'); } } } - - public stat(location: FsLocation): FsaNodeSyncAdapterStats { - return this.call([FsaNodeWorkerMessageCode.Stat, location]) as FsaNodeSyncAdapterStats; - } } diff --git a/src/fsa-to-node/worker/FsaNodeSyncWorker.ts b/src/fsa-to-node/worker/FsaNodeSyncWorker.ts index 6d24f6f65..5f789898e 100644 --- a/src/fsa-to-node/worker/FsaNodeSyncWorker.ts +++ b/src/fsa-to-node/worker/FsaNodeSyncWorker.ts @@ -2,8 +2,8 @@ import { AsyncCallback, SyncMessenger } from './SyncMessenger'; import { encode, decode } from 'json-joy/es6/json-pack/msgpack/util'; import { FsaNodeWorkerMessageCode } from './constants'; import type * as fsa from '../../fsa/types'; -import type { FsaNodeWorkerError, FsaNodeWorkerMsg, FsaNodeWorkerMsgInit, FsaNodeWorkerMsgRootSet, FsaNodeWorkerMsgStat } from './types'; -import type { FsaNodeSyncAdapterStats } from '../types'; +import type { FsaNodeWorkerError, FsaNodeWorkerMsg, FsaNodeWorkerMsgInit, FsaNodeWorkerMsgRequest, FsaNodeWorkerMsgRootSet } from './types'; +import type { FsLocation, FsaNodeSyncAdapterApi, FsaNodeSyncAdapterStats } from '../types'; export class FsaNodeSyncWorker { protected readonly sab: SharedArrayBuffer = new SharedArrayBuffer(1024 * 32); @@ -35,12 +35,14 @@ export class FsaNodeSyncWorker { protected readonly onRequest: AsyncCallback = async (request: Uint8Array): Promise => { try { - const message = decode(request as any) as FsaNodeWorkerMsg; + const message = decode(request as any) as FsaNodeWorkerMsgRequest; if (!Array.isArray(message)) throw new Error('Invalid message format'); const code = message[0]; - const handler = this.handlers[code]; - if (!handler) throw new Error('Invalid message code'); - const response = await handler(message); + if (code !== FsaNodeWorkerMessageCode.Request) throw new Error('Invalid message code'); + const [, method, payload] = message; + const handler = this.handlers[method]; + if (!handler) throw new Error(`Unknown method ${method}`); + const response = await handler(payload); return encode([FsaNodeWorkerMessageCode.Response, response]); } catch (err) { const message = err && typeof err === 'object' && err.message ? err.message : 'Unknown error'; @@ -99,8 +101,8 @@ export class FsaNodeSyncWorker { } } - protected handlers: Record Promise> = { - [FsaNodeWorkerMessageCode.Stat]: async ([, location]: FsaNodeWorkerMsgStat): Promise => { + protected handlers: {[K in keyof FsaNodeSyncAdapterApi]: ((request: Parameters[0]) => Promise>)} = { + stat: async (location: FsLocation): Promise => { const handle = await this.getFileOrDir(location[0], location[1], 'statSync'); return { kind: handle.kind, diff --git a/src/fsa-to-node/worker/constants.ts b/src/fsa-to-node/worker/constants.ts index 60a16c31f..89aa9d980 100644 --- a/src/fsa-to-node/worker/constants.ts +++ b/src/fsa-to-node/worker/constants.ts @@ -2,7 +2,7 @@ export const enum FsaNodeWorkerMessageCode { Init = 0, SetRoot, RootSet, + Request, Response, ResponseError, - Stat, } diff --git a/src/fsa-to-node/worker/types.ts b/src/fsa-to-node/worker/types.ts index 29e8ea90e..49e4bc107 100644 --- a/src/fsa-to-node/worker/types.ts +++ b/src/fsa-to-node/worker/types.ts @@ -1,5 +1,4 @@ import type { IFileSystemDirectoryHandle } from '../../fsa/types'; -import type { FsLocation } from '../types'; import type { FsaNodeWorkerMessageCode } from './constants'; export type FsaNodeWorkerMsgInit = [type: FsaNodeWorkerMessageCode.Init, sab: SharedArrayBuffer]; @@ -9,9 +8,9 @@ export type FsaNodeWorkerMsgSetRoot = [ dir: IFileSystemDirectoryHandle, ]; export type FsaNodeWorkerMsgRootSet = [type: FsaNodeWorkerMessageCode.RootSet, id: number]; +export type FsaNodeWorkerMsgRequest = [type: FsaNodeWorkerMessageCode.Request, method: string, data: unknown]; export type FsaNodeWorkerMsgResponse = [type: FsaNodeWorkerMessageCode.Response, data: unknown]; export type FsaNodeWorkerMsgResponseError = [type: FsaNodeWorkerMessageCode.ResponseError, data: unknown]; -export type FsaNodeWorkerMsgStat = [type: FsaNodeWorkerMessageCode.Stat, location: FsLocation]; export interface FsaNodeWorkerError { message: string; @@ -22,6 +21,7 @@ export type FsaNodeWorkerMsg = | FsaNodeWorkerMsgInit | FsaNodeWorkerMsgSetRoot | FsaNodeWorkerMsgRootSet + | FsaNodeWorkerMsgRequest | FsaNodeWorkerMsgResponse | FsaNodeWorkerMsgResponseError - | FsaNodeWorkerMsgStat; + ;