diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..654c6d4 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets). + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md). diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..ba0f177 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.3/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..dcfba5a --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +pnpm-lock.yaml +docs/ diff --git a/.tangled/workflows/ci.yaml b/.tangled/workflows/ci.yaml new file mode 100644 index 0000000..2448394 --- /dev/null +++ b/.tangled/workflows/ci.yaml @@ -0,0 +1,24 @@ +when: + - event: ['push', 'pull_request'] + +dependencies: + nixpkgs: + - nodejs_24 + - pnpm + +steps: + - name: install + command: | + pnpm install --frozen-lockfile + + - name: lint + command: | + pnpm lint + + - name: typecheck + command: | + pnpm tsc --noEmit + + - name: test + command: | + pnpm test diff --git a/.tangled/workflows/publish.yaml b/.tangled/workflows/publish.yaml new file mode 100644 index 0000000..da59661 --- /dev/null +++ b/.tangled/workflows/publish.yaml @@ -0,0 +1,21 @@ +when: + - event: ['push'] + branch: ['main'] + +dependencies: + nixpkgs: + - nodejs_24 + - pnpm + +steps: + - name: install + command: | + pnpm install --frozen-lockfile + + - name: version and publish + environment: + NPM_TOKEN: $NPM_TOKEN + command: | + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc + pnpm changeset version + pnpm changeset publish diff --git a/README.md b/README.md index c6096ec..44d431f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ import { add } from './math.ts'; { using run = workers(2); - const result = await run(add(3, 4)); // single task + const result = await run(add(3, 4)); // single task const [a, b] = await run([add(1, 2), add(3, 4)]); // batch } ``` @@ -125,9 +125,9 @@ import { shared, int32, bool, mutex, string, bytes } from 'moroutine'; #### Primitives ```ts -const counter = int32(); // standalone Int32 -const flag = bool(); // standalone Bool -const big = int64(); // standalone Int64 (bigint) +const counter = int32(); // standalone Int32 +const flag = bool(); // standalone Bool +const big = int64(); // standalone Int64 (bigint) ``` #### Atomics @@ -136,8 +136,8 @@ Atomic variants use `Atomics.*` for thread-safe operations without a lock. ```ts const counter = int32atomic(); -counter.add(1); // atomic increment, returns previous value -counter.load(); // atomic read +counter.add(1); // atomic increment, returns previous value +counter.load(); // atomic read ``` Full atomic operations: `load`, `store`, `add`, `sub`, `and`, `or`, `xor`, `exchange`, `compareExchange`. @@ -149,9 +149,9 @@ Plain objects in `shared()` create structs backed by a single `SharedArrayBuffer ```ts const point = shared({ x: int32, y: int32 }); -point.load(); // { x: 0, y: 0 } +point.load(); // { x: 0, y: 0 } point.store({ x: 10, y: 20 }); -point.fields.x.store(10); // direct field access +point.fields.x.store(10); // direct field access ``` Structs nest: @@ -169,22 +169,22 @@ Arrays in `shared()` create fixed-length tuples. ```ts const pair = shared([int32, bool]); -pair.load(); // [0, false] +pair.load(); // [0, false] pair.store([42, true]); -pair.get(0).store(99); +pair.elements[0].store(99); ``` #### Bytes and Strings ```ts -const buf = bytes(32); // fixed 32-byte buffer -buf.store(new Uint8Array(32)); // exact length required -buf.load(); // Readonly view -buf.view[0] = 0xff; // direct mutable access +const buf = bytes(32); // fixed 32-byte buffer +buf.store(new Uint8Array(32)); // exact length required +buf.load(); // Readonly view +buf.view[0] = 0xff; // direct mutable access -const name = string(64); // UTF-8, max 64 bytes +const name = string(64); // UTF-8, max 64 bytes name.store('hello'); -name.load(); // 'hello' +name.load(); // 'hello' ``` #### Value Shorthand @@ -192,10 +192,10 @@ name.load(); // 'hello' Primitive values in schemas infer their type. ```ts -shared(0) // Int32 initialized to 0 -shared(true) // Bool initialized to true -shared(0n) // Int64 initialized to 0n -shared({ x: 10, y: 20 }) // struct with Int32 fields +shared(0); // Int32 initialized to 0 +shared(true); // Bool initialized to true +shared(0n); // Int64 initialized to 0n +shared({ x: 10, y: 20 }); // struct with Int32 fields ``` ### Locks @@ -219,8 +219,8 @@ mu.unlock(); ```ts const rw = rwlock(); -using guard = await rw.readLock(); // multiple readers OK -using guard = await rw.writeLock(); // exclusive access +using guard = await rw.readLock(); // multiple readers OK +using guard = await rw.writeLock(); // exclusive access ``` ### Using with Workers @@ -254,10 +254,7 @@ const pos = shared({ x: int32, y: int32 }); { using run = workers(4); - await run([ - updatePosition(mu, pos, 1, 0), - updatePosition(mu, pos, 0, 1), - ]); + await run([updatePosition(mu, pos, 1, 0), updatePosition(mu, pos, 0, 1)]); } console.log(pos.load()); // { x: 1, y: 1 } @@ -323,12 +320,7 @@ const ch = channel(generate(100)); { using run = workers(4); - const [a, b, c, d] = await run([ - process(ch), - process(ch), - process(ch), - process(ch), - ]); + const [a, b, c, d] = await run([process(ch), process(ch), process(ch), process(ch)]); // Items distributed across workers — no duplicates, no gaps } ``` diff --git a/examples/sqlite/db.ts b/examples/sqlite/db.ts index e829ca1..417725f 100644 --- a/examples/sqlite/db.ts +++ b/examples/sqlite/db.ts @@ -19,10 +19,13 @@ export const insertUser = mo(import.meta, (db: DatabaseSync, name: string, email return Number(result.lastInsertRowid); }); -export const getUser = mo(import.meta, (db: DatabaseSync, id: number): { id: number; name: string; email: string } | undefined => { - const stmt = db.prepare('SELECT id, name, email FROM users WHERE id = ?'); - return stmt.get(id) as { id: number; name: string; email: string } | undefined; -}); +export const getUser = mo( + import.meta, + (db: DatabaseSync, id: number): { id: number; name: string; email: string } | undefined => { + const stmt = db.prepare('SELECT id, name, email FROM users WHERE id = ?'); + return stmt.get(id) as { id: number; name: string; email: string } | undefined; + }, +); export const listUsers = mo(import.meta, (db: DatabaseSync): { id: number; name: string; email: string }[] => { const stmt = db.prepare('SELECT id, name, email FROM users'); diff --git a/package.json b/package.json index a7fe79f..f9476a1 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,15 @@ "exports": "./src/index.ts", "packageManager": "pnpm@10.33.0", "scripts": { + "changeset": "changeset", + "lint": "prettier --check .", + "lint:fix": "prettier --write .", "test": "node --experimental-strip-types --test --test-force-exit test/**/*.test.ts" }, "devDependencies": { + "@changesets/cli": "^2.30.0", "@types/node": "^25.5.2", + "prettier": "^3.8.2", "typescript": "^6.0.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf367d7..1d389c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,18 +8,391 @@ importers: .: devDependencies: + '@changesets/cli': + specifier: ^2.30.0 + version: 2.30.0(@types/node@25.5.2) '@types/node': specifier: ^25.5.2 version: 25.5.2 + prettier: + specifier: ^3.8.2 + version: 3.8.2 typescript: specifier: ^6.0.2 version: 6.0.2 packages: + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@changesets/apply-release-plan@7.1.0': + resolution: {integrity: sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ==} + + '@changesets/assemble-release-plan@6.0.9': + resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.30.0': + resolution: {integrity: sha512-5D3Nk2JPqMI1wK25pEymeWRSlSMdo5QOGlyfrKg0AOufrUcjEE3RQgaCpHoBiM31CSNrtSgdJ0U6zL1rLDDfBA==} + hasBin: true + + '@changesets/config@3.1.3': + resolution: {integrity: sha512-vnXjcey8YgBn2L1OPWd3ORs0bGC4LoYcK/ubpgvzNVr53JXV5GiTVj7fWdMRsoKUH7hhhMAQnsJUqLr21EncNw==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} + + '@changesets/get-release-plan@4.0.15': + resolution: {integrity: sha512-Q04ZaRPuEVZtA+auOYgFaVQQSA98dXiVe/yFaZfY7hoSmQICHGvP0TF4u3EDNHWmmCS4ekA/XSpKlSM2PyTS2g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@25.5.2': resolution: {integrity: sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + hasBin: true + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.8.2: + resolution: {integrity: sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==} + engines: {node: '>=14'} + hasBin: true + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + typescript@6.0.2: resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} engines: {node: '>=14.17'} @@ -28,12 +401,442 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + snapshots: + '@babel/runtime@7.29.2': {} + + '@changesets/apply-release-plan@7.1.0': + dependencies: + '@changesets/config': 3.1.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 + + '@changesets/assemble-release-plan@6.0.9': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.30.0(@types/node@25.5.2)': + dependencies: + '@changesets/apply-release-plan': 7.1.0 + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.15 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@25.5.2) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.3': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.3': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.4 + + '@changesets/get-release-plan@4.0.15': + dependencies: + '@changesets/assemble-release-plan': 6.0.9 + '@changesets/config': 3.1.3 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.1.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + + '@inquirer/external-editor@1.0.3(@types/node@25.5.2)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 25.5.2 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.2 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.2 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@types/node@12.20.55': {} + '@types/node@25.5.2': dependencies: undici-types: 7.18.2 + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + chardet@2.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + detect-indent@6.1.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + esprima@4.0.1: {} + + extendable-error@0.1.7: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + human-id@4.1.3: {} + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + + isexe@2.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.startcase@4.4.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mri@1.2.0: {} + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + pify@4.0.1: {} + + prettier@2.8.8: {} + + prettier@3.8.2: {} + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + resolve-from@5.0.0: {} + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safer-buffer@2.1.2: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} + + term-size@2.2.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + typescript@6.0.2: {} undici-types@7.18.2: {} + + universalify@0.1.2: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 diff --git a/src/channel.ts b/src/channel.ts index 9ace508..157ab84 100644 --- a/src/channel.ts +++ b/src/channel.ts @@ -58,7 +58,9 @@ class Distributor { } else { port1.postMessage({ done: true }); } - try { port1.close(); } catch {} + try { + port1.close(); + } catch {} } else { this.tryPull(); } @@ -80,7 +82,9 @@ class Distributor { this.done = true; for (const c of this.consumers) { c.port.postMessage({ done: true }); - try { c.port.close(); } catch {} + try { + c.port.close(); + } catch {} } break; } @@ -98,7 +102,9 @@ class Distributor { this.error = err instanceof Error ? err : new Error(String(err)); for (const c of this.consumers) { c.port.postMessage({ done: true, error: this.error.message }); - try { c.port.close(); } catch {} + try { + c.port.close(); + } catch {} } } diff --git a/src/execute.ts b/src/execute.ts index 2d2c40a..eb19fc2 100644 --- a/src/execute.ts +++ b/src/execute.ts @@ -38,20 +38,33 @@ function pipeToPort(iterable: AsyncIterable, port: MessagePort, highWat let cancelled = false; port.on('message', (signal: string) => { - if (signal === 'pause') { paused = true; } - else if (signal === 'resume') { + if (signal === 'pause') { + paused = true; + } else if (signal === 'resume') { paused = false; - if (resumed) { resumed(); resumed = null; } + if (resumed) { + resumed(); + resumed = null; + } } }); - port.on('close', () => { cancelled = true; if (resumed) { resumed(); resumed = null; } }); + port.on('close', () => { + cancelled = true; + if (resumed) { + resumed(); + resumed = null; + } + }); (async () => { try { for await (const value of iterable) { if (cancelled) break; - if (paused) await new Promise((r) => { resumed = r; }); + if (paused) + await new Promise((r) => { + resumed = r; + }); if (cancelled) break; const extracted = extractTransferables([value]); const serialized = serializeArg(extracted.args[0]); @@ -66,13 +79,14 @@ function pipeToPort(iterable: AsyncIterable, port: MessagePort, highWat port.postMessage({ done: true, error: message }); } } - try { port.close(); } catch {} + try { + port.close(); + } catch {} })(); } function isAsyncGenerator(arg: unknown): boolean { - return typeof arg === 'object' && arg !== null && - (arg as any)[Symbol.toStringTag] === 'AsyncGenerator'; + return typeof arg === 'object' && arg !== null && (arg as any)[Symbol.toStringTag] === 'AsyncGenerator'; } function prepareArg(arg: unknown): unknown { @@ -122,7 +136,12 @@ export function execute(worker: Worker, id: string, args: unknown[]): Promise }); } -export function dispatchStream(worker: Worker, id: string, args: unknown[], opts?: ChannelOptions): AsyncIterable { +export function dispatchStream( + worker: Worker, + id: string, + args: unknown[], + opts?: ChannelOptions, +): AsyncIterable { const url = id.slice(0, id.lastIndexOf('#')); freezeModule(url); const highWater = opts?.highWaterMark ?? DEFAULT_HIGH_WATER; @@ -146,7 +165,10 @@ export function dispatchStream(worker: Worker, id: string, args: unknown[], o let workerUnrefed = false; function unrefWorkerOnce() { - if (!workerUnrefed) { workerUnrefed = true; worker.unref(); } + if (!workerUnrefed) { + workerUnrefed = true; + worker.unref(); + } } port1.on('message', (msg: { value?: unknown; done?: boolean; error?: string }) => { @@ -155,18 +177,27 @@ export function dispatchStream(worker: Worker, id: string, args: unknown[], o done = true; port1.close(); unrefWorkerOnce(); - if (waiting) { waiting(); waiting = null; } + if (waiting) { + waiting(); + waiting = null; + } return; } if (msg.done) { done = true; port1.close(); unrefWorkerOnce(); - if (waiting) { waiting(); waiting = null; } + if (waiting) { + waiting(); + waiting = null; + } return; } queue.push(deserializeArg(msg.value) as T); - if (waiting) { waiting(); waiting = null; } + if (waiting) { + waiting(); + waiting = null; + } if (!paused && queue.length >= highWater) { paused = true; port1.postMessage('pause'); @@ -189,7 +220,9 @@ export function dispatchStream(worker: Worker, id: string, args: unknown[], o } if (error) throw error; if (done) return { done: true, value: undefined }; - await new Promise((resolve) => { waiting = resolve; }); + await new Promise((resolve) => { + waiting = resolve; + }); } }, async return(): Promise> { diff --git a/src/mo.ts b/src/mo.ts index 587563c..3daa0dc 100644 --- a/src/mo.ts +++ b/src/mo.ts @@ -27,11 +27,12 @@ type StreamMoroutine = { }; type IsNever = [T] extends [never] ? true : false; -type MoReturn = IsNever extends true - ? Moroutine - : [R] extends [AsyncGenerator] - ? StreamMoroutine - : Moroutine; +type MoReturn = + IsNever extends true + ? Moroutine + : [R] extends [AsyncGenerator] + ? StreamMoroutine + : Moroutine; function isAsyncGeneratorFunction(fn: Function): boolean { return fn.constructor.name === 'AsyncGeneratorFunction'; diff --git a/src/worker-entry.ts b/src/worker-entry.ts index e2a42bf..5f0b5b9 100644 --- a/src/worker-entry.ts +++ b/src/worker-entry.ts @@ -24,16 +24,25 @@ function portToAsyncIterable(port: MessagePort): AsyncIterable { if (msg.error) { error = new Error(msg.error); done = true; - if (waiting) { waiting(); waiting = null; } + if (waiting) { + waiting(); + waiting = null; + } return; } if (msg.done) { done = true; - if (waiting) { waiting(); waiting = null; } + if (waiting) { + waiting(); + waiting = null; + } return; } queue.push(deserializeArg(msg.value) as T); - if (waiting) { waiting(); waiting = null; } + if (waiting) { + waiting(); + waiting = null; + } if (!paused && queue.length >= HIGH_WATER) { paused = true; port.postMessage('pause'); @@ -55,7 +64,9 @@ function portToAsyncIterable(port: MessagePort): AsyncIterable { } if (error) throw error; if (done) return { done: true, value: undefined }; - await new Promise((resolve) => { waiting = resolve; }); + await new Promise((resolve) => { + waiting = resolve; + }); } }, async return(): Promise> { @@ -112,23 +123,33 @@ parentPort!.on('message', async (msg: { callId?: number; id: string; args: unkno let cancelled = false; port.on('message', (signal: string) => { - if (signal === 'pause') { paused = true; } - else if (signal === 'resume') { + if (signal === 'pause') { + paused = true; + } else if (signal === 'resume') { paused = false; - if (resumed) { resumed(); resumed = null; } + if (resumed) { + resumed(); + resumed = null; + } } }); port.on('close', () => { cancelled = true; - if (resumed) { resumed(); resumed = null; } + if (resumed) { + resumed(); + resumed = null; + } }); try { const gen = fn(...resolvedArgs) as AsyncGenerator; for await (const value of gen) { if (cancelled) break; - if (paused) await new Promise((r) => { resumed = r; }); + if (paused) + await new Promise((r) => { + resumed = r; + }); if (cancelled) break; const serialized = serializeArg(value); const transferList: Transferable[] = []; @@ -143,7 +164,9 @@ parentPort!.on('message', async (msg: { callId?: number; id: string; args: unkno port.postMessage({ done: true, error: message }); } } - try { port.close(); } catch {} + try { + port.close(); + } catch {} return; } diff --git a/test/channel-autodetect.test.ts b/test/channel-autodetect.test.ts index e2f092e..78b83d3 100644 --- a/test/channel-autodetect.test.ts +++ b/test/channel-autodetect.test.ts @@ -5,7 +5,11 @@ import { sumStream, uppercaseStream, generate } from './fixtures/channel-autodet describe('AsyncGenerator auto-detection', () => { it('auto-detects AsyncGenerator arg without channel()', async () => { - async function* numbers() { yield 1; yield 2; yield 3; } + async function* numbers() { + yield 1; + yield 2; + yield 3; + } const run = workers(1); try { const result = await run(sumStream(numbers())); @@ -16,7 +20,10 @@ describe('AsyncGenerator auto-detection', () => { }); it('auto-detects with streaming output (bidirectional)', async () => { - async function* words() { yield 'hello'; yield 'world'; } + async function* words() { + yield 'hello'; + yield 'world'; + } const run = workers(1); try { const results: string[] = []; diff --git a/test/channel-fanout.test.ts b/test/channel-fanout.test.ts index 4eb383f..4c19c7b 100644 --- a/test/channel-fanout.test.ts +++ b/test/channel-fanout.test.ts @@ -8,14 +8,12 @@ describe('channel fan-out', () => { const data = channel(generate(20)); const run = workers(4); try { - const [a, b, c, d] = await run([ - collectItems(data), - collectItems(data), - collectItems(data), - collectItems(data), - ]); + const [a, b, c, d] = await run([collectItems(data), collectItems(data), collectItems(data), collectItems(data)]); const all = [...a, ...b, ...c, ...d].sort((x, y) => x - y); - assert.deepEqual(all, Array.from({ length: 20 }, (_, i) => i)); + assert.deepEqual( + all, + Array.from({ length: 20 }, (_, i) => i), + ); } finally { run[Symbol.dispose](); } @@ -25,10 +23,7 @@ describe('channel fan-out', () => { const data = channel(generate(100)); const run = workers(2); try { - const [a, b] = await run([ - collectItems(data), - collectItems(data), - ]); + const [a, b] = await run([collectItems(data), collectItems(data)]); const setA = new Set(a); for (const item of b) { assert.ok(!setA.has(item), `Item ${item} appeared in both consumers`); @@ -40,7 +35,11 @@ describe('channel fan-out', () => { }); it('single consumer via channel() still works', async () => { - async function* numbers() { yield 1; yield 2; yield 3; } + async function* numbers() { + yield 1; + yield 2; + yield 3; + } const run = workers(1); try { const result = await run(collectItems(channel(numbers()))); @@ -57,12 +56,12 @@ describe('channel fan-out', () => { const data = channel(localGen()); const run = workers(2); try { - const [a, b] = await run([ - collectItems(data), - collectItems(data), - ]); + const [a, b] = await run([collectItems(data), collectItems(data)]); const all = [...a, ...b].sort((x, y) => x - y); - assert.deepEqual(all, Array.from({ length: 10 }, (_, i) => i)); + assert.deepEqual( + all, + Array.from({ length: 10 }, (_, i) => i), + ); } finally { run[Symbol.dispose](); } diff --git a/test/channel-wrapper.test.ts b/test/channel-wrapper.test.ts index 207265a..282eb45 100644 --- a/test/channel-wrapper.test.ts +++ b/test/channel-wrapper.test.ts @@ -4,14 +4,18 @@ import assert from 'node:assert/strict'; describe('channel()', () => { it('returns an object with the channel marker', async () => { const { channel } = await import('../src/channel.ts'); - async function* gen() { yield 1; } + async function* gen() { + yield 1; + } const wrapped = channel(gen()); assert.ok(Symbol.for('moroutine.channel') in (wrapped as any)); }); it('accepts highWaterMark option', async () => { const { channel } = await import('../src/channel.ts'); - async function* gen() { yield 1; } + async function* gen() { + yield 1; + } const wrapped = channel(gen(), { highWaterMark: 32 }); assert.ok(wrapped); }); diff --git a/test/fixtures/exit-dedicated-main.ts b/test/fixtures/exit-dedicated-main.ts index de0cc7b..aa196eb 100644 --- a/test/fixtures/exit-dedicated-main.ts +++ b/test/fixtures/exit-dedicated-main.ts @@ -1,4 +1,5 @@ import { gen } from './exit-gen.ts'; -for await (const v of gen()) {} +for await (const v of gen()) { +} console.log('DONE'); diff --git a/test/fixtures/exit-gen.ts b/test/fixtures/exit-gen.ts index 619e797..fc0e0eb 100644 --- a/test/fixtures/exit-gen.ts +++ b/test/fixtures/exit-gen.ts @@ -1,3 +1,6 @@ import { mo } from 'moroutine'; -export const gen = mo(import.meta, async function* () { yield 1; yield 2; }); +export const gen = mo(import.meta, async function* () { + yield 1; + yield 2; +}); diff --git a/test/fixtures/exit-pool-main.ts b/test/fixtures/exit-pool-main.ts index a3bd2d8..c8ebe96 100644 --- a/test/fixtures/exit-pool-main.ts +++ b/test/fixtures/exit-pool-main.ts @@ -2,6 +2,7 @@ import { workers } from 'moroutine'; import { gen } from './exit-gen.ts'; const run = workers(1); -for await (const v of run(gen())) {} +for await (const v of run(gen())) { +} run[Symbol.dispose](); console.log('DONE'); diff --git a/test/stream-exit.test.ts b/test/stream-exit.test.ts index 5e9df20..294f4ac 100644 --- a/test/stream-exit.test.ts +++ b/test/stream-exit.test.ts @@ -10,20 +10,20 @@ const fixturesDir = join(fileURLToPath(import.meta.url), '..', 'fixtures'); describe('streaming process exit', () => { it('process exits after streaming on dedicated worker', async () => { - const { stdout } = await exec(process.execPath, [ - '--no-warnings', - '--experimental-strip-types', - join(fixturesDir, 'exit-dedicated-main.ts'), - ], { timeout: 5000 }); + const { stdout } = await exec( + process.execPath, + ['--no-warnings', '--experimental-strip-types', join(fixturesDir, 'exit-dedicated-main.ts')], + { timeout: 5000 }, + ); assert.ok(stdout.includes('DONE')); }); it('process exits after streaming with pool', async () => { - const { stdout } = await exec(process.execPath, [ - '--no-warnings', - '--experimental-strip-types', - join(fixturesDir, 'exit-pool-main.ts'), - ], { timeout: 5000 }); + const { stdout } = await exec( + process.execPath, + ['--no-warnings', '--experimental-strip-types', join(fixturesDir, 'exit-pool-main.ts')], + { timeout: 5000 }, + ); assert.ok(stdout.includes('DONE')); }); }); diff --git a/test/stream-input.test.ts b/test/stream-input.test.ts index 01851d1..8959402 100644 --- a/test/stream-input.test.ts +++ b/test/stream-input.test.ts @@ -5,7 +5,11 @@ import { sumStream, uppercaseStream } from './fixtures/stream-input.ts'; describe('channel() input (main -> worker)', () => { it('pipes async iterable to worker', async () => { - async function* numbers() { yield 1; yield 2; yield 3; } + async function* numbers() { + yield 1; + yield 2; + yield 3; + } const run = workers(1); try { const result = await run(sumStream(channel(numbers()))); @@ -16,7 +20,10 @@ describe('channel() input (main -> worker)', () => { }); it('bidirectional: channel input + generator output', async () => { - async function* words() { yield 'hello'; yield 'world'; } + async function* words() { + yield 'hello'; + yield 'world'; + } const run = workers(1); try { const results: string[] = []; @@ -30,7 +37,11 @@ describe('channel() input (main -> worker)', () => { }); it('accepts highWaterMark on channel()', async () => { - async function* numbers() { yield 1; yield 2; yield 3; } + async function* numbers() { + yield 1; + yield 2; + yield 3; + } const run = workers(1); try { const result = await run(sumStream(channel(numbers(), { highWaterMark: 2 }))); diff --git a/test/stream-task.test.ts b/test/stream-task.test.ts index 4972380..aaa12af 100644 --- a/test/stream-task.test.ts +++ b/test/stream-task.test.ts @@ -5,7 +5,9 @@ import { mo } from 'moroutine'; describe('StreamTask', () => { it('mo() with async function* returns StreamTask', async () => { const { StreamTask } = await import('../src/stream-task.ts'); - const gen = mo(import.meta, async function* () { yield 1; }); + const gen = mo(import.meta, async function* () { + yield 1; + }); const task = gen(); assert.ok(task instanceof StreamTask); }); @@ -20,7 +22,9 @@ describe('StreamTask', () => { }); it('StreamTask has uid, id, and args', async () => { - const gen = mo(import.meta, async function* (n: number) { yield n; }); + const gen = mo(import.meta, async function* (n: number) { + yield n; + }); const task = gen(5); assert.equal(typeof task.id, 'string'); assert.deepEqual(task.args, [5]); @@ -28,7 +32,9 @@ describe('StreamTask', () => { }); it('StreamTask uids are unique', async () => { - const gen = mo(import.meta, async function* () { yield 1; }); + const gen = mo(import.meta, async function* () { + yield 1; + }); const a = gen(); const b = gen(); assert.notEqual(a.uid, b.uid); diff --git a/test/stream.test.ts b/test/stream.test.ts index b7c2384..3502dc7 100644 --- a/test/stream.test.ts +++ b/test/stream.test.ts @@ -35,11 +35,14 @@ describe('streaming moroutines (worker -> main)', () => { const run = workers(1); try { const results: number[] = []; - await assert.rejects(async () => { - for await (const value of run(failAfter(3))) { - results.push(value); - } - }, { message: 'intentional error' }); + await assert.rejects( + async () => { + for await (const value of run(failAfter(3))) { + results.push(value); + } + }, + { message: 'intentional error' }, + ); assert.deepEqual(results, [0, 1, 2]); } finally { run[Symbol.dispose]();