{"_id":"@absolutejs/sync-pack-utils","_rev":"5-54d7060967147c29e5f7265eee2a274f","name":"@absolutejs/sync-pack-utils","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.0":{"name":"@absolutejs/sync-pack-utils","version":"0.1.0","keywords":["absolutejs","sync","sync-pack","utils","helpers"],"author":"Alex Kahn","license":"CC BY-NC 4.0","_id":"@absolutejs/sync-pack-utils@0.1.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"dist":{"shasum":"18bf009df18545180e2f0486a1f400a7772e6119","tarball":"https://registry.npmjs.org/@absolutejs/sync-pack-utils/-/sync-pack-utils-0.1.0.tgz","fileCount":5,"integrity":"sha512-XgPzQXWdc1k8Bsagu/W3Ev515nrunAiS9IqpEH+TIr0hCJN8hjP3jWhh9f6KjhqQ+kVE16vhw3hmHTDJkb3skQ==","signatures":[{"sig":"MEUCIQD/KkM+aeneNp7xFmCK75trKtuIqGILvmCK+tOy4sznNwIgJqFiZPggCTqUWiwe+0nQWBOkyLtlFb2U4eletHd7ypo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18982},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"18bf009df18545180e2f0486a1f400a7772e6119","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run typecheck && bun run test && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-XgPzQXWdc1k8Bsagu/W3Ev515nrunAiS9IqpEH+TIr0hCJN8hjP3jWhh9f6KjhqQ+kVE16vhw3hmHTDJkb3skQ==","repository":{"url":"https://github.com/absolutejs/sync-packs.git","type":"git","directory":"utils"},"_npmVersion":"10.8.3","description":"Shared helpers for @absolutejs/sync packs — resolveActor, requireRowOwner/Moderator, createInMemoryStore, and other patterns extracted from the official packs","directories":{},"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"^1.9.2"},"peerDependencies":{"@absolutejs/sync":">= 1.9.2"},"_npmOperationalInternal":{"tmp":"tmp/sync-pack-utils_0.1.0_1780015560296_0.18040106937434008","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@absolutejs/sync-pack-utils","version":"0.1.1","keywords":["absolutejs","sync","sync-pack","utils","helpers"],"author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/sync-pack-utils@0.1.1","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"dist":{"shasum":"9ac60f765a2cd1b1e589dddd61734b05488bb5a9","tarball":"https://registry.npmjs.org/@absolutejs/sync-pack-utils/-/sync-pack-utils-0.1.1.tgz","fileCount":6,"integrity":"sha512-zt5NUujrAc/UzuGdgBKwxFycoMJIcLhFb/EYySPn1XELP6/rRpKho3lDlrppt4C9zIknZ5BsD/TZDkU0VIPEvA==","signatures":[{"sig":"MEUCIGKOaqj/FCwq+A2wUc4SzVphy4JB3zkUKA05EWWssPgTAiEArGU3VvawXWID8QQAVgZ/cZIwHDklzFb207lbdSnXLo4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30338},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"9ac60f765a2cd1b1e589dddd61734b05488bb5a9","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run typecheck && bun run test && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-zt5NUujrAc/UzuGdgBKwxFycoMJIcLhFb/EYySPn1XELP6/rRpKho3lDlrppt4C9zIknZ5BsD/TZDkU0VIPEvA==","repository":{"url":"https://github.com/absolutejs/sync-packs.git","type":"git","directory":"utils"},"_npmVersion":"10.8.3","description":"Shared helpers for @absolutejs/sync packs — resolveActor, requireRowOwner/Moderator, createInMemoryStore, and other patterns extracted from the official packs","directories":{},"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"^1.9.2"},"peerDependencies":{"@absolutejs/sync":">= 1.9.2"},"_npmOperationalInternal":{"tmp":"tmp/sync-pack-utils_0.1.1_1780071581536_0.19500376325493085","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@absolutejs/sync-pack-utils","version":"0.1.2","keywords":["absolutejs","sync","sync-pack","utils","helpers"],"author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/sync-pack-utils@0.1.2","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/sync-packs/tree/main/utils","bugs":{"url":"https://github.com/absolutejs/sync-packs/issues"},"dist":{"shasum":"9ec09865ee7d4dc5c1bf3cb30cfc9a42e73e58af","tarball":"https://registry.npmjs.org/@absolutejs/sync-pack-utils/-/sync-pack-utils-0.1.2.tgz","fileCount":10,"integrity":"sha512-zIyMFvLb1fN9+9cxYO/P2mj3I5tmxmLcDIQNjTI0eJ9bEWlUW93HKImuUBVj/7NZmEvglDJkNDE7lDd8Xeurjg==","signatures":[{"sig":"MEUCIQCk3df8pKk4UmMRo2gct01X0C8LdSrHKguCrX6pvV6PhAIgKc3pwj3TCuyOxqULR1oqTaWfmWknX1G2gWkROTwNkfM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1123267},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"9ec09865ee7d4dc5c1bf3cb30cfc9a42e73e58af","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run typecheck && bun run test && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-zIyMFvLb1fN9+9cxYO/P2mj3I5tmxmLcDIQNjTI0eJ9bEWlUW93HKImuUBVj/7NZmEvglDJkNDE7lDd8Xeurjg==","absolutejs":{"manifestContract":1},"repository":{"url":"https://github.com/absolutejs/sync-packs.git","type":"git","directory":"utils"},"_npmVersion":"10.8.3","description":"Shared helpers for @absolutejs/sync packs — resolveActor, requireRowOwner/Moderator, createInMemoryStore, and other patterns extracted from the official packs","directories":{},"_nodeVersion":"24.3.0","dependencies":{"@sinclair/typebox":"^0.34.0","@absolutejs/manifest":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"^1.9.2"},"peerDependencies":{"@absolutejs/sync":">= 1.9.2"},"_npmOperationalInternal":{"tmp":"tmp/sync-pack-utils_0.1.2_1783965480626_0.022731327595691075","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@absolutejs/sync-pack-utils","version":"0.1.3","keywords":["absolutejs","sync","sync-pack","utils","helpers"],"author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/sync-pack-utils@0.1.3","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/sync-packs/tree/main/utils","bugs":{"url":"https://github.com/absolutejs/sync-packs/issues"},"dist":{"shasum":"74a6742a40403dc2fb78e33079b0cdc01c78fbce","tarball":"https://registry.npmjs.org/@absolutejs/sync-pack-utils/-/sync-pack-utils-0.1.3.tgz","fileCount":10,"integrity":"sha512-I0fhettD7qKc/Gl9lCLUQEOSm6Y33KVDXqDUbpnrD8p0EpGDzWgsW/OXjyL+b6BHnUNGbLSnkgrsa5+EkcvHwg==","signatures":[{"sig":"MEQCIBWa1MKL6Hl5dB7AE5eSwAC81pPZK/cqoRFb6pQl2/ltAiAawEmsO1bqLmURr+vKuh///3VNf3r7S7uWv/0zcHs+xg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":486098},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"74a6742a40403dc2fb78e33079b0cdc01c78fbce","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run typecheck && bun run test && bun run build && bun publish","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-I0fhettD7qKc/Gl9lCLUQEOSm6Y33KVDXqDUbpnrD8p0EpGDzWgsW/OXjyL+b6BHnUNGbLSnkgrsa5+EkcvHwg==","absolutejs":{"runtimePeers":{"@absolutejs/sync":{"range":">=2.11.0 <3","tested":"2.11.0","buildExternals":["@absolutejs/sync"],"artifactImports":["@absolutejs/sync/engine"]}},"manifestContract":2},"repository":{"url":"https://github.com/absolutejs/sync-packs.git","type":"git","directory":"utils"},"_npmVersion":"10.8.3","description":"Shared helpers for @absolutejs/sync packs — resolveActor, requireRowOwner/Moderator, createInMemoryStore, and other patterns extracted from the official packs","directories":{},"_nodeVersion":"24.3.0","dependencies":{"@sinclair/typebox":"^0.34.0","@absolutejs/manifest":"^0.7.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"prettier":"3.5.3","@types/bun":"1.3.14","typescript":"5.8.3","@absolutejs/sync":"2.11.0"},"peerDependencies":{"@absolutejs/sync":">=2.11.0 <3"},"_npmOperationalInternal":{"tmp":"tmp/sync-pack-utils_0.1.3_1784913347549_0.9102744841748385","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@absolutejs/sync-pack-utils","version":"0.1.4","description":"Shared helpers for @absolutejs/sync packs — resolveActor, requireRowOwner/Moderator, createInMemoryStore, and other patterns extracted from the official packs","repository":{"type":"git","url":"git+https://github.com/absolutejs/sync-packs.git","directory":"utils"},"homepage":"https://github.com/absolutejs/sync-packs/tree/main/utils","bugs":{"url":"https://github.com/absolutejs/sync-packs/issues"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","type":"module","license":"Apache-2.0","author":{"name":"Alex Kahn"},"publishConfig":{"access":"public"},"keywords":["absolutejs","sync","sync-pack","utils","helpers"],"scripts":{"build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --sourcemap --target=bun --external @absolutejs/sync && tsc --project tsconfig.build.json && absolute-manifest emit","test":"bun test","typecheck":"tsc --noEmit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run format && bun run typecheck && bun run test && bun run build && bun publish"},"peerDependencies":{"@absolutejs/sync":">=2.11.0 <3"},"devDependencies":{"@absolutejs/sync":"2.11.0","@types/bun":"1.3.14","prettier":"3.5.3","typescript":"5.8.3"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"absolutejs":{"manifestContract":2},"dependencies":{"@absolutejs/manifest":"^0.9.0","@sinclair/typebox":"^0.34.0"},"_id":"@absolutejs/sync-pack-utils@0.1.4","gitHead":"ba7c2594b58ad9e1cd434195d96823ba678f2260","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-V3RO0iFY7WuUq0yT8JyUJY6yJKSf4XRAmKepuwbd5aEAYX/VMt1OrCJ0J/EyszT9Ij8xjuW/yW2zo1SngOTF4A==","shasum":"cd12342d31eb514b1b0ff123cbe9b27bca393504","tarball":"https://registry.npmjs.org/@absolutejs/sync-pack-utils/-/sync-pack-utils-0.1.4.tgz","fileCount":10,"unpackedSize":494108,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCPImLrzVlzJ1MoggJM7HoInvsa+LTJP+to/BwWCz/l7AIgMEnoW0Tr0HFRl5Iu/CnwH+joAXrs6I4tuBuq573Zqgs="}]},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sync-pack-utils_0.1.4_1787720846991_0.11055664802165532"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T00:46:00.154Z","modified":"2026-08-26T05:07:27.295Z","0.1.0":"2026-05-29T00:46:00.477Z","0.1.1":"2026-05-29T16:19:41.672Z","0.1.2":"2026-07-13T17:58:00.808Z","0.1.3":"2026-07-24T17:15:47.719Z","0.1.4":"2026-08-26T05:07:27.135Z"},"bugs":{"url":"https://github.com/absolutejs/sync-packs/issues"},"author":{"name":"Alex Kahn"},"license":"Apache-2.0","homepage":"https://github.com/absolutejs/sync-packs/tree/main/utils","keywords":["absolutejs","sync","sync-pack","utils","helpers"],"repository":{"type":"git","url":"git+https://github.com/absolutejs/sync-packs.git","directory":"utils"},"description":"Shared helpers for @absolutejs/sync packs — resolveActor, requireRowOwner/Moderator, createInMemoryStore, and other patterns extracted from the official packs","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"readme":"# @absolutejs/sync-pack-utils\n\nShared helpers for [`@absolutejs/sync`](https://github.com/absolutejs/sync)\npacks. Each helper closes one repeated pattern that showed up across the six\nofficial packs (presence, comments, digest, notifications, favorites,\ncounters). The goal: make new packs — first- or third-party — cheaper to\nwrite and consistent with what's already shipped.\n\n```bash\nbun add @absolutejs/sync-pack-utils\n```\n\n## API\n\n### Actor resolution\n\n```ts\nimport {\n\tdefaultGetActorId,\n\tresolveActor,\n} from '@absolutejs/sync-pack-utils';\n\n// (ctx) => ctx.userId — the conventional default.\nconst getActorId = config.getActorId ?? defaultGetActorId<MyCtx>();\n\n// Inside a mutation handler: throws UnauthorizedError if no actor id.\n// The context string ends up in the error message so logs name the op.\nconst actorId = resolveActor(getActorId, ctx, 'mypack:create');\n```\n\n### Permission builders\n\n```ts\nimport {\n\trequireRowOwner,\n\trequireOwnerOrModerator,\n} from '@absolutejs/sync-pack-utils';\n\npermissions: {\n\t[table]: {\n\t\tread: ...,\n\t\t// Owner-only writes — uses row.actorId by default; override the\n\t\t// field name for packs that use authorId, userId, etc.\n\t\tinsert: requireRowOwner(getActorId, 'actorId'),\n\t\tupdate: requireRowOwner(getActorId, 'actorId'),\n\t\t// Owner OR moderator delete. Falls back to store.getById when\n\t\t// actions.delete supplied only the row key (the common case).\n\t\tdelete: requireOwnerOrModerator({\n\t\t\tactorIdField: 'actorId',\n\t\t\tcanModerate,        // optional\n\t\t\tgetActorId,\n\t\t\tstore,              // { getById }\n\t\t}),\n\t},\n},\n```\n\n`requireRowOwner` and `requireOwnerOrModerator` are higher-order — call\nthem once at pack-build time to receive the per-row predicate the engine\nexpects. Both reject when `getActorId(ctx)` is `undefined` (anonymous\ncallers can't own a row).\n\n### In-memory store\n\n```ts\nimport {\n\tcreateInMemoryStore,\n\ttype InMemoryStore,\n} from '@absolutejs/sync-pack-utils';\n\ntype FavoriteRow = { id: string; actorId: string; /* ... */ };\n\nconst store: InMemoryStore<FavoriteRow> =\n\tconfig.store ?? createInMemoryStore<FavoriteRow>();\n\nengine.registerPack(defineSyncPack({\n\t// ...\n\treaders: { favorites: store.reader },\n\twriters: { favorites: store.writer },\n\t// store.getById is available for permission + mutation handler use.\n}));\n```\n\n`createInMemoryStore<Row>()` returns:\n\n- `reader: TableReader<CollectionContext>` — `all()` returns `[...rows.values()]`\n- `writer: TableWriter<Row>` — upsert-by-id; `delete` removes by `row.id`\n- `getById(id)` — point lookup\n- `rows: Map<string, Row>` — direct access (treat as read-only)\n\nEvery official pack uses this as its default backing store and exposes a\n`store?: ...` config field so consumers can swap in a Postgres / Drizzle /\nRedis implementation when they need persistence.\n\n## What's intentionally not here\n\n- **`prefixed(prefix, ...)`**: just use template literals.\n  ``${prefix}<my-collection>`` is fine.\n- **`defineActorPack(...)`**: a Convex-style abstraction that wraps\n  `defineSyncPack` with permission defaults. Decided against — it'd hide\n  the engine surface, which is the thing pack authors learn first.\n- **Validators / Zod adapters**: out of scope; sync's `field` helper +\n  schema is the validation layer.\n\n## Pairing with `@absolutejs/sync/testing`\n\nPack tests typically pair with `@absolutejs/sync/testing` (added in sync\n1.9.2):\n\n```ts\nimport { expectRejection } from '@absolutejs/sync/testing';\nimport { resolveActor } from '@absolutejs/sync-pack-utils';\n\nconst error = await expectRejection(() => {\n\tresolveActor(getActorId, {}, 'mypack:do');\n\treturn Promise.resolve();\n});\nexpect(error).toBeInstanceOf(UnauthorizedError);\n```\n\n## Versioning\n\nThis package stays 0.x indefinitely while the ecosystem settles. When the\nsix official packs are stable, the helpers will follow.\n","readmeFilename":"README.md"}