Skip to content

Commit

Permalink
feat: 🎸 normalize adapter rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 20, 2023
1 parent 0d81728 commit 16ce2cf
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 38 deletions.
5 changes: 3 additions & 2 deletions src/fsa-to-node/FsaNodeFs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion src/fsa-to-node/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<K extends keyof FsaNodeSyncAdapterApi>(method: K, payload: Parameters<FsaNodeSyncAdapterApi[K]>[0]): ReturnType<FsaNodeSyncAdapterApi[K]>;
}

export interface FsaNodeSyncAdapterStats {
kind: 'file' | 'directory';
size?: number;
Expand Down
35 changes: 12 additions & 23 deletions src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}
Expand All @@ -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<FsaNodeWorkerMsg>(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<K extends keyof FsaNodeSyncAdapterApi>(method: K, payload: Parameters<FsaNodeSyncAdapterApi[K]>[0]): ReturnType<FsaNodeSyncAdapterApi[K]> {
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<MsgBack>(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;
}
}
18 changes: 10 additions & 8 deletions src/fsa-to-node/worker/FsaNodeSyncWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -35,12 +35,14 @@ export class FsaNodeSyncWorker {

protected readonly onRequest: AsyncCallback = async (request: Uint8Array): Promise<Uint8Array> => {
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';
Expand Down Expand Up @@ -99,8 +101,8 @@ export class FsaNodeSyncWorker {
}
}

protected handlers: Record<number, (msg: FsaNodeWorkerMsg) => Promise<unknown>> = {
[FsaNodeWorkerMessageCode.Stat]: async ([, location]: FsaNodeWorkerMsgStat): Promise<FsaNodeSyncAdapterStats> => {
protected handlers: {[K in keyof FsaNodeSyncAdapterApi]: ((request: Parameters<FsaNodeSyncAdapterApi[K]>[0]) => Promise<ReturnType<FsaNodeSyncAdapterApi[K]>>)} = {
stat: async (location: FsLocation): Promise<FsaNodeSyncAdapterStats> => {
const handle = await this.getFileOrDir(location[0], location[1], 'statSync');
return {
kind: handle.kind,
Expand Down
2 changes: 1 addition & 1 deletion src/fsa-to-node/worker/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const enum FsaNodeWorkerMessageCode {
Init = 0,
SetRoot,
RootSet,
Request,
Response,
ResponseError,
Stat,
}
6 changes: 3 additions & 3 deletions src/fsa-to-node/worker/types.ts
Original file line number Diff line number Diff line change
@@ -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];
Expand All @@ -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;
Expand All @@ -22,6 +21,7 @@ export type FsaNodeWorkerMsg =
| FsaNodeWorkerMsgInit
| FsaNodeWorkerMsgSetRoot
| FsaNodeWorkerMsgRootSet
| FsaNodeWorkerMsgRequest
| FsaNodeWorkerMsgResponse
| FsaNodeWorkerMsgResponseError
| FsaNodeWorkerMsgStat;
;

0 comments on commit 16ce2cf

Please sign in to comment.