Skip to content

Commit

Permalink
fix: inline thingies dependency (#1004)
Browse files Browse the repository at this point in the history
* fix: inline `thingies`

* fix: remove unneeded code

* chore: don't apply prettier to `thingies` code

* refactor: inline `tick` and `until` functions
  • Loading branch information
G-Rath committed Feb 17, 2024
1 parent 7babd6e commit 6fc340d
Show file tree
Hide file tree
Showing 16 changed files with 102 additions and 15 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Expand Up @@ -11,3 +11,4 @@ package-lock.json
CHANGELOG.md

src/json-joy
src/thingies
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -121,7 +121,6 @@
}
},
"dependencies": {
"thingies": "^1.11.1",
"tslib": "^2.0.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/volume/readFile.test.ts
@@ -1,4 +1,4 @@
import { of } from 'thingies';
import { of } from '../../thingies';
import { memfs } from '../..';

describe('.readFile()', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/crud-to-cas/__tests__/testCasfs.ts
@@ -1,4 +1,4 @@
import { of } from 'thingies';
import { of } from '../../thingies';
import { createHash } from 'crypto';
import { hashToLocation } from '../util';
import type { CasApi } from '../../cas/types';
Expand Down
2 changes: 1 addition & 1 deletion src/crud/__tests__/testCrudfs.ts
@@ -1,4 +1,4 @@
import { of } from 'thingies';
import { of } from '../../thingies';
import type { CrudApi } from '../types';

export type Setup = () => {
Expand Down
4 changes: 2 additions & 2 deletions src/fsa-to-node/FsaNodeReadStream.ts
@@ -1,6 +1,6 @@
import { Readable } from 'stream';
import { Defer } from 'thingies/es6/Defer';
import { concurrency } from 'thingies/es6/concurrency';
import { Defer } from '../thingies/Defer';
import { concurrency } from '../thingies/concurrency';
import type { FsaNodeFsOpenFile } from './FsaNodeFsOpenFile';
import type { IReadStream } from '../node/types/misc';
import type { IReadStreamOptions } from '../node/types/options';
Expand Down
4 changes: 2 additions & 2 deletions src/fsa-to-node/FsaNodeWriteStream.ts
@@ -1,6 +1,6 @@
import { Writable } from 'stream';
import { Defer } from 'thingies/es6/Defer';
import { concurrency } from 'thingies/es6/concurrency';
import { Defer } from '../thingies/Defer';
import { concurrency } from '../thingies/concurrency';
import { flagsToNumber } from '../node/util';
import { FLAG } from '../consts/FLAG';
import { FsaNodeFsOpenFile } from './FsaNodeFsOpenFile';
Expand Down
11 changes: 10 additions & 1 deletion src/fsa-to-node/__tests__/FsaNodeFs.test.ts
Expand Up @@ -3,10 +3,19 @@ import { AMODE } from '../../consts/AMODE';
import { nodeToFsa } from '../../node-to-fsa';
import { IDirent, IStats } from '../../node/types/misc';
import { FsaNodeFs } from '../FsaNodeFs';
import { tick, until, of } from 'thingies';
import { of } from '../../thingies';
import { onlyOnNode20 } from '../../__tests__/util';
import { FLAG } from '../../consts/FLAG';

const tick = (ms: number = 1) => new Promise(r => setTimeout(r, ms));

const until = async (check: () => boolean | Promise<boolean>, pollInterval: number = 1) => {
do {
if (await check()) return;
await tick(pollInterval);
} while (true);
};

const setup = (json: NestedDirectoryJSON | null = null, mode: 'read' | 'readwrite' = 'readwrite') => {
const { fs: mfs, vol } = memfs({ mountpoint: json });
const dir = nodeToFsa(mfs, '/mountpoint', { mode, syncHandleAllowed: true });
Expand Down
2 changes: 1 addition & 1 deletion src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts
@@ -1,4 +1,4 @@
import { Defer } from 'thingies/es6/Defer';
import { Defer } from '../../thingies/Defer';
import { FsaNodeWorkerMessageCode } from './constants';
import { SyncMessenger } from './SyncMessenger';
import { decoder, encoder } from '../json';
Expand Down
20 changes: 20 additions & 0 deletions src/thingies/Defer.ts
@@ -0,0 +1,20 @@
/**
* An externally resolvable/rejectable "promise". Use it to resolve/reject
* promise at any time.
*
* ```ts
* const future = new Defer();
*
* future.promise.then(value => console.log(value));
*
* future.resolve(123);
* ```
*/
export class Defer<T> {
public readonly resolve!: (data: T) => void;
public readonly reject!: (error: any) => void;
public readonly promise: Promise<T> = new Promise<T>((resolve, reject) => {
(this as any).resolve = resolve;
(this as any).reject = reject;
});
}
36 changes: 36 additions & 0 deletions src/thingies/concurrency.ts
@@ -0,0 +1,36 @@
import {go} from './go';
import type {Code} from './types';

class Task<T = unknown> {
public readonly resolve!: (data: T) => void;
public readonly reject!: (error: any) => void;
public readonly promise = new Promise<T>((resolve, reject) => {
(this as any).resolve = resolve;
(this as any).reject = reject;
});
constructor(public readonly code: Code<T>) {}
}

/** Limits concurrency of async code. */
export const concurrency = (limit: number) => {
let workers = 0;
const queue = new Set<Task>();
const work = async () => {
const task = queue.values().next().value;
if (task) queue.delete(task);
else return;
workers++;
try {
task.resolve(await task.code());
} catch (error) {
task.reject(error);
} finally {
workers--, queue.size && go(work);
}
};
return async <T = unknown>(code: Code<T>): Promise<T> => {
const task = new Task(code);
queue.add(task as Task<unknown>);
return workers < limit && go(work), task.promise;
};
};
6 changes: 6 additions & 0 deletions src/thingies/go.ts
@@ -0,0 +1,6 @@
import type {Code} from './types';

/** Executes code concurrently. */
export const go = <T>(code: Code<T>): void => {
code().catch(() => {});
};
4 changes: 4 additions & 0 deletions src/thingies/index.ts
@@ -0,0 +1,4 @@
export * from './concurrency';
export * from './Defer';
export * from './go';
export * from './of';
16 changes: 16 additions & 0 deletions src/thingies/of.ts
@@ -0,0 +1,16 @@
/**
* Given a promise awaits it and returns a 3-tuple, with the following members:
*
* - First entry is either the resolved value of the promise or `undefined`.
* - Second entry is either the error thrown by promise or `undefined`.
* - Third entry is a boolean, truthy if promise was resolved and falsy if rejected.
*
* @param promise Promise to convert to 3-tuple.
*/
export const of = async <T, E = unknown>(promise: Promise<T>): Promise<[T | undefined, E | undefined, boolean]> => {
try {
return [await promise, undefined, true];
} catch (error: unknown) {
return [undefined, error as E, false];
}
};
1 change: 1 addition & 0 deletions src/thingies/types.ts
@@ -0,0 +1 @@
export type Code<T = unknown> = () => Promise<T>;
5 changes: 0 additions & 5 deletions yarn.lock
Expand Up @@ -6682,11 +6682,6 @@ text-table@~0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==

thingies@^1.11.1:
version "1.16.0"
resolved "https://registry.yarnpkg.com/thingies/-/thingies-1.16.0.tgz#968cde87fbf0fdd69a1a3a8e9678324f634e5053"
integrity sha512-J23AVs11hSQxuJxvfQyMIaS9z1QpDxOCvMkL3ZxZl8/jmkgmnNGWrlyNxVz6Jbh0U6DuGmHqq6f7zUROfg/ncg==

through2@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764"
Expand Down

0 comments on commit 6fc340d

Please sign in to comment.