{"_id":"@alfiz/prisma","_rev":"5-6a422cd9f73bba7600cbff312b73c9ef","name":"@alfiz/prisma","dist-tags":{"latest":"0.8.1"},"versions":{"0.5.1":{"name":"@alfiz/prisma","version":"0.5.1","license":"UNLICENSED","_id":"@alfiz/prisma@0.5.1","maintainers":[{"name":"bytestorm","email":"kamil.m.arif@gmail.com"}],"dist":{"shasum":"6b6a77c320636ef2ed9df2aae41fbf6d669a6bbd","tarball":"https://registry.npmjs.org/@alfiz/prisma/-/prisma-0.5.1.tgz","fileCount":19,"integrity":"sha512-F+0YIW/e975/d1HpKq2E8UsWuqtN9zmhRVxpCsAgM8ZDOo2Z7NsVcPDnCAJrTWawELjQqe9m7/OI9JxlAocajA==","signatures":[{"sig":"MEUCIQC1toi+B66LUdEvW252ifIYa9+8QULBghnd7TMPjj7KRwIgKjuv0Dm4DF1fsIubfAKVuklyAz3oCqMdflRufJQzNuI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":95542},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"f118f368fec80dc2de0e11e37b4055cd2b93aeec","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"bytestorm","email":"kamil.m.arif@gmail.com"},"_npmVersion":"11.11.0","description":"The Prisma storage driver for the Alfiz Application: implements the storage seam over any Prisma client generated from the bundled schema fragment, with @prisma/client kept out of the dependency graph via a structural delegate interface.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"@alfiz/core":"^0.5.1","@alfiz/application":"^0.5.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/prisma_0.5.1_1785217990397_0.11436983741124918","host":"s3://npm-registry-packages-npm-production"}},"0.5.2":{"name":"@alfiz/prisma","version":"0.5.2","license":"UNLICENSED","_id":"@alfiz/prisma@0.5.2","maintainers":[{"name":"bytestorm","email":"kamil.m.arif@gmail.com"}],"dist":{"shasum":"257105e2a6c7b7b8b27d5f56b93cf4b38623cd4d","tarball":"https://registry.npmjs.org/@alfiz/prisma/-/prisma-0.5.2.tgz","fileCount":19,"integrity":"sha512-5ZIslr7f+OCfegb5k1E5umsM6/xlH/Sc3hZEcGwvhIxlrj7uCTT+VJHnH6cG4OrhfmaJUqjFtrNFOejL15cp4g==","signatures":[{"sig":"MEUCIBIBawDZf33nf9pQHh7V0ZwdCBDrqL3oVII36i/ft4kyAiEAnHYTMsTd9jmah9/JRl7/i6Cv8HoDSguOz3h0vU66HF4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":99412},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"982070d13339c73aed23bc250730ae9971c0a1ed","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"bytestorm","email":"kamil.m.arif@gmail.com"},"_npmVersion":"11.11.0","description":"The Prisma storage driver for the Alfiz Application: implements the storage seam over any Prisma client generated from the bundled schema fragment, with @prisma/client kept out of the dependency graph via a structural delegate interface.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"@alfiz/core":"^0.5.2","@alfiz/application":"^0.5.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/prisma_0.5.2_1785369422899_0.515011542098277","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@alfiz/prisma","version":"0.7.0","license":"MIT","_id":"@alfiz/prisma@0.7.0","maintainers":[{"name":"bytestorm","email":"kamil.m.arif@gmail.com"}],"dist":{"shasum":"b79c0b78052296abdff6aa21b4e3108a9ddb316c","tarball":"https://registry.npmjs.org/@alfiz/prisma/-/prisma-0.7.0.tgz","fileCount":20,"integrity":"sha512-6BU02B1N14MkgPVsFtFHWy2RbuFrKbWpVw/njzhROjRPDQc3XZE7RkjH/ppIyJPUmN6XjUX3fDS19N0yQthuIg==","signatures":[{"sig":"MEUCIGzXwEIwL+khOB1dyUZPm84BCCsPNBd15wrVtnkQD5EZAiEA6tyPIP6ujWhYJ0KIA4CL/U0hqTD7A9YLUhL91oeVzjI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110684},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"e4daba611d3a9826f105513ba023346077eb45b8","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"bytestorm","email":"kamil.m.arif@gmail.com"},"_npmVersion":"11.11.0","description":"The Prisma storage driver for the Alfiz Application: implements the storage seam over any Prisma client generated from the bundled schema fragment, with @prisma/client kept out of the dependency graph via a structural delegate interface.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"@alfiz/core":"^0.7.0","@alfiz/application":"^0.7.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/prisma_0.7.0_1786068434882_0.5244226601224251","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@alfiz/prisma","version":"0.8.0","license":"MIT","_id":"@alfiz/prisma@0.8.0","maintainers":[{"name":"bytestorm","email":"kamil.m.arif@gmail.com"}],"dist":{"shasum":"96b19e451023bda739a7198b5b10a7476e403fbf","tarball":"https://registry.npmjs.org/@alfiz/prisma/-/prisma-0.8.0.tgz","fileCount":20,"integrity":"sha512-EiuMdqsCtP+68m46HBo2Lj3aGT8S2I3fgp/wfHL+/PSAI0NDR8WKww7DaYET/JonfYEDwq4saNI7IB5woUCIDg==","signatures":[{"sig":"MEUCIQCEHlh1xrKZ/J1iX7NOOWyFxOEuPvT0ehLcsqEVwql7vAIgECHC627hdGT4wnOLE+rDNC+ewOdP84IZfX10GzgIer4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":136993},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"07e6b3c3fda7a29b4cae65754a7798a250794375","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"bytestorm","email":"kamil.m.arif@gmail.com"},"_npmVersion":"11.11.0","description":"The Prisma storage driver for the Alfiz Application: implements the storage seam over any Prisma client generated from the bundled schema fragment, with @prisma/client kept out of the dependency graph via a structural delegate interface.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"@alfiz/core":"^0.8.0","@alfiz/application":"^0.8.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/prisma_0.8.0_1786225379424_0.2966636850995019","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@alfiz/prisma","version":"0.8.1","description":"The Prisma storage driver for the Alfiz Application: implements the storage seam over any Prisma client generated from the bundled schema fragment, with @prisma/client kept out of the dependency graph via a structural delegate interface.","license":"MIT","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"dependencies":{"@alfiz/core":"^0.8.1","@alfiz/application":"^0.8.1"},"gitHead":"384e8ffec40c8db9e1b2fa52d409540d6a62ee88","_id":"@alfiz/prisma@0.8.1","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-WFnAimN8MUsM/7FUliykzuRnD7jHhEgELkEpeQUg9Joq6puhXqp4CqwI+4DUK9Xd37C4yiyu+KHTelBUQm3jGQ==","shasum":"cf141a6c2ee49c1cbed35c9396004025b0686b24","tarball":"https://registry.npmjs.org/@alfiz/prisma/-/prisma-0.8.1.tgz","fileCount":20,"unpackedSize":136993,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBRk64aXQV5I1u4zsB7C1MQJRWHKsCyIZawtJRVc4e2AAiBDTsbOZtuTvAwdtwwa+ggsLeUS6NENQSwI8TZNeRO+IA=="}]},"_npmUser":{"name":"bytestorm","email":"kamil.m.arif@gmail.com"},"directories":{},"maintainers":[{"name":"bytestorm","email":"kamil.m.arif@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/prisma_0.8.1_1786235072866_0.18402137223818937"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-28T05:53:10.242Z","modified":"2026-08-09T00:24:33.183Z","0.5.1":"2026-07-28T05:53:10.544Z","0.5.2":"2026-07-29T23:57:03.042Z","0.7.0":"2026-08-07T02:07:15.019Z","0.8.0":"2026-08-08T21:42:59.596Z","0.8.1":"2026-08-09T00:24:33.017Z"},"license":"MIT","description":"The Prisma storage driver for the Alfiz Application: implements the storage seam over any Prisma client generated from the bundled schema fragment, with @prisma/client kept out of the dependency graph via a structural delegate interface.","maintainers":[{"name":"bytestorm","email":"kamil.m.arif@gmail.com"}],"readme":"# @alfiz/prisma\r\n\r\nThe Prisma storage driver for the Alfiz Application. It implements the\r\nstorage seam (`StorageDriver` from `@alfiz/application`) over a Prisma\r\nclient — and does it without depending on `@prisma/client`: the driver is\r\nwritten against a structural interface (`AlfizPrismaDelegates`) that any\r\nclient generated from the bundled schema fragment satisfies.\r\n\r\n## 1. Merge the schema fragment\r\n\r\nCopy the models from [`prisma/schema.prisma`](./prisma/schema.prisma) into\r\nyour application's own `schema.prisma` (they are a fragment — no datasource\r\nor generator blocks — and all models are prefixed `Alfiz` to avoid\r\ncollisions), then migrate and generate as usual:\r\n\r\n```sh\r\nnpx prisma migrate dev\r\nnpx prisma generate\r\n```\r\n\r\nSince 0.8.0 the fragment is **v2**: every model carries an `app`\r\npartition discriminator (`@default(\"\")`) with composite keys led by it,\r\nso several Applications can share one set of tables. A single-application\r\ndeployment changes nothing — an unpartitioned driver reads and writes\r\npartition `\"\"`, which is where a migrated v1 dataset lands. Upgrading\r\nfrom the v1 fragment is a column-add plus PK/index rebuilds; see\r\n`docs/MIGRATING.md` §12 in the repository root.\r\n\r\n## 2. Construct the driver\r\n\r\n```ts\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { createApplication } from \"@alfiz/application\";\r\nimport { prismaDriver } from \"@alfiz/prisma\";\r\n\r\nconst prisma = new PrismaClient();\r\nconst storage = prismaDriver(prisma); // structural match — no adapter, no cast\r\nconst app = createApplication({ storage /* ... */ });\r\n```\r\n\r\nThat no-cast promise is pinned in CI by a compile-only fixture\r\n(`src/prisma-client-shape.ts`) replicating the exact input types\r\n`prisma generate` emits — Json inputs that reject bare `null`,\r\n`bigint | number` scalars, Prisma-style optional properties — so a\r\ndelegate-surface change that would force `as unknown as\r\nAlfizPrismaDelegates` on adopters fails this package's own build instead.\r\nThe match holds under `exactOptionalPropertyTypes` too.\r\n\r\n## The invalidation log (AlfizEpoch / AlfizEvent)\r\n\r\nThe fragment includes two models backing the Application's\r\n`events: { persist: true }` option — the persisted invalidation log that\r\nlets clients on OTHER processes revalidate their caches with one\r\nsingle-row read (`AlfizEpoch`) instead of waiting out a TTL. They are\r\nadditive: merge them and `prisma migrate dev` as usual; the epoch row is\r\nlazily created on first append, no seed required. A client generated\r\nWITHOUT them still satisfies the driver interface — the driver then omits\r\nthe optional event methods and `events.persist` refuses at construction.\r\n\r\n## Permission metrics (AlfizMetric)\r\n\r\nOne more additive model backs the Application's `metrics: {}` option:\r\nrolling counter buckets, keyed by `(bucket, dimension, subject, metric)`\r\nand incremented by upsert, so every app server reporting a window sums into\r\nthe same numbers. Storage is bounded by attributed rows × retention ÷\r\nbucket size, and compaction is a `deleteMany` past the retention cutoff.\r\nLike the log models, a client generated WITHOUT it still satisfies the\r\ndriver interface — the driver omits the metric methods and the Application\r\nrefuses `metrics` at construction rather than accepting batches that go\r\nnowhere. Nothing in this table is access data: dropping it loses counts and\r\nchanges no decision.\r\n\r\n## Partitioned storage: several Applications, one set of tables\r\n\r\n```ts\r\nconst docs = prismaDriver(prisma, { partition: \"docs\", lock });\r\nconst zoom = prismaDriver(prisma, { partition: \"zoom\", lock });\r\n```\r\n\r\nEach driver is pinned to its partition at construction and cannot address\r\nany other. The discriminator is *unforgettable by construction*: the\r\ndelegate types require `app` on every where and create shape, so a query\r\ninside the driver that omitted the partition would fail to compile rather\r\nthan scan every tenant — pinned by the same compile-only fixture as the\r\nno-cast promise. The recommended partition key is the application's\r\nprimary catalog namespace, and the rule in shared tables is **all\r\npartitioned or none**: an application that omits the option lands in\r\npartition `\"\"` beside any legacy data.\r\n\r\nIsolation here is logical and cooperative — every co-tenant holds\r\ncredentials to the whole table set. When isolation must hold against a\r\ncompromised co-tenant rather than against bugs, prefer\r\nschema-per-application via the connection string (`?schema=docs` on\r\nPostgres; a separate database on MySQL) with separate credentials: one\r\n`PrismaClient` per app, zero schema changes, isolation enforced by the\r\ndatabase. Grading a shared-table deployment (or your own driver) is what\r\n`isolationContractCases` / `meshContractCases` in\r\n`@alfiz/application/driver-suite` exist for.\r\n\r\n## Multi-node deployments: pass an advisory lock\r\n\r\n`runExclusive` defaults to an in-process mutex, which serializes graph\r\nwrites within one process only. If several nodes share the database, supply\r\na database advisory lock so two nodes cannot jointly write a graph cycle —\r\nand, with event persistence on, so two nodes cannot interleave sequence\r\nallocation in the invalidation log (event appends serialize under the same\r\nlock, key `alfiz:events`):\r\n\r\n```ts\r\nconst storage = prismaDriver(prisma, {\r\n  lock: (key, fn) =>\r\n    prisma.$transaction(async (tx) => {\r\n      await tx.$executeRaw`SELECT pg_advisory_xact_lock(hashtext(${key}))`;\r\n      return fn();\r\n    }),\r\n});\r\n```\r\n\r\nThe keys the driver hands to `lock` already carry the partition\r\n(`\"docs:groups\"` under `partition: \"docs\"`), so co-tenants sharing one\r\ndatabase never contend on each other's advisory locks. Supplying `lock`\r\nis also what marks the driver cross-process capable\r\n(`StorageDriver.crossProcess`) — a prerequisite for accepting a mesh\r\nWRITE edge into the partition, where a peer Application is a second\r\nprocess executing this partition's semantics (`openPeerApplication` in\r\nwrite mode refuses without it, loudly).\r\n\r\n## What lives where\r\n\r\nThe driver stores and retrieves; it never interprets. All ids are opaque\r\nstrings assigned by the Application layer, which also owns graph integrity,\r\nrequest workflows, catalog versioning, and the audit log. Epoch-ms\r\ntimestamps are stored as `BigInt` columns for lossless round-tripping;\r\noptional core fields map to nullable columns (`undefined` ↔ `NULL`).\r\n","readmeFilename":"README.md"}