@supalive/core 1.2.0 → 1.3.0

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.
Files changed (78) hide show
  1. package/README.md +2 -2
  2. package/dist/db-ClCicssQ.js.map +1 -1
  3. package/dist/index-4Nis7Wnk.d.ts +1973 -0
  4. package/dist/index-4Nis7Wnk.d.ts.map +1 -0
  5. package/dist/index-Ca58CrWX.d.ts +2103 -0
  6. package/dist/index-Ca58CrWX.d.ts.map +1 -0
  7. package/dist/index-DDK9ZIYb.d.ts +2103 -0
  8. package/dist/index-DDK9ZIYb.d.ts.map +1 -0
  9. package/dist/{index-E1_1iRI1.d.ts → index-DJYvJYR4.d.ts} +6 -5
  10. package/dist/index-DJYvJYR4.d.ts.map +1 -0
  11. package/dist/index-Oz3eyddt.d.ts +1974 -0
  12. package/dist/index-Oz3eyddt.d.ts.map +1 -0
  13. package/dist/{mysql-BmkLy5oY.d.ts → mysql-53W9lRh9.d.ts} +2 -2
  14. package/dist/{mysql-BmkLy5oY.d.ts.map → mysql-53W9lRh9.d.ts.map} +1 -1
  15. package/dist/{mysql-Ca1B_0k_.js → mysql-C0mysDQ_.js} +1 -2
  16. package/dist/mysql-C0mysDQ_.js.map +1 -0
  17. package/dist/mysql-D0pFocWL.d.ts +109 -0
  18. package/dist/mysql-D0pFocWL.d.ts.map +1 -0
  19. package/dist/mysql-DF-dZHi7.d.ts +109 -0
  20. package/dist/mysql-DF-dZHi7.d.ts.map +1 -0
  21. package/dist/mysql-QWBVXBjM.d.ts +109 -0
  22. package/dist/mysql-QWBVXBjM.d.ts.map +1 -0
  23. package/dist/mysql-fECZYP_m.d.ts +109 -0
  24. package/dist/mysql-fECZYP_m.d.ts.map +1 -0
  25. package/dist/object-storage-4t7JvpuK.d.ts +67 -0
  26. package/dist/object-storage-4t7JvpuK.d.ts.map +1 -0
  27. package/dist/{postgres-v2ctNE6o.d.ts → postgres-7d6R9P7w.d.ts} +2 -2
  28. package/dist/{postgres-v2ctNE6o.d.ts.map → postgres-7d6R9P7w.d.ts.map} +1 -1
  29. package/dist/postgres-C1qWlB--.d.ts +113 -0
  30. package/dist/postgres-C1qWlB--.d.ts.map +1 -0
  31. package/dist/postgres-CKtJ62S4.d.ts +113 -0
  32. package/dist/postgres-CKtJ62S4.d.ts.map +1 -0
  33. package/dist/postgres-DdqpjjYF.d.ts +113 -0
  34. package/dist/postgres-DdqpjjYF.d.ts.map +1 -0
  35. package/dist/postgres-DhCgxVOr.d.ts +113 -0
  36. package/dist/postgres-DhCgxVOr.d.ts.map +1 -0
  37. package/dist/{postgres-CHDY1HPf.js → postgres-SvdXfb0w.js} +2 -6
  38. package/dist/postgres-SvdXfb0w.js.map +1 -0
  39. package/dist/procedure-Ze1GE-N9.js.map +1 -1
  40. package/dist/src/client/index.d.ts +1 -1
  41. package/dist/src/client/index.js +7 -1
  42. package/dist/src/client/index.js.map +1 -1
  43. package/dist/src/exports/mysql.d.ts +1 -1
  44. package/dist/src/exports/mysql.js +1 -1
  45. package/dist/src/exports/postgres.d.ts +1 -1
  46. package/dist/src/exports/postgres.js +1 -1
  47. package/dist/src/exports/procedure.d.ts +1 -1
  48. package/dist/src/exports/schema-sql.d.ts +16 -15
  49. package/dist/src/exports/schema-sql.d.ts.map +1 -1
  50. package/dist/src/exports/schema-sql.js +15 -3
  51. package/dist/src/exports/schema-sql.js.map +1 -1
  52. package/dist/src/exports/server.d.ts +22 -19
  53. package/dist/src/exports/server.d.ts.map +1 -1
  54. package/dist/src/exports/server.js +15 -8
  55. package/dist/src/exports/server.js.map +1 -1
  56. package/dist/src/exports/storage.d.ts +56 -0
  57. package/dist/src/exports/storage.d.ts.map +1 -0
  58. package/dist/src/exports/storage.js +62 -0
  59. package/dist/src/exports/storage.js.map +1 -0
  60. package/dist/src/exports/subscription-manager-worker-entry.js +1 -1
  61. package/dist/src/exports/types.d.ts +2 -2
  62. package/dist/{subscription-worker-CAf6MUta.js → subscription-worker-B2XtjFWY.js} +16 -15
  63. package/dist/subscription-worker-B2XtjFWY.js.map +1 -0
  64. package/dist/types_server-AN8OiTEx.d.ts +302 -0
  65. package/dist/types_server-AN8OiTEx.d.ts.map +1 -0
  66. package/dist/types_server-C9owgeSs.d.ts +302 -0
  67. package/dist/types_server-C9owgeSs.d.ts.map +1 -0
  68. package/dist/types_server-D5JDD_Dp.d.ts +430 -0
  69. package/dist/types_server-D5JDD_Dp.d.ts.map +1 -0
  70. package/dist/types_server-Dxx_Xx86.d.ts +430 -0
  71. package/dist/types_server-Dxx_Xx86.d.ts.map +1 -0
  72. package/dist/{types_server-CzAufcee.d.ts → types_server-wW3ZgE7l.d.ts} +2 -2
  73. package/dist/{types_server-CzAufcee.d.ts.map → types_server-wW3ZgE7l.d.ts.map} +1 -1
  74. package/package.json +15 -1
  75. package/dist/index-E1_1iRI1.d.ts.map +0 -1
  76. package/dist/mysql-Ca1B_0k_.js.map +0 -1
  77. package/dist/postgres-CHDY1HPf.js.map +0 -1
  78. package/dist/subscription-worker-CAf6MUta.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Cn as schemaRegistry, En as trackSchema, yn as SchemaDefinition } from "../../index-E1_1iRI1.js";
1
+ import { In as trackSchema, Nn as schemaRegistry, kn as SchemaDefinition } from "../../index-DDK9ZIYb.js";
2
2
 
3
3
  //#region src/db/schema-sql.d.ts
4
4
  type SqlDialect = "postgres" | "mysql";
@@ -21,28 +21,29 @@ interface GenerateSchemaSqlOptions {
21
21
  }
22
22
  declare function generateSchemaSql(schemas?: Map<string, SchemaDefinition<string, any, any>> | SchemaDefinition<string, any, any>[], options?: GenerateSchemaSqlOptions): string;
23
23
  //#endregion
24
- //#region src/db/core-tables.d.ts
24
+ //#region src/db/core_tables.d.ts
25
25
  /**
26
- * DDL for the core, framework-owned tables that every Supalive database must
27
- * have alongside the user's own tables:
26
+ * DDL for the core, framework-owned database objects that every Supalive
27
+ * database must have alongside the user's own tables:
28
28
  *
29
- * - `commit_logs` — the append-only OCC change log (+ its lookup indexes).
30
- * - `metadata` — the small key/value table holding the OCC watermarks
31
- * (`latest_committed_ts`, `min_retained_ts`) and the core
32
- * schema version (`core_version`).
29
+ * - `commit_logs` — the append-only OCC change log (+ its lookup indexes).
30
+ * - `metadata` — the small key/value table holding the OCC watermarks
31
+ * (`latest_committed_ts`, `min_retained_ts`) and the
32
+ * core schema version (`core_version`).
33
+ * - `global_commit_ts` — the monotonic commit-timestamp source: a SEQUENCE on
34
+ * Postgres, a single-row `BIGINT` counter table on MySQL.
33
35
  *
34
- * These used to live in each `Database.migrationSql` array and were applied
35
- * ad-hoc. They now belong in the generated `schema.sql` (see
36
- * {@link generateSchemaSql}, which prepends them by default) so a single
36
+ * These are all pure schema (DDL), so they belong in the generated `schema.sql`
37
+ * (see {@link generateSchemaSql}, which prepends them by default) and get
38
+ * migrated ahead of runtime by your normal migration pipeline — a single
37
39
  * generated file fully describes the database.
38
40
  *
39
- * Note: this module intentionally covers ONLY tables + indexes. Non-table
40
- * bootstrap (the `global_commit_ts` sequence, the MySQL `sequence` table, and
41
- * the metadata seed rows) is handled at runtime by `initCore` — see
41
+ * Data seeding (the `metadata` rows and the MySQL counter's initial `0`) and
42
+ * any runtime-only schema changes live in `initCore` see
42
43
  * {@link file://./init_db.ts}.
43
44
  */
44
45
  interface CoreTablesSqlOptions {
45
- /** Emit `IF NOT EXISTS` on `CREATE TABLE`/`CREATE INDEX`. Default true. */
46
+ /** Emit `IF NOT EXISTS` on `CREATE TABLE`/`CREATE INDEX`/`CREATE SEQUENCE`. Default true. */
46
47
  ifNotExists?: boolean;
47
48
  }
48
49
  declare function coreTablesSql(dialect?: SqlDialect, options?: CoreTablesSqlOptions): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"schema-sql.d.ts","names":[],"sources":["../../../src/db/schema-sql.ts","../../../src/db/core-tables.ts"],"mappings":";;;KAMY,UAAA;AAAA,UAsKK,0BAAA;EACb,OAAA,GAAU,UAAU;EACpB,WAAA;AAAA;AAAA,iBAGY,mBAAA,CACZ,MAAA,EAAQ,gBAAA,oBACR,OAAA,GAAU,0BAA0B;AAAA,UAoFvB,wBAAA;EACb,OAAA,GAAU,UAAU;EACpB,WAAA;EACA,MAAA;EAzF+B;;;;;;EAgG/B,iBAAA;AAAA;AAAA,iBAGY,iBAAA,CACZ,OAAA,GAAU,GAAA,SAAY,gBAAA,sBAAsC,gBAAA,sBAC5D,OAAA,GAAU,wBAAA;;;;;AAhRd;;;;AAAsB;AAsKtB;;;;;;;;AAEe;AAGf;;;UC3JiB,oBAAA;ED4JL;EC1JR,WAAW;AAAA;AAAA,iBAGC,aAAA,CACZ,OAAA,GAAS,UAAA,EACT,OAAA,GAAU,oBAAoB"}
1
+ {"version":3,"file":"schema-sql.d.ts","names":[],"sources":["../../../src/db/schema-sql.ts","../../../src/db/core_tables.ts"],"mappings":";;;KAMY,UAAA;AAAA,UA8KK,0BAAA;EACb,OAAA,GAAU,UAAU;EACpB,WAAA;AAAA;AAAA,iBAGY,mBAAA,CACZ,MAAA,EAAQ,gBAAA,oBACR,OAAA,GAAU,0BAA0B;AAAA,UAoFvB,wBAAA;EACb,OAAA,GAAU,UAAU;EACpB,WAAA;EACA,MAAA;EAzF+B;;;;;;EAgG/B,iBAAA;AAAA;AAAA,iBAGY,iBAAA,CACZ,OAAA,GAAU,GAAA,SAAY,gBAAA,sBAAsC,gBAAA,sBAC5D,OAAA,GAAU,wBAAA;;;;;AAxRd;;;;AAAsB;AA8KtB;;;;;;;;AAEe;AAGf;;;;UClKiB,oBAAA;EDmKb;ECjKA,WAAW;AAAA;AAAA,iBAGC,aAAA,CACZ,OAAA,GAAS,UAAA,EACT,OAAA,GAAU,oBAAoB"}
@@ -1,13 +1,18 @@
1
1
  import { r as unwrapZodType } from "../../codec-BHAmGEIQ.js";
2
2
  import { o as trackSchema, r as schemaRegistry } from "../../schema-Dd7u0A1L.js";
3
3
  import { z as z$1 } from "zod";
4
- //#region src/db/core-tables.ts
4
+ //#region src/db/core_tables.ts
5
5
  function coreTablesSql(dialect = "postgres", options) {
6
6
  const ifNotExists = options?.ifNotExists ?? true;
7
7
  const t = ifNotExists ? "IF NOT EXISTS " : "";
8
8
  const i = ifNotExists ? "IF NOT EXISTS " : "";
9
- if (dialect === "mysql") return [`CREATE TABLE ${t}commit_logs (\n id BINARY(16) NOT NULL,\n ts BIGINT NOT NULL,\n table_id BINARY(16) NOT NULL,\n data LONGBLOB NOT NULL,\n PRIMARY KEY (ts, table_id, id),\n INDEX commit_logs_by_table_and_id (table_id, id, ts)\n) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;`, `CREATE TABLE ${t}metadata (\n meta_key VARCHAR(255) PRIMARY KEY,\n meta_value BIGINT NOT NULL\n) ENGINE=InnoDB;`];
9
+ if (dialect === "mysql") return [
10
+ `CREATE TABLE ${t}global_commit_ts (\n id BIGINT NOT NULL\n) ENGINE=InnoDB;`,
11
+ `CREATE TABLE ${t}commit_logs (\n id BINARY(16) NOT NULL,\n ts BIGINT NOT NULL,\n table_id BINARY(16) NOT NULL,\n data LONGBLOB NOT NULL,\n PRIMARY KEY (ts, table_id, id),\n INDEX commit_logs_by_table_and_id (table_id, id, ts)\n) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;`,
12
+ `CREATE TABLE ${t}metadata (\n meta_key VARCHAR(255) PRIMARY KEY,\n meta_value BIGINT NOT NULL\n) ENGINE=InnoDB;`
13
+ ];
10
14
  return [
15
+ `CREATE SEQUENCE ${t}global_commit_ts START 1 INCREMENT 1 NO CYCLE;`,
11
16
  `CREATE TABLE ${t}commit_logs (\n id BYTEA NOT NULL,\n ts BIGINT NOT NULL,\n table_id BYTEA NOT NULL,\n data BYTEA NOT NULL,\n PRIMARY KEY (ts, table_id, id)\n);`,
12
17
  `CREATE INDEX ${i}commit_logs_by_table_and_id ON commit_logs (table_id, id, ts);`,
13
18
  `CREATE INDEX ${i}commit_logs_by_table_ts_and_id ON commit_logs (table_id, ts, id);`,
@@ -115,7 +120,14 @@ function isPrimaryKey(field) {
115
120
  }
116
121
  function getDefaultValue(field) {
117
122
  const meta = getFieldMeta(field);
118
- if (meta && typeof meta.defaultValue === "string") return meta.defaultValue;
123
+ if (meta && meta.defaultValue !== void 0) {
124
+ if (typeof meta.defaultValue === "string") return meta.defaultValue;
125
+ const value = meta.defaultValue;
126
+ if (value === null) return "NULL";
127
+ if (typeof value === "number") return value.toString();
128
+ if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
129
+ if (typeof value === "bigint") return value.toString();
130
+ }
119
131
  return getDefaultFromZod(field);
120
132
  }
121
133
  function schemaToCreateTable(schema, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"schema-sql.js","names":["z"],"sources":["../../../src/db/core-tables.ts","../../../src/db/schema-sql.ts"],"sourcesContent":["import type { SqlDialect } from \"./schema-sql\";\n\n/**\n * DDL for the core, framework-owned tables that every Supalive database must\n * have alongside the user's own tables:\n *\n * - `commit_logs` — the append-only OCC change log (+ its lookup indexes).\n * - `metadata` — the small key/value table holding the OCC watermarks\n * (`latest_committed_ts`, `min_retained_ts`) and the core\n * schema version (`core_version`).\n *\n * These used to live in each `Database.migrationSql` array and were applied\n * ad-hoc. They now belong in the generated `schema.sql` (see\n * {@link generateSchemaSql}, which prepends them by default) so a single\n * generated file fully describes the database.\n *\n * Note: this module intentionally covers ONLY tables + indexes. Non-table\n * bootstrap (the `global_commit_ts` sequence, the MySQL `sequence` table, and\n * the metadata seed rows) is handled at runtime by `initCore` — see\n * {@link file://./init_db.ts}.\n */\n\nexport interface CoreTablesSqlOptions {\n /** Emit `IF NOT EXISTS` on `CREATE TABLE`/`CREATE INDEX`. Default true. */\n ifNotExists?: boolean;\n}\n\nexport function coreTablesSql(\n dialect: SqlDialect = \"postgres\",\n options?: CoreTablesSqlOptions,\n): string[] {\n const ifNotExists = options?.ifNotExists ?? true;\n const t = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n const i = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n\n if (dialect === \"mysql\") {\n return [\n `CREATE TABLE ${t}commit_logs (\\n` +\n ` id BINARY(16) NOT NULL,\\n` +\n ` ts BIGINT NOT NULL,\\n` +\n ` table_id BINARY(16) NOT NULL,\\n` +\n ` data LONGBLOB NOT NULL,\\n` +\n ` PRIMARY KEY (ts, table_id, id),\\n` +\n ` INDEX commit_logs_by_table_and_id (table_id, id, ts)\\n` +\n `) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;`,\n `CREATE TABLE ${t}metadata (\\n` +\n ` meta_key VARCHAR(255) PRIMARY KEY,\\n` +\n ` meta_value BIGINT NOT NULL\\n` +\n `) ENGINE=InnoDB;`,\n ];\n }\n\n return [\n `CREATE TABLE ${t}commit_logs (\\n` +\n ` id BYTEA NOT NULL,\\n` +\n ` ts BIGINT NOT NULL,\\n` +\n ` table_id BYTEA NOT NULL,\\n` +\n ` data BYTEA NOT NULL,\\n` +\n ` PRIMARY KEY (ts, table_id, id)\\n` +\n `);`,\n `CREATE INDEX ${i}commit_logs_by_table_and_id ON commit_logs (table_id, id, ts);`,\n `CREATE INDEX ${i}commit_logs_by_table_ts_and_id ON commit_logs (table_id, ts, id);`,\n `CREATE TABLE ${t}metadata (\\n` +\n ` meta_key TEXT PRIMARY KEY,\\n` +\n ` meta_value BIGINT NOT NULL\\n` +\n `);`,\n ];\n}\n","import { z } from \"zod\";\nimport { SchemaDefinition, schemaRegistry } from \"./schema\";\nimport type { DeclarativeIndex } from \"./schema\";\nimport { unwrapZodType } from \"./codec\";\nimport { coreTablesSql } from \"./core-tables\";\n\nexport type SqlDialect = \"postgres\" | \"mysql\";\n\nfunction getFieldMeta(field: unknown): Record<string, unknown> | undefined {\n const f = field as any;\n const meta = typeof f.meta === \"function\" ? f.meta() : undefined;\n if (meta) return meta;\n\n const unwrapped = unwrapZodType(field);\n if (unwrapped !== field) {\n const innerMeta = typeof (unwrapped as any).meta === \"function\" ? (unwrapped as any).meta() : undefined;\n if (innerMeta) return innerMeta;\n }\n\n return undefined;\n}\n\nfunction getStringMaxLength(field: unknown): number | undefined {\n const unwrapped = unwrapZodType(field);\n if (!(unwrapped instanceof z.ZodString)) return undefined;\n\n const checks: any[] = (unwrapped as any).def?.checks ?? [];\n let maxLength: number | undefined;\n\n for (const check of checks) {\n const c = check._zod?.def ?? check.def ?? check;\n if (c.check === \"length_equals\" || c.check === \"size_equals\") {\n const len = c.length ?? c.size;\n if (typeof len === \"number\") maxLength = maxLength === undefined ? len : Math.min(maxLength, len);\n }\n if (c.check === \"max_length\" || c.check === \"max_size\") {\n const len = c.maximum ?? c.max;\n if (typeof len === \"number\") maxLength = maxLength === undefined ? len : Math.min(maxLength, len);\n }\n }\n\n return maxLength;\n}\n\nfunction isOptional(field: unknown): boolean {\n return (\n field instanceof z.ZodOptional ||\n field instanceof z.ZodNullable\n );\n}\n\nfunction escapeSQLString(s: string): string {\n return `'${s.replace(/'/g, \"''\")}'`;\n}\n\nfunction getDefaultFromZod(field: unknown): string | undefined {\n if (!(field instanceof z.ZodDefault)) return undefined;\n\n try {\n const f = field as any;\n let value = f.defaultValue;\n if (value === undefined) value = f.def?.defaultValue;\n if (typeof value === \"function\") value = value();\n\n if (value === undefined) return undefined;\n if (value === null) return \"NULL\";\n if (typeof value === \"string\") return escapeSQLString(value);\n if (typeof value === \"number\") return value.toString();\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n if (typeof value === \"bigint\") return value.toString();\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nconst VARCHAR_MAX = 65535;\n\nfunction jsonType(dialect: SqlDialect): string {\n return dialect === \"mysql\" ? \"JSON\" : \"JSONB\";\n}\n\n// Maps a scalar (non-collection) Zod type to a native SQL column type.\n// Returns undefined for types that don't have a simple scalar mapping\n// (objects, records, nested arrays, unknown types), so callers can decide\n// how to fall back. `field` is the original (possibly wrapped) node used to\n// read length constraints; `unwrapped` is the underlying scalar type.\nfunction getScalarSqlType(unwrapped: unknown, field: unknown, dialect: SqlDialect): string | undefined {\n if (unwrapped instanceof z.ZodString) {\n const maxLen = getStringMaxLength(field);\n if (maxLen !== undefined && maxLen <= VARCHAR_MAX) return `VARCHAR(${maxLen})`;\n return \"TEXT\";\n }\n\n if (unwrapped instanceof z.ZodNumber) return \"BIGINT\";\n\n if (unwrapped instanceof z.ZodBoolean) {\n return dialect === \"mysql\" ? \"TINYINT(1)\" : \"BOOLEAN\";\n }\n\n if (unwrapped instanceof z.ZodDate) {\n return dialect === \"mysql\" ? \"DATETIME(3)\" : \"TIMESTAMPTZ\";\n }\n\n if (unwrapped instanceof z.ZodBigInt) return \"BIGINT\";\n\n if (unwrapped instanceof z.ZodEnum) return \"TEXT\";\n\n return undefined;\n}\n\nfunction getArrayElement(arr: z.ZodArray): unknown {\n return arr.element ?? arr.def?.element ?? arr.def?.type;\n}\n\n// Resolves the SQL type for an array field. MySQL has no native array column\n// type, so arrays are stored as JSON. Postgres supports native arrays of\n// scalar types (e.g. TEXT[], BIGINT[]); arrays of objects/records or nested\n// arrays fall back to JSONB.\nfunction getArraySqlType(arr: z.ZodArray, dialect: SqlDialect): string {\n if (dialect === \"mysql\") return \"JSON\";\n\n const rawElement = getArrayElement(arr);\n const element = unwrapZodType(rawElement);\n\n // Honor an explicit SQL type declared on the element's meta.\n const elementMeta = getFieldMeta(rawElement);\n if (elementMeta) {\n if (typeof elementMeta.pgType === \"string\") return `${elementMeta.pgType}[]`;\n }\n\n const scalar = getScalarSqlType(element, rawElement, dialect);\n if (scalar !== undefined) return `${scalar}[]`;\n\n return \"JSONB\";\n}\n\nfunction getSqlType(field: unknown, dialect: SqlDialect): string {\n const meta = getFieldMeta(field);\n if (meta) {\n const dialectKey = dialect === \"mysql\" ? \"mysqlType\" : \"pgType\";\n if (typeof meta[dialectKey] === \"string\") return meta[dialectKey] as string;\n }\n\n const unwrapped = unwrapZodType(field);\n\n if (unwrapped instanceof z.ZodArray) {\n return getArraySqlType(unwrapped, dialect);\n }\n\n if (unwrapped instanceof z.ZodObject || unwrapped instanceof z.ZodRecord) {\n return jsonType(dialect);\n }\n\n return getScalarSqlType(unwrapped, field, dialect) ?? \"TEXT\";\n}\n\nfunction isPrimaryKey(field: unknown): boolean {\n const meta = getFieldMeta(field);\n return meta?.primaryKey === true;\n}\n\nfunction getDefaultValue(field: unknown): string | undefined {\n const meta = getFieldMeta(field);\n if (meta && typeof meta.defaultValue === \"string\") {\n return meta.defaultValue;\n }\n\n return getDefaultFromZod(field);\n}\n\nexport interface SchemaToCreateTableOptions {\n dialect?: SqlDialect;\n ifNotExists?: boolean;\n}\n\nexport function schemaToCreateTable(\n schema: SchemaDefinition<string, any, any>,\n options?: SchemaToCreateTableOptions,\n): string {\n const dialect = options?.dialect ?? \"postgres\";\n const ifNotExists = options?.ifNotExists ?? true;\n\n const tableName = schema.table;\n const shape = schema.schema.shape;\n const columns: Record<string, string> = schema.columns;\n\n const userKeys = Object.keys(shape).filter(k => k !== \"id\" && k !== \"commitTs\");\n const orderedKeys = [\"id\", ...userKeys, \"commitTs\"];\n\n const lines: string[] = [];\n\n for (const fieldName of orderedKeys) {\n const field = shape[fieldName];\n if (!field) continue;\n\n const colName = columns[fieldName] ?? fieldName;\n if (!colName) continue;\n\n const sqlType = getSqlType(field, dialect);\n const notNull = !isOptional(field);\n const pk = isPrimaryKey(field);\n const defaultVal = fieldName === \"commitTs\" ? \"0\" : getDefaultValue(field);\n\n let line = ` ${colName} ${sqlType}`;\n if (notNull) line += \" NOT NULL\";\n if (pk) line += \" PRIMARY KEY\";\n if (defaultVal !== undefined) line += ` DEFAULT ${defaultVal}`;\n\n lines.push(line);\n }\n\n const ifNot = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n return `CREATE TABLE ${ifNot}${tableName} (\\n${lines.join(\",\\n\")}\\n);`;\n}\n\nexport function formatDeclarativeIndex(\n idx: DeclarativeIndex,\n tableName: string,\n columns: Record<string, string>,\n): string {\n const colNames = idx.columns.map(c => columns[c] ?? c).join(\", \");\n let sql = `CREATE ${idx.unique ? \"UNIQUE \" : \"\"}INDEX IF NOT EXISTS ${idx.name} ON ${tableName}`;\n if (idx.type) sql += ` USING ${idx.type}`;\n sql += ` (${colNames})`;\n if (idx.where) sql += ` WHERE ${idx.where}`;\n return sql + \";\";\n}\n\nexport interface SchemaIndexesOptions {\n /** Emit `IF NOT EXISTS` on the auto-generated commit_ts index. Default true. */\n ifNotExists?: boolean;\n}\n\nexport function schemaIndexes(\n schema: SchemaDefinition<string, any, any>,\n options?: SchemaIndexesOptions,\n): string[] {\n const out = (schema.indexes ?? []).map(idx => {\n if (typeof idx === \"string\") return idx;\n return formatDeclarativeIndex(idx, schema.table, schema.columns);\n });\n\n // Every table has a `commit_ts` column (OCC) that is otherwise unindexed.\n // Auto-add an index on it unless the user already declared one covering\n // the commit_ts field or one with the same generated name.\n const commitCol = schema.columns[\"commitTs\"] ?? \"commit_ts\";\n const autoName = `${schema.table}_commit_ts_idx`;\n const alreadyDeclared = (schema.indexes ?? []).some(idx => {\n if (typeof idx === \"string\") return idx.includes(autoName);\n if (idx.name === autoName) return true;\n return idx.columns.length === 1 &&\n (idx.columns[0] === \"commitTs\" || idx.columns[0] === commitCol);\n });\n if (!alreadyDeclared) {\n const ifNot = (options?.ifNotExists ?? true) ? \"IF NOT EXISTS \" : \"\";\n out.push(`CREATE INDEX ${ifNot}${autoName} ON ${schema.table} (${commitCol});`);\n }\n\n return out;\n}\n\nexport interface GenerateSchemaSqlOptions {\n dialect?: SqlDialect;\n ifNotExists?: boolean;\n header?: boolean;\n /**\n * Prepend the framework-owned core tables (`commit_logs`, `metadata`) and\n * their indexes so the generated SQL fully describes the database. Default\n * true. Non-table core bootstrap (sequences, seed rows) is handled at\n * runtime by `initCore`, not emitted here.\n */\n includeCoreTables?: boolean;\n}\n\nexport function generateSchemaSql(\n schemas?: Map<string, SchemaDefinition<string, any, any>> | SchemaDefinition<string, any, any>[],\n options?: GenerateSchemaSqlOptions,\n): string {\n const dialect = options?.dialect ?? \"postgres\";\n const header = options?.header ?? true;\n const includeCoreTables = options?.includeCoreTables ?? true;\n\n let list: SchemaDefinition<string, any, any>[];\n\n if (schemas instanceof Map) {\n list = [...schemas.values()];\n } else if (Array.isArray(schemas)) {\n list = schemas;\n } else {\n list = [...schemaRegistry.values()];\n }\n\n list = list.filter(s => s?.table);\n list.sort((a, b) => a.table.localeCompare(b.table));\n\n const parts: string[] = [];\n\n if (header) {\n parts.push(\"-- Generated by Supalive Schema Generator\");\n parts.push(`-- Dialect: ${dialect}`);\n parts.push(`-- Tables: ${list.length}${includeCoreTables ? \" (+ core)\" : \"\"}`);\n parts.push(\"\");\n }\n\n if (includeCoreTables) {\n parts.push(\"-- Core tables (framework-owned)\");\n for (const stmt of coreTablesSql(dialect, { ifNotExists: options?.ifNotExists })) {\n parts.push(stmt);\n }\n parts.push(\"\");\n }\n\n for (const schema of list) {\n parts.push(schemaToCreateTable(schema, { ...options, dialect }));\n const indexStmts = schemaIndexes(schema, { ifNotExists: options?.ifNotExists });\n for (const stmt of indexStmts) {\n parts.push(stmt);\n }\n parts.push(\"\");\n }\n\n return parts.join(\"\\n\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema-sql.js","names":["z"],"sources":["../../../src/db/core_tables.ts","../../../src/db/schema-sql.ts"],"sourcesContent":["import type { SqlDialect } from \"./schema-sql\";\n\n/**\n * DDL for the core, framework-owned database objects that every Supalive\n * database must have alongside the user's own tables:\n *\n * - `commit_logs` — the append-only OCC change log (+ its lookup indexes).\n * - `metadata` — the small key/value table holding the OCC watermarks\n * (`latest_committed_ts`, `min_retained_ts`) and the\n * core schema version (`core_version`).\n * - `global_commit_ts` — the monotonic commit-timestamp source: a SEQUENCE on\n * Postgres, a single-row `BIGINT` counter table on MySQL.\n *\n * These are all pure schema (DDL), so they belong in the generated `schema.sql`\n * (see {@link generateSchemaSql}, which prepends them by default) and get\n * migrated ahead of runtime by your normal migration pipeline — a single\n * generated file fully describes the database.\n *\n * Data seeding (the `metadata` rows and the MySQL counter's initial `0`) and\n * any runtime-only schema changes live in `initCore` — see\n * {@link file://./init_db.ts}.\n */\n\nexport interface CoreTablesSqlOptions {\n /** Emit `IF NOT EXISTS` on `CREATE TABLE`/`CREATE INDEX`/`CREATE SEQUENCE`. Default true. */\n ifNotExists?: boolean;\n}\n\nexport function coreTablesSql(\n dialect: SqlDialect = \"postgres\",\n options?: CoreTablesSqlOptions,\n): string[] {\n const ifNotExists = options?.ifNotExists ?? true;\n const t = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n const i = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n\n if (dialect === \"mysql\") {\n return [\n // MySQL has no sequences: a single-row counter table advanced via\n // LAST_INSERT_ID (see MySqlDatabase.getNextTimestamp). Seeded to 0\n // by initCore.\n `CREATE TABLE ${t}global_commit_ts (\\n` +\n ` id BIGINT NOT NULL\\n` +\n `) ENGINE=InnoDB;`,\n `CREATE TABLE ${t}commit_logs (\\n` +\n ` id BINARY(16) NOT NULL,\\n` +\n ` ts BIGINT NOT NULL,\\n` +\n ` table_id BINARY(16) NOT NULL,\\n` +\n ` data LONGBLOB NOT NULL,\\n` +\n ` PRIMARY KEY (ts, table_id, id),\\n` +\n ` INDEX commit_logs_by_table_and_id (table_id, id, ts)\\n` +\n `) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;`,\n `CREATE TABLE ${t}metadata (\\n` +\n ` meta_key VARCHAR(255) PRIMARY KEY,\\n` +\n ` meta_value BIGINT NOT NULL\\n` +\n `) ENGINE=InnoDB;`,\n ];\n }\n\n return [\n // Monotonic OCC commit-timestamp source (see PgDatabase.getNextTimestamp).\n `CREATE SEQUENCE ${t}global_commit_ts START 1 INCREMENT 1 NO CYCLE;`,\n `CREATE TABLE ${t}commit_logs (\\n` +\n ` id BYTEA NOT NULL,\\n` +\n ` ts BIGINT NOT NULL,\\n` +\n ` table_id BYTEA NOT NULL,\\n` +\n ` data BYTEA NOT NULL,\\n` +\n ` PRIMARY KEY (ts, table_id, id)\\n` +\n `);`,\n `CREATE INDEX ${i}commit_logs_by_table_and_id ON commit_logs (table_id, id, ts);`,\n `CREATE INDEX ${i}commit_logs_by_table_ts_and_id ON commit_logs (table_id, ts, id);`,\n `CREATE TABLE ${t}metadata (\\n` +\n ` meta_key TEXT PRIMARY KEY,\\n` +\n ` meta_value BIGINT NOT NULL\\n` +\n `);`,\n ];\n}\n","import { z } from \"zod\";\nimport { SchemaDefinition, schemaRegistry } from \"./schema\";\nimport type { DeclarativeIndex } from \"./schema\";\nimport { unwrapZodType } from \"./codec\";\nimport { coreTablesSql } from \"./core_tables\";\n\nexport type SqlDialect = \"postgres\" | \"mysql\";\n\nfunction getFieldMeta(field: unknown): Record<string, unknown> | undefined {\n const f = field as any;\n const meta = typeof f.meta === \"function\" ? f.meta() : undefined;\n if (meta) return meta;\n\n const unwrapped = unwrapZodType(field);\n if (unwrapped !== field) {\n const innerMeta = typeof (unwrapped as any).meta === \"function\" ? (unwrapped as any).meta() : undefined;\n if (innerMeta) return innerMeta;\n }\n\n return undefined;\n}\n\nfunction getStringMaxLength(field: unknown): number | undefined {\n const unwrapped = unwrapZodType(field);\n if (!(unwrapped instanceof z.ZodString)) return undefined;\n\n const checks: any[] = (unwrapped as any).def?.checks ?? [];\n let maxLength: number | undefined;\n\n for (const check of checks) {\n const c = check._zod?.def ?? check.def ?? check;\n if (c.check === \"length_equals\" || c.check === \"size_equals\") {\n const len = c.length ?? c.size;\n if (typeof len === \"number\") maxLength = maxLength === undefined ? len : Math.min(maxLength, len);\n }\n if (c.check === \"max_length\" || c.check === \"max_size\") {\n const len = c.maximum ?? c.max;\n if (typeof len === \"number\") maxLength = maxLength === undefined ? len : Math.min(maxLength, len);\n }\n }\n\n return maxLength;\n}\n\nfunction isOptional(field: unknown): boolean {\n return (\n field instanceof z.ZodOptional ||\n field instanceof z.ZodNullable\n );\n}\n\nfunction escapeSQLString(s: string): string {\n return `'${s.replace(/'/g, \"''\")}'`;\n}\n\nfunction getDefaultFromZod(field: unknown): string | undefined {\n if (!(field instanceof z.ZodDefault)) return undefined;\n\n try {\n const f = field as any;\n let value = f.defaultValue;\n if (value === undefined) value = f.def?.defaultValue;\n if (typeof value === \"function\") value = value();\n\n if (value === undefined) return undefined;\n if (value === null) return \"NULL\";\n if (typeof value === \"string\") return escapeSQLString(value);\n if (typeof value === \"number\") return value.toString();\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n if (typeof value === \"bigint\") return value.toString();\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nconst VARCHAR_MAX = 65535;\n\nfunction jsonType(dialect: SqlDialect): string {\n return dialect === \"mysql\" ? \"JSON\" : \"JSONB\";\n}\n\n// Maps a scalar (non-collection) Zod type to a native SQL column type.\n// Returns undefined for types that don't have a simple scalar mapping\n// (objects, records, nested arrays, unknown types), so callers can decide\n// how to fall back. `field` is the original (possibly wrapped) node used to\n// read length constraints; `unwrapped` is the underlying scalar type.\nfunction getScalarSqlType(unwrapped: unknown, field: unknown, dialect: SqlDialect): string | undefined {\n if (unwrapped instanceof z.ZodString) {\n const maxLen = getStringMaxLength(field);\n if (maxLen !== undefined && maxLen <= VARCHAR_MAX) return `VARCHAR(${maxLen})`;\n return \"TEXT\";\n }\n\n if (unwrapped instanceof z.ZodNumber) return \"BIGINT\";\n\n if (unwrapped instanceof z.ZodBoolean) {\n return dialect === \"mysql\" ? \"TINYINT(1)\" : \"BOOLEAN\";\n }\n\n if (unwrapped instanceof z.ZodDate) {\n return dialect === \"mysql\" ? \"DATETIME(3)\" : \"TIMESTAMPTZ\";\n }\n\n if (unwrapped instanceof z.ZodBigInt) return \"BIGINT\";\n\n if (unwrapped instanceof z.ZodEnum) return \"TEXT\";\n\n return undefined;\n}\n\nfunction getArrayElement(arr: z.ZodArray): unknown {\n return arr.element ?? arr.def?.element ?? arr.def?.type;\n}\n\n// Resolves the SQL type for an array field. MySQL has no native array column\n// type, so arrays are stored as JSON. Postgres supports native arrays of\n// scalar types (e.g. TEXT[], BIGINT[]); arrays of objects/records or nested\n// arrays fall back to JSONB.\nfunction getArraySqlType(arr: z.ZodArray, dialect: SqlDialect): string {\n if (dialect === \"mysql\") return \"JSON\";\n\n const rawElement = getArrayElement(arr);\n const element = unwrapZodType(rawElement);\n\n // Honor an explicit SQL type declared on the element's meta.\n const elementMeta = getFieldMeta(rawElement);\n if (elementMeta) {\n if (typeof elementMeta.pgType === \"string\") return `${elementMeta.pgType}[]`;\n }\n\n const scalar = getScalarSqlType(element, rawElement, dialect);\n if (scalar !== undefined) return `${scalar}[]`;\n\n return \"JSONB\";\n}\n\nfunction getSqlType(field: unknown, dialect: SqlDialect): string {\n const meta = getFieldMeta(field);\n if (meta) {\n const dialectKey = dialect === \"mysql\" ? \"mysqlType\" : \"pgType\";\n if (typeof meta[dialectKey] === \"string\") return meta[dialectKey] as string;\n }\n\n const unwrapped = unwrapZodType(field);\n\n if (unwrapped instanceof z.ZodArray) {\n return getArraySqlType(unwrapped, dialect);\n }\n\n if (unwrapped instanceof z.ZodObject || unwrapped instanceof z.ZodRecord) {\n return jsonType(dialect);\n }\n\n return getScalarSqlType(unwrapped, field, dialect) ?? \"TEXT\";\n}\n\nfunction isPrimaryKey(field: unknown): boolean {\n const meta = getFieldMeta(field);\n return meta?.primaryKey === true;\n}\n\nfunction getDefaultValue(field: unknown): string | undefined {\n const meta = getFieldMeta(field);\n if (meta && meta.defaultValue !== undefined) {\n // A string is treated as a raw SQL expression (e.g. \"now()\") for\n // backwards compatibility; other values are converted to SQL literals.\n if (typeof meta.defaultValue === \"string\") return meta.defaultValue;\n\n const value = meta.defaultValue;\n if (value === null) return \"NULL\";\n if (typeof value === \"number\") return value.toString();\n if (typeof value === \"boolean\") return value ? \"TRUE\" : \"FALSE\";\n if (typeof value === \"bigint\") return value.toString();\n }\n\n return getDefaultFromZod(field);\n}\n\nexport interface SchemaToCreateTableOptions {\n dialect?: SqlDialect;\n ifNotExists?: boolean;\n}\n\nexport function schemaToCreateTable(\n schema: SchemaDefinition<string, any, any>,\n options?: SchemaToCreateTableOptions,\n): string {\n const dialect = options?.dialect ?? \"postgres\";\n const ifNotExists = options?.ifNotExists ?? true;\n\n const tableName = schema.table;\n const shape = schema.schema.shape;\n const columns: Record<string, string> = schema.columns;\n\n const userKeys = Object.keys(shape).filter(k => k !== \"id\" && k !== \"commitTs\");\n const orderedKeys = [\"id\", ...userKeys, \"commitTs\"];\n\n const lines: string[] = [];\n\n for (const fieldName of orderedKeys) {\n const field = shape[fieldName];\n if (!field) continue;\n\n const colName = columns[fieldName] ?? fieldName;\n if (!colName) continue;\n\n const sqlType = getSqlType(field, dialect);\n const notNull = !isOptional(field);\n const pk = isPrimaryKey(field);\n const defaultVal = fieldName === \"commitTs\" ? \"0\" : getDefaultValue(field);\n\n let line = ` ${colName} ${sqlType}`;\n if (notNull) line += \" NOT NULL\";\n if (pk) line += \" PRIMARY KEY\";\n if (defaultVal !== undefined) line += ` DEFAULT ${defaultVal}`;\n\n lines.push(line);\n }\n\n const ifNot = ifNotExists ? \"IF NOT EXISTS \" : \"\";\n return `CREATE TABLE ${ifNot}${tableName} (\\n${lines.join(\",\\n\")}\\n);`;\n}\n\nexport function formatDeclarativeIndex(\n idx: DeclarativeIndex,\n tableName: string,\n columns: Record<string, string>,\n): string {\n const colNames = idx.columns.map(c => columns[c] ?? c).join(\", \");\n let sql = `CREATE ${idx.unique ? \"UNIQUE \" : \"\"}INDEX IF NOT EXISTS ${idx.name} ON ${tableName}`;\n if (idx.type) sql += ` USING ${idx.type}`;\n sql += ` (${colNames})`;\n if (idx.where) sql += ` WHERE ${idx.where}`;\n return sql + \";\";\n}\n\nexport interface SchemaIndexesOptions {\n /** Emit `IF NOT EXISTS` on the auto-generated commit_ts index. Default true. */\n ifNotExists?: boolean;\n}\n\nexport function schemaIndexes(\n schema: SchemaDefinition<string, any, any>,\n options?: SchemaIndexesOptions,\n): string[] {\n const out = (schema.indexes ?? []).map(idx => {\n if (typeof idx === \"string\") return idx;\n return formatDeclarativeIndex(idx, schema.table, schema.columns);\n });\n\n // Every table has a `commit_ts` column (OCC) that is otherwise unindexed.\n // Auto-add an index on it unless the user already declared one covering\n // the commit_ts field or one with the same generated name.\n const commitCol = schema.columns[\"commitTs\"] ?? \"commit_ts\";\n const autoName = `${schema.table}_commit_ts_idx`;\n const alreadyDeclared = (schema.indexes ?? []).some(idx => {\n if (typeof idx === \"string\") return idx.includes(autoName);\n if (idx.name === autoName) return true;\n return idx.columns.length === 1 &&\n (idx.columns[0] === \"commitTs\" || idx.columns[0] === commitCol);\n });\n if (!alreadyDeclared) {\n const ifNot = (options?.ifNotExists ?? true) ? \"IF NOT EXISTS \" : \"\";\n out.push(`CREATE INDEX ${ifNot}${autoName} ON ${schema.table} (${commitCol});`);\n }\n\n return out;\n}\n\nexport interface GenerateSchemaSqlOptions {\n dialect?: SqlDialect;\n ifNotExists?: boolean;\n header?: boolean;\n /**\n * Prepend the framework-owned core tables (`commit_logs`, `metadata`) and\n * their indexes so the generated SQL fully describes the database. Default\n * true. Non-table core bootstrap (sequences, seed rows) is handled at\n * runtime by `initCore`, not emitted here.\n */\n includeCoreTables?: boolean;\n}\n\nexport function generateSchemaSql(\n schemas?: Map<string, SchemaDefinition<string, any, any>> | SchemaDefinition<string, any, any>[],\n options?: GenerateSchemaSqlOptions,\n): string {\n const dialect = options?.dialect ?? \"postgres\";\n const header = options?.header ?? true;\n const includeCoreTables = options?.includeCoreTables ?? true;\n\n let list: SchemaDefinition<string, any, any>[];\n\n if (schemas instanceof Map) {\n list = [...schemas.values()];\n } else if (Array.isArray(schemas)) {\n list = schemas;\n } else {\n list = [...schemaRegistry.values()];\n }\n\n list = list.filter(s => s?.table);\n list.sort((a, b) => a.table.localeCompare(b.table));\n\n const parts: string[] = [];\n\n if (header) {\n parts.push(\"-- Generated by Supalive Schema Generator\");\n parts.push(`-- Dialect: ${dialect}`);\n parts.push(`-- Tables: ${list.length}${includeCoreTables ? \" (+ core)\" : \"\"}`);\n parts.push(\"\");\n }\n\n if (includeCoreTables) {\n parts.push(\"-- Core tables (framework-owned)\");\n for (const stmt of coreTablesSql(dialect, { ifNotExists: options?.ifNotExists })) {\n parts.push(stmt);\n }\n parts.push(\"\");\n }\n\n for (const schema of list) {\n parts.push(schemaToCreateTable(schema, { ...options, dialect }));\n const indexStmts = schemaIndexes(schema, { ifNotExists: options?.ifNotExists });\n for (const stmt of indexStmts) {\n parts.push(stmt);\n }\n parts.push(\"\");\n }\n\n return parts.join(\"\\n\");\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { At as SupaliveDb, Bn as InvalidateWritesetParamsSchema, E as Context, Gn as UnregisterSubscriptionParams, Hn as RegisterSubscriptionParams, Jn as UnregisterSubscriptionsParams, Kn as UnregisterSubscriptionParamsSchema, Ln as CacheLayer, On as Database, Qn as UpdateSubscriptionReadSetResult, Rn as AffectedSubscription, Un as RegisterSubscriptionParamsSchema, Vn as InvalidateWritesetResult, Wn as RegisterSubscriptionResult, Xn as UpdateSubscriptionReadSetParams, Yn as UnregisterSubscriptionsResult, Zn as UpdateSubscriptionReadSetParamsSchema, qn as UnregisterSubscriptionResult, rt as Router, zn as InvalidateWritesetParams } from "../../index-E1_1iRI1.js";
2
- import { t as MySqlDatabase } from "../../mysql-BmkLy5oY.js";
3
- import { t as PgDatabase } from "../../postgres-v2ctNE6o.js";
4
- import { A as ScheduledJobDef, C as EnqueueOptions, D as QStashScheduler, E as JobScheduler, O as QStashSchedulerOptions, S as DevSchedulerOptions, T as JobClient, b as UpstashConfig, f as DatabaseConfig, k as ScheduleHandle, u as SubId, v as SubscriptionManagerConfig, w as IncomingJobRequest, x as DevScheduler, y as SupaliveServerConfig } from "../../types_server-CzAufcee.js";
1
+ import { $n as RegisterSubscriptionParamsSchema, At as DevScheduler, Bt as SupaliveDb, E as Context, Ft as JobScheduler, It as QStashScheduler, Jn as AffectedSubscription, Lt as QStashSchedulerOptions, Mt as EnqueueOptions, Nt as IncomingJobRequest, Pt as JobClient, Qn as RegisterSubscriptionParams, Rn as Database, Rt as ScheduleHandle, Xn as InvalidateWritesetParamsSchema, Yn as InvalidateWritesetParams, Zn as InvalidateWritesetResult, ar as UnregisterSubscriptionsResult, cr as UpdateSubscriptionReadSetResult, er as RegisterSubscriptionResult, ir as UnregisterSubscriptionsParams, jt as DevSchedulerOptions, nr as UnregisterSubscriptionParamsSchema, or as UpdateSubscriptionReadSetParams, qn as CacheLayer, rr as UnregisterSubscriptionResult, rt as Router, sr as UpdateSubscriptionReadSetParamsSchema, tr as UnregisterSubscriptionParams, zt as ScheduledJobDef } from "../../index-DDK9ZIYb.js";
2
+ import { t as MySqlDatabase } from "../../mysql-DF-dZHi7.js";
3
+ import { t as PgDatabase } from "../../postgres-CKtJ62S4.js";
4
+ import { b as UpstashConfig, f as DatabaseConfig, u as SubId, v as SubscriptionManagerConfig, y as SupaliveServerConfig } from "../../types_server-C9owgeSs.js";
5
5
  import pino, { Level } from "pino";
6
6
  import Redis$1 from "ioredis";
7
7
 
@@ -21,10 +21,12 @@ declare class SupaliveWebSocketServer<TContext extends Context> {
21
21
  private router?;
22
22
  private retentionWatermark;
23
23
  private oneShotDeps;
24
- private scheduler?;
24
+ private scheduler;
25
25
  private jobPath;
26
- private jobClient?;
26
+ private jobClient;
27
27
  private rpcHandler?;
28
+ /** Optional object storage exposed to every procedure as `ctx.storage`. */
29
+ private storage;
28
30
  private sessions;
29
31
  private serverSubscriptions;
30
32
  private subManagerClient;
@@ -67,7 +69,7 @@ declare class SupaliveWebSocketServer<TContext extends Context> {
67
69
  * The app-facing {@link JobClient} — hand it to your service layer so
68
70
  * procedures can schedule/cancel one-shots without reaching for the server.
69
71
  */
70
- getJobClient(): JobClient | undefined;
72
+ getJobClient(): JobClient;
71
73
  stop(): Promise<void>;
72
74
  getStats(): {
73
75
  instanceId: string;
@@ -330,23 +332,24 @@ declare class SubManagerClient {
330
332
  //#endregion
331
333
  //#region src/db/init_db.d.ts
332
334
  /**
333
- * Current core schema version. Bump this whenever core needs a new non-table
334
- * database operation (a sequence, a seed row, a backfill). Each increment adds
335
- * a case to `Database.coreMigrationStatements` for that version step.
335
+ * Current core runtime-bootstrap version. Bump this whenever core needs a new
336
+ * runtime database operation a data seed, a backfill, or a schema change that
337
+ * must be applied directly at runtime rather than through the migration
338
+ * pipeline. Each increment adds a case to `Database.coreMigrationStatements`.
336
339
  *
337
- * The core *tables* (commit_logs, metadata) are NOT versioned here — they come
338
- * from the generated schema (`coreTablesSql` / `generateSchemaSql`) which must
339
- * be applied to the database BEFORE `initCore` runs.
340
+ * The core *schema* (the `commit_logs`/`metadata` tables and the
341
+ * `global_commit_ts` sequence/counter) is NOT versioned here it comes from
342
+ * the generated schema (`coreTablesSql` / `generateSchemaSql`), which must be
343
+ * applied to the database BEFORE `initCore` runs.
340
344
  */
341
345
  declare const CORE_VERSION = 1n;
342
346
  /**
343
- * Bring the core, non-table database state up to {@link CORE_VERSION}. Idempotent
344
- * and safe to call from every process at startup: a lock-free version read
345
- * short-circuits the common "already current" case, and the actual migration
346
- * runs under a cross-process lock with a re-check so only one process applies
347
- * it.
347
+ * Bring the core runtime state up to {@link CORE_VERSION}. Idempotent and safe
348
+ * to call from every process at startup: a lock-free version read short-circuits
349
+ * the common "already current" case, and the actual migration runs under a
350
+ * cross-process lock with a re-check so only one process applies it.
348
351
  *
349
- * Assumes the core tables already exist (apply the generated schema first);
352
+ * Assumes the core schema already exists (apply the generated schema first);
350
353
  * the `metadata` table is where the version and seed rows live.
351
354
  */
352
355
  declare function initCore(db: Database): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","names":[],"sources":["../../../src/server/supalive-server.ts","../../../src/logger.ts","../../../src/server/subscription-manager.ts","../../../src/server/subscription-manager-client.ts","../../../src/db/init_db.ts","../../../src/server/sub_hash.ts"],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","names":[],"sources":["../../../src/server/supalive-server.ts","../../../src/logger.ts","../../../src/server/subscription-manager.ts","../../../src/server/subscription-manager-client.ts","../../../src/db/init_db.ts","../../../src/server/sub_hash.ts"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { r as evaluateCacheFreshness } from "../../overlap-checker-ClJC0nxW.js";
4
4
  import { i as AuthenticationError, o as ClientMessageSchema } from "../../types_client_rpc-CIsjQQGG.js";
5
5
  import { n as RemoteSubscriptionMessageSchema } from "../../types_server-Dk6o_B7N.js";
6
6
  import { n as sleep } from "../../realtime_db-BtwBABDY.js";
7
- import { C as RetentionWatermark, D as logger, E as logLevelOf, O as serializeMapValue, S as RETENTION_WATERMARK_CHANNEL, T as isProduction, _ as UnregisterSubscriptionResultSchema, a as createDatabase, b as UpdateSubscriptionReadSetParamsSchema, c as initDatabase, d as InvalidateWritesetResultSchema, g as UnregisterSubscriptionParamsSchema, h as RegisterSubscriptionResultSchema, i as bootstrapDbTypes, l as CacheLayer, m as RegisterSubscriptionParamsSchema, n as CORE_VERSION, o as initCacheLayer, p as RegisterSubscriptionBatchResultSchema, r as DB_QUERY_TIMEOUT_MS, s as initCore, u as InvalidateWritesetParamsSchema, w as appInstanceId, x as UpdateSubscriptionReadSetResultSchema, y as UnregisterSubscriptionsResultSchema } from "../../subscription-worker-CAf6MUta.js";
7
+ import { C as RetentionWatermark, D as logger, E as logLevelOf, O as serializeMapValue, S as RETENTION_WATERMARK_CHANNEL, T as isProduction, _ as UnregisterSubscriptionResultSchema, a as createDatabase, b as UpdateSubscriptionReadSetParamsSchema, c as initDatabase, d as InvalidateWritesetResultSchema, g as UnregisterSubscriptionParamsSchema, h as RegisterSubscriptionResultSchema, i as bootstrapDbTypes, l as CacheLayer, m as RegisterSubscriptionParamsSchema, n as CORE_VERSION, o as initCacheLayer, p as RegisterSubscriptionBatchResultSchema, r as DB_QUERY_TIMEOUT_MS, s as initCore, u as InvalidateWritesetParamsSchema, w as appInstanceId, x as UpdateSubscriptionReadSetResultSchema, y as UnregisterSubscriptionsResultSchema } from "../../subscription-worker-B2XtjFWY.js";
8
8
  import { createServer } from "http";
9
9
  import { WebSocket, WebSocketServer } from "ws";
10
10
  import { v4 } from "uuid";
@@ -638,7 +638,9 @@ var HttpRpcHandler = class {
638
638
  const fn = procedure.fn;
639
639
  return fn({
640
640
  db: this.deps.db,
641
- serverCtx
641
+ serverCtx,
642
+ storage: this.deps.storage,
643
+ scheduler: this.deps.scheduler
642
644
  }, input);
643
645
  }
644
646
  async resolveAuth(req) {
@@ -790,6 +792,8 @@ var SupaliveWebSocketServer = class {
790
792
  jobPath;
791
793
  jobClient;
792
794
  rpcHandler;
795
+ /** Optional object storage exposed to every procedure as `ctx.storage`. */
796
+ storage;
793
797
  sessions = /* @__PURE__ */ new Map();
794
798
  serverSubscriptions = /* @__PURE__ */ new Map();
795
799
  subManagerClient;
@@ -812,15 +816,14 @@ var SupaliveWebSocketServer = class {
812
816
  this.cache = config.cacheLayer;
813
817
  this.redisSub = config.redisSubClient;
814
818
  this.db = config.database;
819
+ this.storage = config.storage;
815
820
  this.db.setOnAfterCommit((writeSet, commitTs) => {
816
821
  this.handleMutationCommit(writeSet, commitTs).catch((err) => logger$2.error(err, "post-commit invalidation failed"));
817
822
  });
818
823
  this.scheduler = config.scheduler;
819
824
  this.jobPath = normalizeJobPath(config.jobPath ?? "/_jobs");
820
- if (this.scheduler) {
821
- if (!this.config.publicUrl) throw new Error("publicUrl config is required when a scheduler is configured (used to build job endpoints)");
822
- this.jobClient = new JobClient(this.scheduler, (name) => this.endpointFor(name));
823
- }
825
+ if (!this.config.publicUrl) throw new Error("publicUrl config is required when a scheduler is configured (used to build job endpoints)");
826
+ this.jobClient = new JobClient(this.scheduler, (name) => this.endpointFor(name));
824
827
  this.oneShotDeps = {
825
828
  db: this.db,
826
829
  cache: this.cache,
@@ -832,7 +835,9 @@ var SupaliveWebSocketServer = class {
832
835
  db: this.db,
833
836
  oneShotDeps: this.oneShotDeps,
834
837
  verifyAuth: config.verifyAuth,
835
- rpc: config.rpc
838
+ rpc: config.rpc,
839
+ storage: this.storage,
840
+ scheduler: this.jobClient
836
841
  });
837
842
  this.subManagerClient.setRecoveryDriver(this.runSubManagerRecovery.bind(this));
838
843
  this.subManagerClient.setAffectedHandler(this.runAffectedHandler.bind(this));
@@ -1232,7 +1237,9 @@ var SupaliveWebSocketServer = class {
1232
1237
  const fn = procedure.fn;
1233
1238
  result = await fn({
1234
1239
  db: this.db,
1235
- serverCtx: session.serverCtx
1240
+ serverCtx: session.serverCtx,
1241
+ storage: this.storage,
1242
+ scheduler: this.jobClient
1236
1243
  }, validatedInput);
1237
1244
  } finally {
1238
1245
  session.actionInFlight--;