@trylight/app 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/db/cli.js +9 -6
- package/dist/server/env.d.ts +1 -0
- package/dist/server/env.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,6 +46,11 @@ sign-in; a stranger to a public app only reads what members kept.
|
|
|
46
46
|
|
|
47
47
|
## Schema sync
|
|
48
48
|
|
|
49
|
+
`light-db sync` and `migrate` connect with `DATABASE_URL_UNPOOLED`, the
|
|
50
|
+
database's direct address, and refuse to run without it: they serialise on
|
|
51
|
+
Postgres advisory locks, which a transaction pooler (the app's `DATABASE_URL`
|
|
52
|
+
on Neon) keeps on a pooled connection after the process exits.
|
|
53
|
+
|
|
49
54
|
`plan()` diffs `db/schema` against the newest migration snapshot with
|
|
50
55
|
drizzle-kit's API, removals first and additions second, so drizzle-kit never
|
|
51
56
|
has to ask whether a column was renamed (it can't without a terminal).
|
package/dist/db/cli.js
CHANGED
|
@@ -24,7 +24,9 @@ const SYNC_LOCK_KEY = 4_815_162_343;
|
|
|
24
24
|
/** Exit code of a migrate whose migrations committed but whose change triggers didn't go on. */
|
|
25
25
|
const APPLIED_UNTRACKED = 2;
|
|
26
26
|
// pg_advisory_lock waits for the one before it; a process that dies releases it.
|
|
27
|
-
|
|
27
|
+
// Only on a direct connection: behind a transaction pooler the lock stays on a
|
|
28
|
+
// pooled server connection after the process exits, and every later sync waits.
|
|
29
|
+
const connect = (onnotice = () => undefined) => postgres(unpooledDatabaseUrl(), { max: 1, onnotice });
|
|
28
30
|
const root = process.cwd();
|
|
29
31
|
const envFile = join(root, ".env.local");
|
|
30
32
|
if (existsSync(envFile))
|
|
@@ -33,11 +35,12 @@ const [command] = process.argv.slice(2);
|
|
|
33
35
|
async function loadSchema() {
|
|
34
36
|
return import(pathToFileURL(join(root, SCHEMA_ENTRY)).href);
|
|
35
37
|
}
|
|
36
|
-
function
|
|
37
|
-
const {
|
|
38
|
-
if (
|
|
39
|
-
throw new Error("
|
|
40
|
-
|
|
38
|
+
function unpooledDatabaseUrl() {
|
|
39
|
+
const { unpooledDatabaseUrl } = env();
|
|
40
|
+
if (unpooledDatabaseUrl === undefined) {
|
|
41
|
+
throw new Error("DATABASE_URL_UNPOOLED is not set: light-db sync and migrate need the database's direct (unpooled) connection.");
|
|
42
|
+
}
|
|
43
|
+
return unpooledDatabaseUrl;
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Makes the database match `db/schema`, whatever the change does to the rows
|
package/dist/server/env.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Read when asked, not at import: a build imports this without a runtime env. */
|
|
2
2
|
export declare function env(): {
|
|
3
3
|
databaseUrl: string | undefined;
|
|
4
|
+
unpooledDatabaseUrl: string | undefined;
|
|
4
5
|
/** Sign-in needs Plaza, this app's id in it, and a database for sessions. */
|
|
5
6
|
configured: boolean;
|
|
6
7
|
/**
|
package/dist/server/env.js
CHANGED
|
@@ -4,12 +4,15 @@ import { z } from "zod/v4";
|
|
|
4
4
|
const serverEnv = z
|
|
5
5
|
.object({
|
|
6
6
|
DATABASE_URL: z.string().min(1).optional(),
|
|
7
|
+
/** The same database without a pooler: schema changes and their locks need a session. */
|
|
8
|
+
DATABASE_URL_UNPOOLED: z.string().min(1).optional(),
|
|
7
9
|
MII_PLAZA_URL: z.url().optional(),
|
|
8
10
|
MII_APP_ID: z.string().min(1).optional(),
|
|
9
11
|
NODE_ENV: z.string().optional()
|
|
10
12
|
})
|
|
11
13
|
.transform((env) => ({
|
|
12
14
|
databaseUrl: env.DATABASE_URL,
|
|
15
|
+
unpooledDatabaseUrl: env.DATABASE_URL_UNPOOLED,
|
|
13
16
|
/** Sign-in needs Plaza, this app's id in it, and a database for sessions. */
|
|
14
17
|
configured: Boolean(env.MII_PLAZA_URL && env.MII_APP_ID && env.DATABASE_URL),
|
|
15
18
|
/**
|
package/package.json
CHANGED