@smthrs/journal 1.0.0-rc.3 → 1.0.0-rc.5
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/dist/cjs/JournalGeneration.d.ts.map +1 -1
- package/dist/cjs/JournalGeneration.js +2 -1
- package/dist/cjs/JournalGeneration.js.map +2 -2
- package/dist/esm/JournalGeneration.d.ts.map +1 -1
- package/dist/esm/JournalGeneration.js +7 -1
- package/dist/esm/JournalGeneration.js.map +1 -1
- package/package.json +3 -3
- package/src/JournalGeneration.ts +7 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JournalGeneration.d.ts","sourceRoot":"","sources":["../../src/JournalGeneration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"JournalGeneration.d.ts","sourceRoot":"","sources":["../../src/JournalGeneration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,2FAqBrB,CAAA;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,mFAgBtE,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,GAAI,QAAQ,aAAa,CAAC,MAAM,CAAC,oDAMhD,CAAA"}
|
|
@@ -39,13 +39,14 @@ var SqlClient = __toESM(require("effect/unstable/sql/SqlClient"), 1);
|
|
|
39
39
|
const initialize = Effect.gen(function* () {
|
|
40
40
|
const sql = yield* SqlClient.SqlClient;
|
|
41
41
|
if (Dialect.isReadOnly(sql)) return;
|
|
42
|
-
|
|
42
|
+
const create = sql`
|
|
43
43
|
CREATE TABLE IF NOT EXISTS flows_journal_generations (
|
|
44
44
|
run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),
|
|
45
45
|
generation ${Dialect.integer(sql)} NOT NULL CHECK (${Dialect.isInteger(sql, sql`generation`)} AND generation > 0 AND generation <= 9007199254740991),
|
|
46
46
|
after_seq ${Dialect.integer(sql)} NOT NULL CHECK (${Dialect.isInteger(sql, sql`after_seq`)} AND after_seq >= -1 AND after_seq <= 9007199254740991)
|
|
47
47
|
)
|
|
48
48
|
`;
|
|
49
|
+
yield* sql.onDialectOrElse({ pg: () => sql.withTransaction(create), orElse: () => create });
|
|
49
50
|
});
|
|
50
51
|
const journals = /* @__PURE__ */ new WeakMap();
|
|
51
52
|
const onTruncate = (forget2) => Effect.gen(function* () {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/JournalGeneration.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Durable generations distinguish histories that reuse journal sequences.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport * as Effect from \"effect/Effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\n\n/**\n * Installs the generation table idempotently. Both the SQL journal and time\n * travel initialize it, including databases whose migration ladder already\n * passed the journal's reserved block. A read-only client installs nothing.\n *\n * @category migrations\n * @since 1.0.0-rc.0\n */\nexport const initialize = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n // A read-only observer reads the schema it finds and installs nothing.\n if (Dialect.isReadOnly(sql)) return\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,cAAyB;AACzB,aAAwB;AACxB,gBAA2B;AAUpB,MAAM,aAAa,OAAO,IAAI,aAAY;AAC/C,QAAM,MAAM,OAAO,UAAU;AAE7B,MAAI,QAAQ,WAAW,GAAG,EAAG;AAC7B,
|
|
4
|
+
"sourcesContent": ["/**\n * Durable generations distinguish histories that reuse journal sequences.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport * as Effect from \"effect/Effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\n\n/**\n * Installs the generation table idempotently. Both the SQL journal and time\n * travel initialize it, including databases whose migration ladder already\n * passed the journal's reserved block. A read-only client installs nothing.\n *\n * @category migrations\n * @since 1.0.0-rc.0\n */\nexport const initialize = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n // A read-only observer reads the schema it finds and installs nothing.\n if (Dialect.isReadOnly(sql)) return\n const create = sql`\n CREATE TABLE IF NOT EXISTS flows_journal_generations (\n run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),\n generation ${Dialect.integer(sql)} NOT NULL CHECK (${\n Dialect.isInteger(sql, sql`generation`)\n } AND generation > 0 AND generation <= 9007199254740991),\n after_seq ${Dialect.integer(sql)} NOT NULL CHECK (${\n Dialect.isInteger(sql, sql`after_seq`)\n } AND after_seq >= -1 AND after_seq <= 9007199254740991)\n )\n `\n // The journal layer and time travel's migration both run this, side by side\n // on a host that builds them together. PostgreSQL serializes only what opens\n // a transaction, which takes the schema's writer lock first: two bare\n // CREATE TABLE IF NOT EXISTS statements race in the catalog, and the loser\n // fails on `pg_type_typname_nsp_index`.\n yield* sql.onDialectOrElse({ pg: () => sql.withTransaction(create), orElse: () => create })\n})\n\nconst journals = new WeakMap<SqlClient.SqlClient, Set<(runIds: ReadonlyArray<string>) => void>>()\n\n/**\n * Registers a live journal's cache invalidation until its scope closes.\n * Multiple journals over the same SQL client must observe the same rewind.\n *\n * @category lifecycle\n * @since 1.0.0-rc.0\n */\nexport const onTruncate = (forget: (runIds: ReadonlyArray<string>) => void) =>\n Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n let listeners = journals.get(sql)\n if (listeners === undefined) {\n listeners = new Set()\n journals.set(sql, listeners)\n }\n const registered = listeners\n yield* Effect.acquireRelease(\n Effect.sync(() => registered.add(forget)),\n () =>\n Effect.sync(() => {\n registered.delete(forget)\n })\n )\n })\n\n/**\n * Forgets cached identities and allocation floors after a committed truncation.\n * The rewinder must quiesce producers and flush pending admissions first.\n * Database rows remain authoritative; this operation changes no durable data.\n *\n * @category lifecycle\n * @since 1.0.0-rc.0\n */\nexport const forget = (runIds: ReadonlyArray<string>) =>\n Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n yield* Effect.sync(() => {\n for (const invalidate of journals.get(sql) ?? []) invalidate(runIds)\n })\n })\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,cAAyB;AACzB,aAAwB;AACxB,gBAA2B;AAUpB,MAAM,aAAa,OAAO,IAAI,aAAY;AAC/C,QAAM,MAAM,OAAO,UAAU;AAE7B,MAAI,QAAQ,WAAW,GAAG,EAAG;AAC7B,QAAM,SAAS;AAAA;AAAA;AAAA,mBAGE,QAAQ,QAAQ,GAAG,CAAC,oBACnC,QAAQ,UAAU,KAAK,eAAe,CACxC;AAAA,kBACgB,QAAQ,QAAQ,GAAG,CAAC,oBAClC,QAAQ,UAAU,KAAK,cAAc,CACvC;AAAA;AAAA;AAQA,SAAO,IAAI,gBAAgB,EAAE,IAAI,MAAM,IAAI,gBAAgB,MAAM,GAAG,QAAQ,MAAM,OAAO,CAAC;AAC5F,CAAC;AAED,MAAM,WAAW,oBAAI,QAA2E;AASzF,MAAM,aAAa,CAACA,YACzB,OAAO,IAAI,aAAY;AACrB,QAAM,MAAM,OAAO,UAAU;AAC7B,MAAI,YAAY,SAAS,IAAI,GAAG;AAChC,MAAI,cAAc,QAAW;AAC3B,gBAAY,oBAAI,IAAI;AACpB,aAAS,IAAI,KAAK,SAAS;AAAA,EAC7B;AACA,QAAM,aAAa;AACnB,SAAO,OAAO;AAAA,IACZ,OAAO,KAAK,MAAM,WAAW,IAAIA,OAAM,CAAC;AAAA,IACxC,MACE,OAAO,KAAK,MAAM;AAChB,iBAAW,OAAOA,OAAM;AAAA,IAC1B,CAAC;AAAA,EACL;AACF,CAAC;AAUI,MAAM,SAAS,CAAC,WACrB,OAAO,IAAI,aAAY;AACrB,QAAM,MAAM,OAAO,UAAU;AAC7B,SAAO,OAAO,KAAK,MAAM;AACvB,eAAW,cAAc,SAAS,IAAI,GAAG,KAAK,CAAC,EAAG,YAAW,MAAM;AAAA,EACrE,CAAC;AACH,CAAC;",
|
|
6
6
|
"names": ["forget"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JournalGeneration.d.ts","sourceRoot":"","sources":["../../src/JournalGeneration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"JournalGeneration.d.ts","sourceRoot":"","sources":["../../src/JournalGeneration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,2FAqBrB,CAAA;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,mFAgBtE,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,GAAI,QAAQ,aAAa,CAAC,MAAM,CAAC,oDAMhD,CAAA"}
|
|
@@ -19,13 +19,19 @@ export const initialize = Effect.gen(function* () {
|
|
|
19
19
|
// A read-only observer reads the schema it finds and installs nothing.
|
|
20
20
|
if (Dialect.isReadOnly(sql))
|
|
21
21
|
return;
|
|
22
|
-
|
|
22
|
+
const create = sql `
|
|
23
23
|
CREATE TABLE IF NOT EXISTS flows_journal_generations (
|
|
24
24
|
run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),
|
|
25
25
|
generation ${Dialect.integer(sql)} NOT NULL CHECK (${Dialect.isInteger(sql, sql `generation`)} AND generation > 0 AND generation <= 9007199254740991),
|
|
26
26
|
after_seq ${Dialect.integer(sql)} NOT NULL CHECK (${Dialect.isInteger(sql, sql `after_seq`)} AND after_seq >= -1 AND after_seq <= 9007199254740991)
|
|
27
27
|
)
|
|
28
28
|
`;
|
|
29
|
+
// The journal layer and time travel's migration both run this, side by side
|
|
30
|
+
// on a host that builds them together. PostgreSQL serializes only what opens
|
|
31
|
+
// a transaction, which takes the schema's writer lock first: two bare
|
|
32
|
+
// CREATE TABLE IF NOT EXISTS statements race in the catalog, and the loser
|
|
33
|
+
// fails on `pg_type_typname_nsp_index`.
|
|
34
|
+
yield* sql.onDialectOrElse({ pg: () => sql.withTransaction(create), orElse: () => create });
|
|
29
35
|
});
|
|
30
36
|
const journals = new WeakMap();
|
|
31
37
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JournalGeneration.js","sourceRoot":"","sources":["../../src/JournalGeneration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAA;AACnD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAA;IACtC,uEAAuE;IACvE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAM;IACnC,
|
|
1
|
+
{"version":3,"file":"JournalGeneration.js","sourceRoot":"","sources":["../../src/JournalGeneration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAA;AACnD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAA;IACtC,uEAAuE;IACvE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAM;IACnC,MAAM,MAAM,GAAG,GAAG,CAAA;;;mBAGD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,oBACnC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAA,YAAY,CACxC;kBACgB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,oBAClC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAA,WAAW,CACvC;;GAEC,CAAA;IACD,4EAA4E;IAC5E,6EAA6E;IAC7E,sEAAsE;IACtE,2EAA2E;IAC3E,wCAAwC;IACxC,KAAK,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;AAC7F,CAAC,CAAC,CAAA;AAEF,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAqE,CAAA;AAEjG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAA+C,EAAE,EAAE,CAC5E,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAA;IACtC,IAAI,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,SAAS,GAAG,IAAI,GAAG,EAAE,CAAA;QACrB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;IAC9B,CAAC;IACD,MAAM,UAAU,GAAG,SAAS,CAAA;IAC5B,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACzC,GAAG,EAAE,CACH,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACf,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC3B,CAAC,CAAC,CACL,CAAA;AACH,CAAC,CAAC,CAAA;AAEJ;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAA6B,EAAE,EAAE,CACtD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAA;IACtC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;QACtB,KAAK,MAAM,UAAU,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IACtE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["/**\n * Durable generations distinguish histories that reuse journal sequences.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport * as Effect from \"effect/Effect\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\n\n/**\n * Installs the generation table idempotently. Both the SQL journal and time\n * travel initialize it, including databases whose migration ladder already\n * passed the journal's reserved block. A read-only client installs nothing.\n *\n * @category migrations\n * @since 1.0.0-rc.0\n */\nexport const initialize = Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n // A read-only observer reads the schema it finds and installs nothing.\n if (Dialect.isReadOnly(sql)) return\n const create = sql`\n CREATE TABLE IF NOT EXISTS flows_journal_generations (\n run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),\n generation ${Dialect.integer(sql)} NOT NULL CHECK (${\n Dialect.isInteger(sql, sql`generation`)\n } AND generation > 0 AND generation <= 9007199254740991),\n after_seq ${Dialect.integer(sql)} NOT NULL CHECK (${\n Dialect.isInteger(sql, sql`after_seq`)\n } AND after_seq >= -1 AND after_seq <= 9007199254740991)\n )\n `\n // The journal layer and time travel's migration both run this, side by side\n // on a host that builds them together. PostgreSQL serializes only what opens\n // a transaction, which takes the schema's writer lock first: two bare\n // CREATE TABLE IF NOT EXISTS statements race in the catalog, and the loser\n // fails on `pg_type_typname_nsp_index`.\n yield* sql.onDialectOrElse({ pg: () => sql.withTransaction(create), orElse: () => create })\n})\n\nconst journals = new WeakMap<SqlClient.SqlClient, Set<(runIds: ReadonlyArray<string>) => void>>()\n\n/**\n * Registers a live journal's cache invalidation until its scope closes.\n * Multiple journals over the same SQL client must observe the same rewind.\n *\n * @category lifecycle\n * @since 1.0.0-rc.0\n */\nexport const onTruncate = (forget: (runIds: ReadonlyArray<string>) => void) =>\n Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n let listeners = journals.get(sql)\n if (listeners === undefined) {\n listeners = new Set()\n journals.set(sql, listeners)\n }\n const registered = listeners\n yield* Effect.acquireRelease(\n Effect.sync(() => registered.add(forget)),\n () =>\n Effect.sync(() => {\n registered.delete(forget)\n })\n )\n })\n\n/**\n * Forgets cached identities and allocation floors after a committed truncation.\n * The rewinder must quiesce producers and flush pending admissions first.\n * Database rows remain authoritative; this operation changes no durable data.\n *\n * @category lifecycle\n * @since 1.0.0-rc.0\n */\nexport const forget = (runIds: ReadonlyArray<string>) =>\n Effect.gen(function*() {\n const sql = yield* SqlClient.SqlClient\n yield* Effect.sync(() => {\n for (const invalidate of journals.get(sql) ?? []) invalidate(runIds)\n })\n })\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smthrs/journal",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.5",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"smthrs": {
|
|
7
7
|
"group": "engine"
|
|
@@ -226,14 +226,14 @@
|
|
|
226
226
|
"tag": "next"
|
|
227
227
|
},
|
|
228
228
|
"dependencies": {
|
|
229
|
-
"@smthrs/database": "1.0.0-rc.
|
|
229
|
+
"@smthrs/database": "1.0.0-rc.5"
|
|
230
230
|
},
|
|
231
231
|
"devDependencies": {
|
|
232
232
|
"@effect/language-service": "0.87.2",
|
|
233
233
|
"@effect/sql-sqlite-node": "4.0.0-rc.115",
|
|
234
234
|
"@effect/vitest": "4.0.0-rc.115",
|
|
235
235
|
"@eslint/js": "9.39.5",
|
|
236
|
-
"@smthrs/flow": "1.0.0-rc.
|
|
236
|
+
"@smthrs/flow": "1.0.0-rc.5",
|
|
237
237
|
"@types/node": "26.4.1",
|
|
238
238
|
"@vitest/coverage-v8": "5.0.0",
|
|
239
239
|
"dprint": "0.57.1",
|
package/src/JournalGeneration.ts
CHANGED
|
@@ -20,7 +20,7 @@ export const initialize = Effect.gen(function*() {
|
|
|
20
20
|
const sql = yield* SqlClient.SqlClient
|
|
21
21
|
// A read-only observer reads the schema it finds and installs nothing.
|
|
22
22
|
if (Dialect.isReadOnly(sql)) return
|
|
23
|
-
|
|
23
|
+
const create = sql`
|
|
24
24
|
CREATE TABLE IF NOT EXISTS flows_journal_generations (
|
|
25
25
|
run_id TEXT PRIMARY KEY NOT NULL CHECK (length(run_id) > 0),
|
|
26
26
|
generation ${Dialect.integer(sql)} NOT NULL CHECK (${
|
|
@@ -31,6 +31,12 @@ export const initialize = Effect.gen(function*() {
|
|
|
31
31
|
} AND after_seq >= -1 AND after_seq <= 9007199254740991)
|
|
32
32
|
)
|
|
33
33
|
`
|
|
34
|
+
// The journal layer and time travel's migration both run this, side by side
|
|
35
|
+
// on a host that builds them together. PostgreSQL serializes only what opens
|
|
36
|
+
// a transaction, which takes the schema's writer lock first: two bare
|
|
37
|
+
// CREATE TABLE IF NOT EXISTS statements race in the catalog, and the loser
|
|
38
|
+
// fails on `pg_type_typname_nsp_index`.
|
|
39
|
+
yield* sql.onDialectOrElse({ pg: () => sql.withTransaction(create), orElse: () => create })
|
|
34
40
|
})
|
|
35
41
|
|
|
36
42
|
const journals = new WeakMap<SqlClient.SqlClient, Set<(runIds: ReadonlyArray<string>) => void>>()
|