-
-
Notifications
You must be signed in to change notification settings - Fork 2
feat: migration handling #175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f2fa687
a11afef
831ad68
a57242a
055575e
786e799
f44586c
e3c6596
d64df5f
34aaf2b
0b4000f
8a3126a
99b59fb
1b010a0
35c768b
a74c21e
4f57710
277236a
900fe5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| // Auto-generated by idb-client-generator — always regenerated | ||
| export const IDB_SCHEMA_HASH = "56b52d79"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| // Auto-generated by idb-client-generator — always regenerated | ||
| export const IDB_SCHEMA_HASH = "d1c83f66"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| export * from "./prisma-idb-client"; | ||
| export * from "./idb-interface"; | ||
| export * from "./idb-utils"; | ||
| export * from "./idb-schema-hash"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,14 @@ | ||
| /* eslint-disable @typescript-eslint/no-unused-vars */ | ||
| import { openDB } from "idb"; | ||
| import { openDB, deleteDB } from "idb"; | ||
| import type { IDBPDatabase, StoreNames, IDBPTransaction } from "idb"; | ||
| import type { Prisma } from "../../generated/prisma/client"; | ||
| import * as IDBUtils from "./idb-utils"; | ||
| import type { PrismaIDBSchema } from "./idb-interface"; | ||
| import { IDB_SCHEMA_HASH } from "./idb-schema-hash"; | ||
| import { createId } from "@paralleldrive/cuid2"; | ||
| import { v4 as uuidv4 } from "uuid"; | ||
| const IDB_VERSION = 1; | ||
| const DROP_DB_ON_SCHEMA_VERSION_MISMATCH = false; | ||
| export class PrismaIDBClient { | ||
| private static instance: PrismaIDBClient; | ||
| _db!: IDBPDatabase<PrismaIDBSchema>; | ||
|
|
@@ -51,6 +53,18 @@ export class PrismaIDBClient { | |
| if (!PrismaIDBClient.instance) { | ||
| const client = new PrismaIDBClient(); | ||
| await client.initialize(); | ||
| const storedHash = await client._db.get("_idb_meta", "schemaHash"); | ||
| if (storedHash !== undefined && storedHash !== IDB_SCHEMA_HASH) { | ||
| client._db.close(); | ||
| if (!DROP_DB_ON_SCHEMA_VERSION_MISMATCH) { | ||
| throw new Error( | ||
| `IDB schema mismatch: stored hash "${storedHash}" does not match expected "${IDB_SCHEMA_HASH}". Set dropDbOnSchemaVersionMismatch = true in your generator config to automatically reset the database.` | ||
| ); | ||
| } | ||
| await deleteDB("prisma-idb"); | ||
| return PrismaIDBClient.createClient(); | ||
| } | ||
| await client._db.put("_idb_meta", IDB_SCHEMA_HASH, "schemaHash"); | ||
|
Comment on lines
+56
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Inspect generated clients/templates for DB versioning and meta-store upgrade handling.
fd 'prisma-idb-client\.ts$' . -t f | while read -r file; do
echo "=== $file ==="
rg -n -C2 'const IDB_VERSION|openDB<|upgrade\(|oldVersion|_idb_meta|schemaHash' "$file"
doneRepository: prisma-idb/idb-client-generator Length of output: 2586 🏁 Script executed: # Get the full blocking() callback implementation and singleton handling
sed -n '105,120p' apps/usage/src/lib/prisma-idb/client/prisma-idb-client.tsRepository: prisma-idb/idb-client-generator Length of output: 841 🏁 Script executed: # Check for generator templates that produce this file
fd -t f 'prisma-idb-client' packages/generator/src --type fRepository: prisma-idb/idb-client-generator Length of output: 57 🏁 Script executed: # Verify if this is indeed a generated file by checking for generation markers
head -20 apps/usage/src/lib/prisma-idb/client/prisma-idb-client.tsRepository: prisma-idb/idb-client-generator Length of output: 881 🏁 Script executed: # Search for the generator template that produces prisma-idb-client.ts
fd -t f 'prisma-idb-client' packages/generator/srcRepository: prisma-idb/idb-client-generator Length of output: 57 🏁 Script executed: # Look for the template file by pattern
find packages/generator/src -name '*prisma-idb-client*' -o -name '*client.ts*' | head -20Repository: prisma-idb/idb-client-generator Length of output: 128 🏁 Script executed: # Check the generator directory structure
tree -L 3 packages/generator/srcRepository: prisma-idb/idb-client-generator Length of output: 1180 🏁 Script executed: # Inspect the generator template for prisma-idb-client
cat -n packages/generator/src/fileCreators/prisma-idb-client/create.ts | head -150Repository: prisma-idb/idb-client-generator Length of output: 5287 🏁 Script executed: # Search for upgrade and blocking callback in the template
rg -n -A 5 -B 2 'upgrade\(|blocking\(' packages/generator/src/fileCreators/prisma-idb-client/Repository: prisma-idb/idb-client-generator Length of output: 4279 🏁 Script executed: # Check for any version bump logic or migration handling in the generator
rg -n 'IDB_VERSION|oldVersion' packages/generator/src/Repository: prisma-idb/idb-client-generator Length of output: 686 🏁 Script executed: # Check the complete initialization and singleton caching logic
sed -n '40,75p' apps/usage/src/lib/prisma-idb/client/prisma-idb-client.tsRepository: prisma-idb/idb-client-generator Length of output: 1622 🏁 Script executed: # Verify the learning about generated code and confirm the fix location
head -5 packages/generator/src/fileCreators/prisma-idb-client/classes/PrismaIDBClient.tsRepository: prisma-idb/idb-client-generator Length of output: 358 Fix Lines 56–67 access Additionally, the singleton is cached (line 69) before Both issues originate in the generator template at
🤖 Prompt for AI Agents |
||
| PrismaIDBClient.instance = client; | ||
| } | ||
| return PrismaIDBClient.instance; | ||
|
|
@@ -64,7 +78,7 @@ export class PrismaIDBClient { | |
| return this.outboxEnabled && this.includedModels.has(modelName); | ||
| } | ||
| private async initialize() { | ||
| this._db = await openDB<PrismaIDBSchema>("prisma-idb", IDB_VERSION, { | ||
| const db = await openDB<PrismaIDBSchema>("prisma-idb", IDB_VERSION, { | ||
| upgrade(db) { | ||
| db.createObjectStore("User", { keyPath: ["id"] }); | ||
| db.createObjectStore("Group", { keyPath: ["id"] }); | ||
|
|
@@ -86,8 +100,13 @@ export class PrismaIDBClient { | |
| const ModelWithUniqueAttributesStore = db.createObjectStore("ModelWithUniqueAttributes", { keyPath: ["id"] }); | ||
| ModelWithUniqueAttributesStore.createIndex("codeIndex", ["code"], { unique: true }); | ||
| db.createObjectStore("Todo", { keyPath: ["id"] }); | ||
| db.createObjectStore("_idb_meta"); | ||
| }, | ||
| blocking() { | ||
| db.close(); | ||
| }, | ||
| }); | ||
| this._db = db; | ||
|
Comment on lines
+105
to
+109
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify whether any close/blocking path clears the cached singleton.
fd 'prisma-idb-client\.ts$' . -t f | while read -r file; do
echo "=== $file ==="
rg -n -C3 'private static instance|createClient\(|blocking\(|close\(|instance\s*=' "$file"
doneRepository: prisma-idb/idb-client-generator Length of output: 3804 Clear the cached singleton instance when The Suggested fix- private static instance: PrismaIDBClient;
+ private static instance: PrismaIDBClient | undefined;
...
blocking() {
db.close();
+ if (PrismaIDBClient.instance?._db === db) {
+ PrismaIDBClient.instance = undefined;
+ }
},🤖 Prompt for AI Agents |
||
| this.user = new UserIDBClass(this, ["id"]); | ||
| this.group = new GroupIDBClass(this, ["id"]); | ||
| this.userGroup = new UserGroupIDBClass(this, ["groupId", "userId"]); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import CodeBlockWriter from "code-block-writer"; | ||
|
|
||
| /** | ||
| * Generate the idb-schema-hash.ts file content. | ||
| * This file is always regenerated on every `prisma generate` run. | ||
| */ | ||
| export function createSchemaHashFile(writer: CodeBlockWriter, hash: string) { | ||
| writer.writeLine(`// Auto-generated by idb-client-generator — always regenerated`); | ||
| writer.writeLine(`export const IDB_SCHEMA_HASH = ${JSON.stringify(hash)};`); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,20 @@ | ||
| import type CodeBlockWriter from "code-block-writer"; | ||
|
|
||
| export function createClientIndexFile(writer: CodeBlockWriter, outboxSync: boolean) { | ||
| export function createClientIndexFile( | ||
| writer: CodeBlockWriter, | ||
| options: { | ||
| outboxSync: boolean; | ||
| hasMigrations?: boolean; | ||
| } | ||
| ) { | ||
| const { outboxSync, hasMigrations = false } = options; | ||
| writer.writeLine(`export * from './prisma-idb-client';`); | ||
| writer.writeLine(`export * from './idb-interface';`); | ||
| writer.writeLine(`export * from './idb-utils';`); | ||
| if (outboxSync) { | ||
| writer.writeLine(`export * from './apply-pull';`); | ||
| } | ||
| if (hasMigrations) { | ||
| writer.writeLine(`export * from './idb-schema-hash';`); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: prisma-idb/idb-client-generator
Length of output: 5112
🏁 Script executed:
Repository: prisma-idb/idb-client-generator
Length of output: 3503
🏁 Script executed:
Repository: prisma-idb/idb-client-generator
Length of output: 159
🏁 Script executed:
Repository: prisma-idb/idb-client-generator
Length of output: 403
Fix IndexedDB schema upgrade path: bump version when introducing
_idb_metastore.The generated code adds
_idb_metastore in theupgrade()callback (line 464) but uses the legacy path with hardcodedIDB_VERSION = 1(line 19). Existing users with a v1 database will not trigger the upgrade callback, so_idb_metais never created. The subsequent schema-drift check at line 57 (await client._db.get("_idb_meta", "schemaHash")) fails instead of detecting drift.The generator has two code paths: a migration-based path using
CURRENT_VERSION(when migration info is available) and a legacy path using hardcodedIDB_VERSION = 1. The generated example uses the legacy path. When adding new object stores, ensure the version is incremented in the generator's version declaration logic, or migrate to the migration-based upgrade callback inpackages/generator/src/fileCreators/prisma-idb-client/classes/PrismaIDBClient.ts.🤖 Prompt for AI Agents