From 7750b218975cc673760d0af32febf64c18f966d8 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 21:57:30 -0300 Subject: [PATCH 1/9] feat: update poku to v4.3.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d7808cd..bb3939e 100644 --- a/package.json +++ b/package.json @@ -57,12 +57,12 @@ "provenance": true }, "peerDependencies": { - "poku": ">=4.2.0" + "poku": ">=4.3.0" }, "devDependencies": { "@ianvs/prettier-plugin-sort-imports": "^4.7.0", "@types/node": "^25.5.0", - "poku": "file:../poku", + "poku": "^4.3.0", "prettier": "^3.6.2", "rimraf": "^6.0.1", "tsx": "^4.21.0", From 642698d0049d2badcceac6df3016c51c0ce3d7b5 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 21:59:32 -0300 Subject: [PATCH 2/9] chore: regenerate lockfile --- package-lock.json | 99 ++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index b86f62a..da68867 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "@pokujs/scope-hooks", - "version": "1.0.1-rc.0", + "version": "1.0.0-rc.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@pokujs/scope-hooks", - "version": "1.0.1-rc.0", + "version": "1.0.0-rc.1", "license": "MIT", "devDependencies": { "@ianvs/prettier-plugin-sort-imports": "^4.7.0", "@types/node": "^25.5.0", - "poku": "file:../poku", + "poku": "^4.3.0", "prettier": "^3.6.2", "rimraf": "^6.0.1", "tsx": "^4.21.0", @@ -24,40 +24,7 @@ "typescript": ">=6.x.x" }, "peerDependencies": { - "poku": ">=4.2.0" - } - }, - "../poku": { - "name": "poku", - "version": "4.2.0", - "dev": true, - "license": "MIT", - "bin": { - "poku": "lib/bin/index.js" - }, - "devDependencies": { - "@biomejs/biome": "^2.4.10", - "@ianvs/prettier-plugin-sort-imports": "^4.7.1", - "@pokujs/c8": "^1.0.2", - "@pokujs/docker": "^1.0.0", - "@types/node": "^25.5.0", - "concurrently": "^9.2.1", - "jsonc.min": "^1.1.2", - "monocart-coverage-reports": "^2.12.9", - "packages-update": "^2.0.0", - "prettier": "^3.8.1", - "tsx": "^4.21.0", - "typescript": "^6.0.2" - }, - "engines": { - "bun": ">=1.x.x", - "deno": ">=2.x.x", - "node": ">=16.x.x", - "typescript": ">=5.x.x" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wellwelwel" + "poku": ">=4.3.0" } }, "node_modules/@babel/code-frame": { @@ -703,13 +670,13 @@ } }, "node_modules/@types/node": { - "version": "25.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", - "integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.18.0" + "undici-types": "~7.19.0" } }, "node_modules/balanced-match": { @@ -811,9 +778,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.13.7", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", - "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", "dev": true, "license": "MIT", "dependencies": { @@ -862,9 +829,9 @@ } }, "node_modules/lru-cache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.2.tgz", - "integrity": "sha512-wgWa6FWQ3QRRJbIjbsldRJZxdxYngT/dO0I5Ynmlnin8qy7tC6xYzbcJjtN4wHLXtkbVwHzk0C+OejVw1XM+DQ==", + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", "dev": true, "license": "BlueOak-1.0.0", "engines": { @@ -936,13 +903,29 @@ "license": "ISC" }, "node_modules/poku": { - "resolved": "../poku", - "link": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/poku/-/poku-4.3.0.tgz", + "integrity": "sha512-s6xHA93lzirvScBuW5UxUAbx4Cw6C/5MEMTe/27jTtLkDmIsWNpUH2CiMbSOKMxLGj7C3JoM2zfacu3kCrlk3Q==", + "dev": true, + "license": "MIT", + "bin": { + "poku": "lib/bin/index.js" + }, + "engines": { + "bun": ">=1.x.x", + "deno": ">=2.x.x", + "node": ">=16.x.x", + "typescript": ">=5.x.x" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } }, "node_modules/prettier": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, "license": "MIT", "bin": { @@ -1019,9 +1002,9 @@ } }, "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1033,9 +1016,9 @@ } }, "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", "dev": true, "license": "MIT" } From 9f4dec4b351d940178840a883363c1daaba06f49 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:01:19 -0300 Subject: [PATCH 3/9] fix: use local SCOPE_HOOKS_KEY symbol instead of importing from poku/plugins --- src/index.ts | 2 +- tests/scope-hooks.test.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index f9c62e9..b6cb2c7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { SCOPE_HOOKS_KEY } from 'poku/plugins'; +const SCOPE_HOOKS_KEY = Symbol.for('@pokujs/poku.test-scope-hooks'); export type ScopeHookHolder = { scope: unknown }; diff --git a/tests/scope-hooks.test.ts b/tests/scope-hooks.test.ts index c9bb253..35852ec 100644 --- a/tests/scope-hooks.test.ts +++ b/tests/scope-hooks.test.ts @@ -1,7 +1,8 @@ import { afterEach, assert, beforeEach, test } from 'poku'; -import { SCOPE_HOOKS_KEY } from 'poku/plugins'; import { composeScopeHooks, getScopeHooks } from '../src/index.ts'; +const SCOPE_HOOKS_KEY = Symbol.for('@pokujs/poku.test-scope-hooks'); + const g = globalThis as Record; let originalHooks: unknown; From 571e6811444da9fb4d1d00cf430a6b233ec6422f Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:03:38 -0300 Subject: [PATCH 4/9] fix: add --allow-write to deno test script for CI --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bb3939e..22a2ae9 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "scripts": { "test": "node --import=tsx ./node_modules/poku/lib/bin/index.js tests --showLogs", "test:bun": "bun ./node_modules/poku/lib/bin/index.js tests --showLogs", - "test:deno": "deno run -A npm:poku tests --showLogs", + "test:deno": "deno run -A --allow-write npm:poku tests --showLogs", "clean": "rimraf dist", "build": "npm run clean && tsc -p tsconfig.dist.json", "typecheck": "tsc -p tsconfig.build.json --noEmit", From 1da648c0ea912b67117b0b07168854a55ff29fae Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:05:07 -0300 Subject: [PATCH 5/9] fix: remove redundant --allow-write from deno test script (already included in -A) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 22a2ae9..bb3939e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "scripts": { "test": "node --import=tsx ./node_modules/poku/lib/bin/index.js tests --showLogs", "test:bun": "bun ./node_modules/poku/lib/bin/index.js tests --showLogs", - "test:deno": "deno run -A --allow-write npm:poku tests --showLogs", + "test:deno": "deno run -A npm:poku tests --showLogs", "clean": "rimraf dist", "build": "npm run clean && tsc -p tsconfig.dist.json", "typecheck": "tsc -p tsconfig.build.json --noEmit", From 509b1a2b3846b8eb49b9192217e76e0f106ac173 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:05:42 -0300 Subject: [PATCH 6/9] fix: use explicit deno permissions instead of -A --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bb3939e..1787d21 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "scripts": { "test": "node --import=tsx ./node_modules/poku/lib/bin/index.js tests --showLogs", "test:bun": "bun ./node_modules/poku/lib/bin/index.js tests --showLogs", - "test:deno": "deno run -A npm:poku tests --showLogs", + "test:deno": "deno run --allow-read --allow-write --allow-env --allow-run npm:poku tests --showLogs", "clean": "rimraf dist", "build": "npm run clean && tsc -p tsconfig.dist.json", "typecheck": "tsc -p tsconfig.build.json --noEmit", From 02ed2f073c24ee8399de969e090b7388b91d3c26 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:21:10 -0300 Subject: [PATCH 7/9] fix: use fixture files instead of dynamic file creation, fix SCOPE_HOOKS_KEY import, add write permission --- package.json | 2 +- poku.config.ts | 3 + .../scope-hooks/integration.fixture.ts | 79 +++++++++++++ tests/poku-integration.test.ts | 104 +----------------- 4 files changed, 87 insertions(+), 101 deletions(-) create mode 100644 poku.config.ts create mode 100644 tests/__fixtures__/integration/scope-hooks/integration.fixture.ts diff --git a/package.json b/package.json index 1787d21..bb3939e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "scripts": { "test": "node --import=tsx ./node_modules/poku/lib/bin/index.js tests --showLogs", "test:bun": "bun ./node_modules/poku/lib/bin/index.js tests --showLogs", - "test:deno": "deno run --allow-read --allow-write --allow-env --allow-run npm:poku tests --showLogs", + "test:deno": "deno run -A npm:poku tests --showLogs", "clean": "rimraf dist", "build": "npm run clean && tsc -p tsconfig.dist.json", "typecheck": "tsc -p tsconfig.build.json --noEmit", diff --git a/poku.config.ts b/poku.config.ts new file mode 100644 index 0000000..2786d79 --- /dev/null +++ b/poku.config.ts @@ -0,0 +1,3 @@ +export default { + deno: { allow: ['read', 'write', 'env', 'run', 'net'] } +} \ No newline at end of file diff --git a/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts b/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts new file mode 100644 index 0000000..c9a938f --- /dev/null +++ b/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts @@ -0,0 +1,79 @@ +import { AsyncLocalStorage } from 'node:async_hooks'; +import { assert, describe, it } from 'poku'; +import { composeScopeHooks } from '../../../../dist/index.js'; + +const als = new AsyncLocalStorage(); +const events: string[] = []; +const seenIds: number[] = []; +let idSeed = 0; + +composeScopeHooks({ + name: '@pokujs/scope-hooks.integration-fixture', + createHolder: () => ({ scope: undefined }), + runScoped: async (holder, fn) => { + const id = ++idSeed; + holder.scope = { id }; + events.push(`before:${id}`); + + await als.run(id, async () => { + const result = fn(); + if (result instanceof Promise) await result; + }); + + events.push(`after:${id}`); + }, +}); + +await describe('scope hooks integration fixture', async () => { + const runs = [ + it('first test executes inside the composed scope', async () => { + const id = als.getStore(); + assert.ok(typeof id === 'number', 'ALS store exists for the first test'); + seenIds.push(id as number); + + await Promise.resolve(); + + assert.strictEqual( + als.getStore(), + id, + 'ALS store remains stable for the first test' + ); + + events.push(`test:${id}`); + }), + + it('second test executes inside the composed scope', async () => { + const id = als.getStore(); + assert.ok(typeof id === 'number', 'ALS store exists for the second test'); + seenIds.push(id as number); + + await Promise.resolve(); + + assert.strictEqual( + als.getStore(), + id, + 'ALS store remains stable for the second test' + ); + + events.push(`test:${id}`); + }), + ]; + + await Promise.all(runs); +}); + +assert.strictEqual(seenIds.length, 2, 'Both poku it callbacks executed'); +assert.ok( + seenIds[0] !== seenIds[1], + 'Each poku it callback received an isolated scope id' +); + +for (const id of seenIds) { + const beforeIndex = events.indexOf(`before:${id}`); + const testIndex = events.indexOf(`test:${id}`); + const afterIndex = events.indexOf(`after:${id}`); + + assert.ok(beforeIndex >= 0, `before hook ran for scope ${id}`); + assert.ok(testIndex > beforeIndex, `test body ran after before hook for scope ${id}`); + assert.ok(afterIndex > testIndex, `after hook ran after test body for scope ${id}`); +} \ No newline at end of file diff --git a/tests/poku-integration.test.ts b/tests/poku-integration.test.ts index 1de0162..5484c54 100644 --- a/tests/poku-integration.test.ts +++ b/tests/poku-integration.test.ts @@ -1,110 +1,14 @@ -import { mkdtemp, rm, writeFile } from 'node:fs/promises'; -import { join, relative } from 'node:path'; import process from 'node:process'; -import { afterEach, assert, test } from 'poku'; +import { assert, test } from 'poku'; test('scope hooks integrate with poku it execution', async () => { const repoDir = process.cwd(); - const tempDir = await mkdtemp(join(repoDir, '.poku-scope-hooks-')); - const fixturePath = join(tempDir, 'scope-hooks-it.fixture.ts'); - const fixtureRelativePath = relative(repoDir, fixturePath).replaceAll( - '\\', - '/' - ); - const scopeHooksModuleUrl = new URL('../src/index.ts', import.meta.url).href; - - const fixtureSource = ` -import { AsyncLocalStorage } from 'node:async_hooks'; -import { assert, describe, it } from 'poku'; -import { composeScopeHooks } from '${scopeHooksModuleUrl}'; - -const als = new AsyncLocalStorage(); -const events: string[] = []; -const seenIds: number[] = []; -let idSeed = 0; - -composeScopeHooks({ - name: '@pokujs/scope-hooks.integration-fixture', - createHolder: () => ({ scope: undefined }), - runScoped: async (holder, fn) => { - const id = ++idSeed; - holder.scope = { id }; - events.push(\`before:\${id}\`); - - await als.run(id, async () => { - const result = fn(); - if (result instanceof Promise) await result; - }); - - events.push(\`after:\${id}\`); - }, -}); - -await describe('scope hooks integration fixture', async () => { - const runs = [ - it('first test executes inside the composed scope', async () => { - const id = als.getStore(); - assert.ok(typeof id === 'number', 'ALS store exists for the first test'); - seenIds.push(id as number); - - await Promise.resolve(); - - assert.strictEqual( - als.getStore(), - id, - 'ALS store remains stable for the first test' - ); - - events.push(\`test:\${id}\`); - }), - - it('second test executes inside the composed scope', async () => { - const id = als.getStore(); - assert.ok(typeof id === 'number', 'ALS store exists for the second test'); - seenIds.push(id as number); - - await Promise.resolve(); - - assert.strictEqual( - als.getStore(), - id, - 'ALS store remains stable for the second test' - ); - - events.push(\`test:\${id}\`); - }), - ]; - - await Promise.all(runs); -}); - -assert.strictEqual(seenIds.length, 2, 'Both poku it callbacks executed'); -assert.ok( - seenIds[0] !== seenIds[1], - 'Each poku it callback received an isolated scope id' -); - -for (const id of seenIds) { - const beforeIndex = events.indexOf(\`before:\${id}\`); - const testIndex = events.indexOf(\`test:\${id}\`); - const afterIndex = events.indexOf(\`after:\${id}\`); - - assert.ok(beforeIndex >= 0, \`before hook ran for scope \${id}\`); - assert.ok(testIndex > beforeIndex, \`test body ran after before hook for scope \${id}\`); - assert.ok(afterIndex > testIndex, \`after hook ran after test body for scope \${id}\`); -} -`; - - afterEach(async () => { - await rm(tempDir, { recursive: true, force: true }); - }); - - await writeFile(fixturePath, fixtureSource, 'utf8'); + const fixturePath = 'tests/__fixtures__/integration/scope-hooks/integration.fixture.ts'; const { inspectPoku } = await import('poku/plugins'); const result = await inspectPoku({ - command: `./${fixtureRelativePath} --showLogs`, + command: `${fixturePath} --showLogs`, spawnOptions: { cwd: repoDir }, }); @@ -125,4 +29,4 @@ for (const id of seenIds) { result.stdout.includes('second test executes inside the composed scope'), 'Second test executed through poku' ); -}); +}); \ No newline at end of file From 3c7af8be0acde7456538a45126811bd9d01fab18 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:21:40 -0300 Subject: [PATCH 8/9] chore: remove unused poku.config.ts --- poku.config.ts | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 poku.config.ts diff --git a/poku.config.ts b/poku.config.ts deleted file mode 100644 index 2786d79..0000000 --- a/poku.config.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default { - deno: { allow: ['read', 'write', 'env', 'run', 'net'] } -} \ No newline at end of file From d5de85c9919688eaf0c10a8932d3efaa700e07d9 Mon Sep 17 00:00:00 2001 From: lojhan Date: Sun, 19 Apr 2026 22:26:05 -0300 Subject: [PATCH 9/9] fix: correct fixture import path for typecheck --- .../__fixtures__/integration/scope-hooks/integration.fixture.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts b/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts index c9a938f..772320c 100644 --- a/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts +++ b/tests/__fixtures__/integration/scope-hooks/integration.fixture.ts @@ -1,6 +1,6 @@ import { AsyncLocalStorage } from 'node:async_hooks'; import { assert, describe, it } from 'poku'; -import { composeScopeHooks } from '../../../../dist/index.js'; +import { composeScopeHooks } from '../../../../src/index.ts'; const als = new AsyncLocalStorage(); const events: string[] = [];