Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@
"test": "node --test ./test-node/**/*.test.js && pnpm run test-jest:ci"
},
"dependencies": {
"@paralleldrive/cuid2": "2.2.2",
"dezalgo": "^1.0.4",
"once": "^1.4.0"
"@paralleldrive/cuid2": "2.2.2"
},
"packageManager": "pnpm@10.8.1",
"devDependencies": {
Expand Down
19 changes: 0 additions & 19 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions src/Formidable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/* eslint-disable no-underscore-dangle */

import { init as cuid2init } from "@paralleldrive/cuid2";
import dezalgo from "dezalgo";
import { EventEmitter } from "node:events";
import fsPromises from "node:fs/promises";
import os from "node:os";
Expand All @@ -15,13 +14,13 @@ import {
createBrotliDecompress,
createUnzip,
} from "node:zlib";
import once from "once";
import FormidableError, * as errors from "./FormidableError.js";
import PersistentFile from "./PersistentFile.js";
import VolatileFile from "./VolatileFile.js";
import DummyParser from "./parsers/Dummy.js";
import MultipartParser from "./parsers/Multipart.js";
import { json, multipart, octetstream, querystring } from "./plugins/index.js";
import { dezalgo, once } from "./utils.js";

const CUID2_FINGERPRINT = `${
process.env.NODE_ENV
Expand Down
52 changes: 52 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
function copyOwnProperties(source, target) {
Object.keys(source).forEach((key) => {
// eslint-disable-next-line no-param-reassign
target[key] = source[key];
});
return target;
}

function once(fn) {
if (typeof fn !== "function") {
throw new TypeError("Expected a function");
}

const wrapped = function func(...args) {
if (wrapped.called) {
return wrapped.value;
}

wrapped.called = true;
wrapped.value = fn.apply(this, args);
return wrapped.value;
};

wrapped.called = false;
return copyOwnProperties(fn, wrapped);
}

function dezalgo(fn) {
if (typeof fn !== "function") {
throw new TypeError("Expected a function");
}

let sync = true;
queueMicrotask(() => {
sync = false;
});

const wrapped = function funcWrapper(...args) {
if (sync) {
queueMicrotask(() => {
fn.apply(this, args);
});
return undefined;
}

return fn.apply(this, args);
};

return copyOwnProperties(fn, wrapped);
}

export { once, dezalgo };
57 changes: 57 additions & 0 deletions test-node/utils/dezalgo.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { deepStrictEqual, strictEqual } from "node:assert";
import test from "node:test";
import { dezalgo } from "../../src/utils.js";

test("dezalgo contains the dark pony", async () => {
let n = 0;
let called = 0;
const order = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
let index = 0;

function foo(i, cb) {
const wrapped = dezalgo(cb);
if (++n % 2) {
wrapped(true, i);
} else {
process.nextTick(wrapped.bind(null, false, i));
}
}

for (let i = 0; i < 10; i += 1) {
foo(i, (cached, value) => {
strictEqual(value, order[index]);
index += 1;
strictEqual(value % 2, cached ? 0 : 1);
called += 1;
});
strictEqual(called, 0);
}

await new Promise((resolve) => {
setTimeout(resolve, 10);
});

strictEqual(called, 10);
});

test("dezalgo preserves callback own properties", async () => {
const callback = () => {};
callback.meta = { keep: true };

const wrapped = dezalgo(callback);
deepStrictEqual(wrapped.meta, { keep: true });

let called = false;

const done = new Promise((resolve) => {
const asyncWrapped = dezalgo(() => {
called = true;
resolve();
});
asyncWrapped();
strictEqual(called, false);
});

await done;
strictEqual(called, true);
});
37 changes: 37 additions & 0 deletions test-node/utils/once.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { deepStrictEqual, ok, strictEqual } from "node:assert";
import test from "node:test";
import { once } from "../../src/utils.js";

test("once(fn)", () => {
let f = 0;
function fn(g) {
strictEqual(f, 0);
f += 1;
return f + g + this;
}

fn.ownProperty = {};
const wrapped = once(fn);

strictEqual(fn.ownProperty, wrapped.ownProperty);
strictEqual(wrapped.called, false);

for (let i = 0; i < 1e3; i += 1) {
strictEqual(f, i === 0 ? 0 : 1);
const g = wrapped.call(1, 1);
ok(wrapped.called);
strictEqual(g, 3);
strictEqual(f, 1);
}
});

test("once wrapper preserves callback own properties", () => {
function fn() {
return true;
}

fn.meta = { keep: true };
const wrapped = once(fn);

deepStrictEqual(wrapped.meta, { keep: true });
});
Loading