@rocicorp/zero 1.3.0-canary.3 → 1.4.0-canary.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 (61) hide show
  1. package/out/analyze-query/src/analyze-cli.d.ts +24 -0
  2. package/out/analyze-query/src/analyze-cli.d.ts.map +1 -0
  3. package/out/analyze-query/src/analyze-cli.js +279 -0
  4. package/out/analyze-query/src/analyze-cli.js.map +1 -0
  5. package/out/analyze-query/src/bin-analyze.js +6 -6
  6. package/out/analyze-query/src/bin-transform.js +2 -2
  7. package/out/ast-to-zql/src/bin.js +1 -1
  8. package/out/z2s/src/compiler.d.ts.map +1 -1
  9. package/out/z2s/src/compiler.js +4 -1
  10. package/out/z2s/src/compiler.js.map +1 -1
  11. package/out/z2s/src/sql.d.ts.map +1 -1
  12. package/out/z2s/src/sql.js +1 -0
  13. package/out/z2s/src/sql.js.map +1 -1
  14. package/out/zero/package.js +5 -1
  15. package/out/zero/package.js.map +1 -1
  16. package/out/zero/src/analyze.d.ts +2 -0
  17. package/out/zero/src/analyze.d.ts.map +1 -0
  18. package/out/zero/src/analyze.js +2 -0
  19. package/out/zero-cache/src/server/anonymous-otel-start.js +1 -1
  20. package/out/zero-cache/src/server/change-streamer.js +1 -1
  21. package/out/zero-cache/src/services/analyze.js +1 -1
  22. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  23. package/out/zero-cache/src/services/change-source/pg/change-source.js +17 -21
  24. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  25. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +2 -2
  26. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +1 -1
  27. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +24 -15
  28. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  29. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +35 -58
  30. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  31. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  32. package/out/zero-cache/src/services/change-source/pg/schema/init.js +1 -1
  33. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  34. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +1 -2
  35. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
  36. package/out/zero-cache/src/services/change-source/pg/schema/published.js +15 -18
  37. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  38. package/out/zero-cache/src/services/change-source/protocol/current/data.js +1 -1
  39. package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
  40. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  41. package/out/zero-cache/src/services/litestream/commands.js +12 -6
  42. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  43. package/out/zero-cache/src/services/mutagen/mutagen.js +2 -2
  44. package/out/zero-cache/src/services/statz.js +1 -1
  45. package/out/zero-cache/src/services/view-syncer/cvr-store.js +1 -1
  46. package/out/zero-cache/src/services/view-syncer/cvr.js +1 -1
  47. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +1 -1
  48. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +1 -1
  49. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +1 -1
  50. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  51. package/out/zero-cache/src/workers/syncer.js +1 -1
  52. package/out/zero-client/src/client/inspector/inspector.d.ts +24 -0
  53. package/out/zero-client/src/client/inspector/inspector.d.ts.map +1 -1
  54. package/out/zero-client/src/client/inspector/inspector.js +28 -0
  55. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  56. package/out/zero-client/src/client/inspector/lazy-inspector.d.ts +9 -0
  57. package/out/zero-client/src/client/inspector/lazy-inspector.d.ts.map +1 -1
  58. package/out/zero-client/src/client/inspector/lazy-inspector.js +28 -1
  59. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  60. package/out/zero-client/src/client/version.js +1 -1
  61. package/package.json +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sql.js","names":["#seen","#size"],"sources":["../../../../z2s/src/sql.ts"],"sourcesContent":["import {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {FormatConfig, SQLItem, SQLQuery} from '@databases/sql';\nimport sql, {SQLItemType} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n isPgNumberType,\n isPgStringType,\n} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {LiteralValue} from '../../zero-protocol/src/ast.ts';\nimport type {ServerColumnSchema} from '../../zero-types/src/server-schema.ts';\n\nexport function formatPg(sql: SQLQuery) {\n const format = new ReusingFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatPgInternalConvert(sql: SQLQuery) {\n const format = new SQLConvertFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatSqlite(sql: SQLQuery) {\n const format = new ReusingFormat(escapeSQLiteIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nconst sqlConvert = Symbol('fromJson');\n\nexport type LiteralType = 'boolean' | 'number' | 'string' | 'null';\nexport type PluralLiteralType = Exclude<LiteralType, 'null'>;\n\ntype ColumnSqlConvertArg = {\n [sqlConvert]: 'column';\n type: string;\n value: unknown;\n plural: boolean;\n isEnum: boolean;\n isComparison: boolean;\n};\n\ntype SqlConvertArg =\n | ColumnSqlConvertArg\n | {\n [sqlConvert]: 'literal';\n type: LiteralType;\n value: LiteralValue;\n plural: boolean;\n };\n\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertSingularLiteralArg(\n value: string | boolean | number | null,\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type: value === null ? 'null' : (typeof value as LiteralType),\n value,\n plural: false,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertPluralLiteralArg(\n type: PluralLiteralType,\n value: PluralLiteralType[],\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type,\n value,\n plural: true,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertColumnArg(\n serverColumnSchema: ServerColumnSchema,\n value: unknown,\n plural: boolean,\n isComparison: boolean,\n): SQLQuery {\n return sql.value({\n [sqlConvert]: 'column',\n type: serverColumnSchema.type,\n isEnum: serverColumnSchema.isEnum,\n value,\n plural: plural || serverColumnSchema.isArray,\n isComparison,\n });\n}\n\nclass ReusingFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n if (this.#seen.has(value)) {\n return {\n placeholder: `$${this.#seen.get(value)}`,\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(value, this.#seen.size + 1);\n return {placeholder: `$${this.#seen.size}`, value};\n };\n}\n\nfunction stringify(arg: SqlConvertArg): string | null {\n if (arg.value === null) {\n return null;\n }\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n if (arg[sqlConvert] === 'literal' && arg.type === 'string') {\n return arg.value as unknown as string;\n }\n if (\n arg[sqlConvert] === 'column' &&\n (arg.isEnum || isPgStringType(arg.type))\n ) {\n return arg.value as string;\n }\n return JSON.stringify(arg.value);\n}\n\nclass SQLConvertFormat implements FormatConfig {\n readonly #seen: Map<unknown, Map<string, number>> = new Map();\n #size = 0;\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const byType = this.#seen.get(value.value);\n if (byType?.has(value.type)) {\n return {\n placeholder: createPlaceholder(byType.get(value.type)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#size++;\n if (byType) {\n byType.set(value.type, this.#size);\n } else {\n this.#seen.set(value.value, new Map([[value.type, this.#size]]));\n }\n return {\n placeholder: createPlaceholder(this.#size, value),\n value: stringify(value),\n };\n };\n}\n\nfunction createPlaceholder(index: number, arg: SqlConvertArg) {\n if (arg.type === 'null') {\n assert(arg.value === null, \"Args of type 'null' must have value null\");\n assert(!arg.plural, \"Args of type 'null' must not be plural\");\n return `$${index}`;\n }\n\n if (arg[sqlConvert] === 'literal') {\n const {value} = arg;\n if (Array.isArray(value)) {\n const elType = pgTypeForLiteralType(arg.type);\n return formatPlural(index, `value::${elType}`);\n }\n return `$${index}::text::${pgTypeForLiteralType(arg.type)}`;\n }\n\n const common = formatCommonToSingularAndPlural(index, arg);\n return arg.plural ? formatPlural(index, common) : common;\n}\n\nfunction formatCommonToSingularAndPlural(\n index: number,\n arg: ColumnSqlConvertArg,\n) {\n // Ok, so what is with all the `::text` casts\n // before the final cast?\n // This is to force the statement to describe its arguments\n // as being text. Without the text cast the args are described as\n // being bool/json/numeric/whatever and the bindings try to coerce\n // the inputs to those types.\n const valuePlaceholder = arg.plural ? 'value' : `$${index}`;\n let atTimeZone = ` AT TIME ZONE 'UTC'`;\n switch (arg.type) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timestamp with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'date':\n case 'timestamp':\n case 'timestamp without time zone':\n return `to_timestamp(${valuePlaceholder}::text::numeric / 1000.0)${atTimeZone}`;\n\n case 'timetz':\n // @ts-expect-error Fallthrough intended\n case 'time with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'time':\n case 'time without time zone':\n return `(${valuePlaceholder}::text::int * interval'1ms')::time${atTimeZone}`;\n\n // uuid: cast to native uuid type for proper comparison and index usage\n case 'uuid':\n return `${valuePlaceholder}::text::uuid`;\n }\n if (arg.isEnum) {\n return `${valuePlaceholder}::text::\"${arg.type}\"`;\n }\n if (isPgStringType(arg.type)) {\n // For comparison cast to the general `text` type, not the\n // specific column type (i.e. `arg.type`), because we don't want to\n // force the value being compared to the size/max-size of the column\n // type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgNumberType(arg.type)) {\n // For comparison cast to `double precision` which uses IEEE 754 (the same\n // representation as JavaScript numbers which will accurately\n // represent any number value from zql) not the specific column type\n // (i.e. `arg.type`), because we don't want to force the value being\n // compared to the range and precision of the column type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text::double precision`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n return `${valuePlaceholder}::text::${arg.type}`;\n}\n\nfunction formatPlural(index: number, select: string) {\n return `ARRAY(\n SELECT ${select} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n}\n\nfunction pgTypeForLiteralType(type: Exclude<LiteralType, 'null'>) {\n switch (type) {\n case 'boolean':\n return 'boolean';\n case 'number':\n // `double precision` uses IEEE 754, the same representation as JavaScript\n // numbers, and so this will accurately represent any number value\n // from zql\n return 'double precision';\n case 'string':\n return 'text';\n default:\n unreachable(type);\n }\n}\n\nexport {sql};\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\n\nconst whitespacePrefixRe = /^\\s*/;\n\nfunction formatFn(\n items: readonly SQLItem[],\n {escapeIdentifier, formatValue}: FormatConfig,\n): {\n text: string;\n values: unknown[];\n} {\n // Create an empty query object.\n let text = '';\n const values = [];\n\n const localIdentifiers = new Map<unknown, string>();\n\n for (const item of items) {\n switch (item.type) {\n // If this is just raw text, we add it directly to the query text.\n case SQLItemType.RAW: {\n text += item.text;\n break;\n }\n\n // If we got a value SQL item, add a placeholder and add the value to our\n // placeholder values array.\n case SQLItemType.VALUE: {\n const {placeholder, value} = formatValue(item.value, values.length);\n text += placeholder;\n if (value !== PREVIOUSLY_SEEN_VALUE) {\n values.push(value);\n }\n\n break;\n }\n\n // If we got an identifier type, escape the strings and get a local\n // identifier for non-string identifiers.\n case SQLItemType.IDENTIFIER: {\n // This is a specific addition for Zero as Zero\n // does not support dots in identifiers.\n // If a dot is found, we assume it is a namespace\n // and split the identifier into its parts.\n const names =\n item.names.length === 1 &&\n typeof item.names[0] === 'string' &&\n item.names[0].includes('.')\n ? item.names[0].split('.')\n : item.names;\n\n text += names\n .map((name): string => {\n if (typeof name === 'string') return escapeIdentifier(name);\n\n if (!localIdentifiers.has(name)) {\n localIdentifiers.set(name, `__local_${localIdentifiers.size}__`);\n }\n\n return escapeIdentifier(localIdentifiers.get(name)!);\n })\n .join('.');\n break;\n }\n }\n }\n\n if (text.trim()) {\n const lines = text.split('\\n');\n const min = Math.min(\n ...lines\n .filter(l => l.trim() !== '')\n .map(l => whitespacePrefixRe.exec(l)![0].length),\n );\n if (min) {\n text = lines.map(line => line.substr(min)).join('\\n');\n }\n }\n return {\n text: text.trim(),\n values,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sql.js","names":["#seen","#size"],"sources":["../../../../z2s/src/sql.ts"],"sourcesContent":["import {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {FormatConfig, SQLItem, SQLQuery} from '@databases/sql';\nimport sql, {SQLItemType} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n isPgNumberType,\n isPgStringType,\n} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {LiteralValue} from '../../zero-protocol/src/ast.ts';\nimport type {ServerColumnSchema} from '../../zero-types/src/server-schema.ts';\n\nexport function formatPg(sql: SQLQuery) {\n const format = new ReusingFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatPgInternalConvert(sql: SQLQuery) {\n const format = new SQLConvertFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatSqlite(sql: SQLQuery) {\n const format = new ReusingFormat(escapeSQLiteIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nconst sqlConvert = Symbol('fromJson');\n\nexport type LiteralType = 'boolean' | 'number' | 'string' | 'null';\nexport type PluralLiteralType = Exclude<LiteralType, 'null'>;\n\ntype ColumnSqlConvertArg = {\n [sqlConvert]: 'column';\n type: string;\n value: unknown;\n plural: boolean;\n isEnum: boolean;\n isComparison: boolean;\n};\n\ntype SqlConvertArg =\n | ColumnSqlConvertArg\n | {\n [sqlConvert]: 'literal';\n type: LiteralType;\n value: LiteralValue;\n plural: boolean;\n };\n\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertSingularLiteralArg(\n value: string | boolean | number | null,\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type: value === null ? 'null' : (typeof value as LiteralType),\n value,\n plural: false,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertPluralLiteralArg(\n type: PluralLiteralType,\n value: PluralLiteralType[],\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type,\n value,\n plural: true,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertColumnArg(\n serverColumnSchema: ServerColumnSchema,\n value: unknown,\n plural: boolean,\n isComparison: boolean,\n): SQLQuery {\n return sql.value({\n [sqlConvert]: 'column',\n type: serverColumnSchema.type,\n isEnum: serverColumnSchema.isEnum,\n value,\n plural: plural || serverColumnSchema.isArray,\n isComparison,\n });\n}\n\nclass ReusingFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n if (this.#seen.has(value)) {\n return {\n placeholder: `$${this.#seen.get(value)}`,\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(value, this.#seen.size + 1);\n return {placeholder: `$${this.#seen.size}`, value};\n };\n}\n\nfunction stringify(arg: SqlConvertArg): string | null {\n if (arg.value === null) {\n return null;\n }\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n if (arg[sqlConvert] === 'literal' && arg.type === 'string') {\n return arg.value as unknown as string;\n }\n if (\n arg[sqlConvert] === 'column' &&\n (arg.isEnum || isPgStringType(arg.type))\n ) {\n return arg.value as string;\n }\n return JSON.stringify(arg.value);\n}\n\nclass SQLConvertFormat implements FormatConfig {\n readonly #seen: Map<unknown, Map<string, number>> = new Map();\n #size = 0;\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const byType = this.#seen.get(value.value);\n if (byType?.has(value.type)) {\n return {\n placeholder: createPlaceholder(byType.get(value.type)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#size++;\n if (byType) {\n byType.set(value.type, this.#size);\n } else {\n this.#seen.set(value.value, new Map([[value.type, this.#size]]));\n }\n return {\n placeholder: createPlaceholder(this.#size, value),\n value: stringify(value),\n };\n };\n}\n\nfunction createPlaceholder(index: number, arg: SqlConvertArg) {\n if (arg.type === 'null') {\n assert(arg.value === null, \"Args of type 'null' must have value null\");\n assert(!arg.plural, \"Args of type 'null' must not be plural\");\n return `$${index}`;\n }\n\n if (arg.value === null && arg.plural) {\n return `$${index}`;\n }\n\n if (arg[sqlConvert] === 'literal') {\n const {value} = arg;\n if (Array.isArray(value)) {\n const elType = pgTypeForLiteralType(arg.type);\n return formatPlural(index, `value::${elType}`);\n }\n return `$${index}::text::${pgTypeForLiteralType(arg.type)}`;\n }\n\n const common = formatCommonToSingularAndPlural(index, arg);\n return arg.plural ? formatPlural(index, common) : common;\n}\n\nfunction formatCommonToSingularAndPlural(\n index: number,\n arg: ColumnSqlConvertArg,\n) {\n // Ok, so what is with all the `::text` casts\n // before the final cast?\n // This is to force the statement to describe its arguments\n // as being text. Without the text cast the args are described as\n // being bool/json/numeric/whatever and the bindings try to coerce\n // the inputs to those types.\n const valuePlaceholder = arg.plural ? 'value' : `$${index}`;\n let atTimeZone = ` AT TIME ZONE 'UTC'`;\n switch (arg.type) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timestamp with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'date':\n case 'timestamp':\n case 'timestamp without time zone':\n return `to_timestamp(${valuePlaceholder}::text::numeric / 1000.0)${atTimeZone}`;\n\n case 'timetz':\n // @ts-expect-error Fallthrough intended\n case 'time with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'time':\n case 'time without time zone':\n return `(${valuePlaceholder}::text::int * interval'1ms')::time${atTimeZone}`;\n\n // uuid: cast to native uuid type for proper comparison and index usage\n case 'uuid':\n return `${valuePlaceholder}::text::uuid`;\n }\n if (arg.isEnum) {\n return `${valuePlaceholder}::text::\"${arg.type}\"`;\n }\n if (isPgStringType(arg.type)) {\n // For comparison cast to the general `text` type, not the\n // specific column type (i.e. `arg.type`), because we don't want to\n // force the value being compared to the size/max-size of the column\n // type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgNumberType(arg.type)) {\n // For comparison cast to `double precision` which uses IEEE 754 (the same\n // representation as JavaScript numbers which will accurately\n // represent any number value from zql) not the specific column type\n // (i.e. `arg.type`), because we don't want to force the value being\n // compared to the range and precision of the column type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text::double precision`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n return `${valuePlaceholder}::text::${arg.type}`;\n}\n\nfunction formatPlural(index: number, select: string) {\n return `ARRAY(\n SELECT ${select} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n}\n\nfunction pgTypeForLiteralType(type: Exclude<LiteralType, 'null'>) {\n switch (type) {\n case 'boolean':\n return 'boolean';\n case 'number':\n // `double precision` uses IEEE 754, the same representation as JavaScript\n // numbers, and so this will accurately represent any number value\n // from zql\n return 'double precision';\n case 'string':\n return 'text';\n default:\n unreachable(type);\n }\n}\n\nexport {sql};\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\n\nconst whitespacePrefixRe = /^\\s*/;\n\nfunction formatFn(\n items: readonly SQLItem[],\n {escapeIdentifier, formatValue}: FormatConfig,\n): {\n text: string;\n values: unknown[];\n} {\n // Create an empty query object.\n let text = '';\n const values = [];\n\n const localIdentifiers = new Map<unknown, string>();\n\n for (const item of items) {\n switch (item.type) {\n // If this is just raw text, we add it directly to the query text.\n case SQLItemType.RAW: {\n text += item.text;\n break;\n }\n\n // If we got a value SQL item, add a placeholder and add the value to our\n // placeholder values array.\n case SQLItemType.VALUE: {\n const {placeholder, value} = formatValue(item.value, values.length);\n text += placeholder;\n if (value !== PREVIOUSLY_SEEN_VALUE) {\n values.push(value);\n }\n\n break;\n }\n\n // If we got an identifier type, escape the strings and get a local\n // identifier for non-string identifiers.\n case SQLItemType.IDENTIFIER: {\n // This is a specific addition for Zero as Zero\n // does not support dots in identifiers.\n // If a dot is found, we assume it is a namespace\n // and split the identifier into its parts.\n const names =\n item.names.length === 1 &&\n typeof item.names[0] === 'string' &&\n item.names[0].includes('.')\n ? item.names[0].split('.')\n : item.names;\n\n text += names\n .map((name): string => {\n if (typeof name === 'string') return escapeIdentifier(name);\n\n if (!localIdentifiers.has(name)) {\n localIdentifiers.set(name, `__local_${localIdentifiers.size}__`);\n }\n\n return escapeIdentifier(localIdentifiers.get(name)!);\n })\n .join('.');\n break;\n }\n }\n }\n\n if (text.trim()) {\n const lines = text.split('\\n');\n const min = Math.min(\n ...lines\n .filter(l => l.trim() !== '')\n .map(l => whitespacePrefixRe.exec(l)![0].length),\n );\n if (min) {\n text = lines.map(line => line.substr(min)).join('\\n');\n }\n }\n return {\n text: text.trim(),\n values,\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  var package_default = {
2
2
  name: "@rocicorp/zero",
3
- version: "1.3.0-canary.3",
3
+ version: "1.4.0-canary.0",
4
4
  description: "Zero is a web framework for serverless web development.",
5
5
  homepage: "https://zero.rocicorp.dev",
6
6
  bugs: { "url": "https://bugs.rocicorp.dev" },
@@ -31,6 +31,10 @@ var package_default = {
31
31
  "types": "./out/zero/src/zero.d.ts",
32
32
  "default": "./out/zero/src/zero.js"
33
33
  },
34
+ "./analyze": {
35
+ "types": "./out/zero/src/analyze.d.ts",
36
+ "default": "./out/zero/src/analyze.js"
37
+ },
34
38
  "./bindings": {
35
39
  "types": "./out/zero/src/bindings.d.ts",
36
40
  "default": "./out/zero/src/bindings.js"
@@ -1 +1 @@
1
- {"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.3.0-canary.3\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --type-aware src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.203.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.62.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.203.0\",\n \"@opentelemetry/resources\": \"^2.0.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.0.1\",\n \"@opentelemetry/sdk-node\": \"^0.203.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.0.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^5.4.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.0.17\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.0\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"js-xxhash\": \"^4.0.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.45.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"tsx\": \"^4.21.0\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"@vitest/runner\": \"4.1.3\",\n \"analyze-query\": \"0.0.0\",\n \"ast-to-zql\": \"0.0.0\",\n \"expo-sqlite\": \">=15\",\n \"replicache\": \"15.2.1\",\n \"shared\": \"0.0.0\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typedoc-plugin-markdown\": \"^4.10.0\",\n \"typescript\": \"~6.0.2\",\n \"vite\": \"8.0.3\",\n \"vitest\": \"4.1.3\",\n \"zero-cache\": \"0.0.0\",\n \"zero-client\": \"0.0.0\",\n \"zero-pg\": \"0.0.0\",\n \"zero-protocol\": \"0.0.0\",\n \"zero-react\": \"0.0.0\",\n \"zero-server\": \"0.0.0\",\n \"zero-solid\": \"0.0.0\",\n \"zqlite\": \"0.0.0\"\n },\n \"peerDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"expo-sqlite\": \">=15\"\n },\n \"peerDependenciesMeta\": {\n \"expo-sqlite\": {\n \"optional\": true\n },\n \"@op-engineering/op-sqlite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=22\"\n }\n}"],"mappings":""}
1
+ {"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.4.0-canary.0\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./analyze\": {\n \"types\": \"./out/zero/src/analyze.d.ts\",\n \"default\": \"./out/zero/src/analyze.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --type-aware src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.203.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.62.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.203.0\",\n \"@opentelemetry/resources\": \"^2.0.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.0.1\",\n \"@opentelemetry/sdk-node\": \"^0.203.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.0.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^5.4.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.0.17\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.0\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"js-xxhash\": \"^4.0.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.45.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"tsx\": \"^4.21.0\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"@vitest/runner\": \"4.1.3\",\n \"analyze-query\": \"0.0.0\",\n \"ast-to-zql\": \"0.0.0\",\n \"expo-sqlite\": \">=15\",\n \"replicache\": \"15.2.1\",\n \"shared\": \"0.0.0\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typedoc-plugin-markdown\": \"^4.10.0\",\n \"typescript\": \"~6.0.2\",\n \"vite\": \"8.0.3\",\n \"vitest\": \"4.1.3\",\n \"zero-cache\": \"0.0.0\",\n \"zero-client\": \"0.0.0\",\n \"zero-pg\": \"0.0.0\",\n \"zero-protocol\": \"0.0.0\",\n \"zero-react\": \"0.0.0\",\n \"zero-server\": \"0.0.0\",\n \"zero-solid\": \"0.0.0\",\n \"zqlite\": \"0.0.0\"\n },\n \"peerDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"expo-sqlite\": \">=15\"\n },\n \"peerDependenciesMeta\": {\n \"expo-sqlite\": {\n \"optional\": true\n },\n \"@op-engineering/op-sqlite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=22\"\n }\n}"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export { runAnalyzeCLI, type AnalyzeCLIOptions, } from '../../analyze-query/src/analyze-cli.ts';
2
+ //# sourceMappingURL=analyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../../src/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,wCAAwC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { runAnalyzeCLI } from "../../analyze-query/src/analyze-cli.js";
2
+ export { runAnalyzeCLI };
@@ -1,8 +1,8 @@
1
1
  import { h64 } from "../../../shared/src/hash.js";
2
2
  import { getServerVersion, getZeroConfig } from "../config/zero-config.js";
3
3
  import { setupOtelDiagnosticLogger } from "./otel-diag-logger.js";
4
- import "@opentelemetry/api";
5
4
  import { homedir, platform } from "os";
5
+ import "@opentelemetry/api";
6
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
7
7
  import { resourceFromAttributes } from "@opentelemetry/resources";
8
8
  import { execSync } from "child_process";
@@ -1,9 +1,9 @@
1
1
  import { assert } from "../../../shared/src/asserts.js";
2
2
  import { must } from "../../../shared/src/must.js";
3
- import { DatabaseInitError } from "../../../zqlite/src/db.js";
4
3
  import { parentWorker, singleProcessMode } from "../types/processes.js";
5
4
  import { getShardConfig } from "../types/shards.js";
6
5
  import { getNormalizedZeroConfig } from "../config/zero-config.js";
6
+ import { DatabaseInitError } from "../../../zqlite/src/db.js";
7
7
  import { pgClient } from "../types/pg.js";
8
8
  import { exitAfter, runUntilKilled } from "../services/life-cycle.js";
9
9
  import { createLogContext } from "./logging.js";
@@ -1,8 +1,8 @@
1
1
  import { MemoryStorage } from "../../../zql/src/ivm/memory-storage.js";
2
2
  import { AccumulatorDebugger, serializePlanDebugEvents } from "../../../zql/src/planner/planner-debug.js";
3
+ import { Debug } from "../../../zql/src/builder/debug-delegate.js";
3
4
  import { Database } from "../../../zqlite/src/db.js";
4
5
  import { TableSource } from "../../../zqlite/src/table-source.js";
5
- import { Debug } from "../../../zql/src/builder/debug-delegate.js";
6
6
  import { computeZqlSpecs, mustGetTableSpec } from "../db/lite-tables.js";
7
7
  import { createSQLiteCostModel } from "../../../zqlite/src/sqlite-cost-model.js";
8
8
  import { runAst } from "./run-ast.js";
@@ -1 +1 @@
1
- {"version":3,"file":"change-source.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAejD,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AAOzD,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,KAAK,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAGhE,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,wCAAwC,CAAC;AAchD,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAGV,eAAe,IAAI,gBAAgB,EACpC,MAAM,yCAAyC,CAAC;AA2BjD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,UAAU,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,aAAa,EACtB,mBAAmB,SAAI,GACtB,OAAO,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,CAAC,CAsC7E;AAqcD,qBAAa,KAAM,YAAW,QAAQ;;gBAIxB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAI9B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAgC3C,GAAG,CAAC,SAAS,EAAE,WAAW;CAoB3B;AAED,QAAA,MAAM,eAAe;;;;aAInB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAmwBxD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,gBAAgB,WAwB3E"}
1
+ {"version":3,"file":"change-source.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAejD,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AAOzD,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,KAAK,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAGhE,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,wCAAwC,CAAC;AAchD,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAGV,eAAe,IAAI,gBAAgB,EACpC,MAAM,yCAAyC,CAAC;AAuBjD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,UAAU,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,aAAa,EACtB,mBAAmB,SAAI,GACtB,OAAO,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,CAAC,CAsC7E;AAqcD,qBAAa,KAAM,YAAW,QAAQ;;gBAIxB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAI9B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAgC3C,GAAG,CAAC,SAAS,EAAE,WAAW;CAoB3B;AAED,QAAA,MAAM,eAAe;;;;aAInB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AA2wBxD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,gBAAgB,WAwB3E"}
@@ -7,8 +7,8 @@ import { must } from "../../../../../shared/src/must.js";
7
7
  import { mapValues } from "../../../../../shared/src/objects.js";
8
8
  import { equals, intersection, symmetricDifferences } from "../../../../../shared/src/set-utils.js";
9
9
  import { stringify } from "../../../../../shared/src/bigint-json.js";
10
- import { Database } from "../../../../../zqlite/src/db.js";
11
10
  import { upstreamSchema } from "../../../types/shards.js";
11
+ import { Database } from "../../../../../zqlite/src/db.js";
12
12
  import { UnsupportedColumnDefaultError, mapPostgresToLiteColumn } from "../../../db/pg-to-lite.js";
13
13
  import { getSubscriptionStateAndContext } from "../../replicator/schema/replication-state.js";
14
14
  import { StatementRunner } from "../../../db/statements.js";
@@ -29,8 +29,8 @@ import { updateShardSchema } from "./schema/init.js";
29
29
  import { initialSync } from "./initial-sync.js";
30
30
  import { streamBackfill } from "./backfill-stream.js";
31
31
  import { subscribe } from "./logical-replication/stream.js";
32
- import postgres from "postgres";
33
32
  import { nanoid } from "nanoid";
33
+ import postgres from "postgres";
34
34
  import { PG_ADMIN_SHUTDOWN, PG_INSUFFICIENT_PRIVILEGE, PG_OBJECT_IN_USE } from "@drdgvhbh/postgres-error-codes";
35
35
  //#region ../zero-cache/src/services/change-source/pg/change-source.ts
36
36
  /**
@@ -561,7 +561,7 @@ var ChangeMaker = class {
561
561
  return [];
562
562
  }
563
563
  case "commit":
564
- this.#lastSnapshotInTx = void 0;
564
+ this.#lastReplicationEventInTx = void 0;
565
565
  return [[
566
566
  "commit",
567
567
  msg,
@@ -573,34 +573,30 @@ var ChangeMaker = class {
573
573
  default: throw new Error(`Unexpected message type ${stringify(msg)}`);
574
574
  }
575
575
  }
576
- #preSchema;
577
- #lastSnapshotInTx;
576
+ #lastReplicationEventInTx;
578
577
  #handleDdlMessage(msg) {
579
578
  const event = parseLogicalMessageContent(msg, replicationEventSchema);
580
579
  clearTimeout(this.#replicaIdentityTimer);
581
- let previousSchema;
580
+ let prevEvent = this.#lastReplicationEventInTx;
582
581
  const { type } = event;
583
582
  switch (type) {
584
583
  case "ddlStart":
585
- this.#preSchema = event.schema;
586
- return [];
584
+ case "schemaSnapshot": break;
587
585
  case "ddlUpdate":
588
- previousSchema = must(this.#preSchema, `ddlUpdate received without a ddlStart`);
589
- break;
590
- case "schemaSnapshot":
591
- previousSchema = this.#lastSnapshotInTx ?? null;
586
+ assert(prevEvent, `ddlUpdate received without a ddlStart`);
592
587
  break;
593
588
  default:
594
589
  this.#lc.info?.(`ignoring unknown ddl message type: ${type}`);
595
590
  return [];
596
591
  }
597
- this.#lastSnapshotInTx = event.schema;
598
- if (!previousSchema) {
599
- this.#lc.info?.(`received ${msg.prefix}/${type} event`);
592
+ this.#lastReplicationEventInTx = event;
593
+ if (!prevEvent) {
594
+ this.#lc.info?.(`received ${msg.prefix}/${type} event`, event);
600
595
  return [];
601
596
  }
602
597
  this.#lc.info?.(`processing ${msg.prefix}/${type} event`, event);
603
- const changes = this.#makeSchemaChanges(previousSchema, event).map((change) => ["data", change]);
598
+ const effectiveTag = prevEvent.type === "ddlStart" ? prevEvent.event.tag : event.event.tag;
599
+ const changes = this.#makeSchemaChanges(prevEvent.schema, event, effectiveTag).map((change) => ["data", change]);
604
600
  this.#lc.withContext("tag", event.event.tag).withContext("query", event.context.query).info?.(`${changes.length} schema change(s)`, { changes });
605
601
  const replicaIdentities = replicaIdentitiesForTablesWithoutPrimaryKeys(event.schema);
606
602
  if (replicaIdentities) this.#replicaIdentityTimer = setTimeout(async () => {
@@ -639,10 +635,10 @@ var ChangeMaker = class {
639
635
  * columns. This, for example, would be needed to properly support changing
640
636
  * the type of a column that's indexed.
641
637
  */
642
- #makeSchemaChanges(preSchema, update) {
638
+ #makeSchemaChanges(preSchema, event, tag) {
643
639
  try {
644
640
  const [prevTbl, prevIdx] = specsByID(preSchema);
645
- const [nextTbl, nextIdx] = specsByID(update.schema);
641
+ const [nextTbl, nextIdx] = specsByID(event.schema);
646
642
  const changes = [];
647
643
  for (const table of nextTbl.values()) validate(this.#lc, table);
648
644
  const [droppedIdx, createdIdx] = symmetricDifferences(prevIdx, nextIdx);
@@ -673,7 +669,7 @@ var ChangeMaker = class {
673
669
  });
674
670
  }
675
671
  const tables = intersection(prevTbl, nextTbl);
676
- for (const id of tables) changes.push(...this.#getTableChanges(must(prevTbl.get(id)), must(nextTbl.get(id)), update.event.tag));
672
+ for (const id of tables) changes.push(...this.#getTableChanges(must(prevTbl.get(id)), must(nextTbl.get(id)), tag));
677
673
  for (const id of createdTbl) {
678
674
  const spec = must(nextTbl.get(id));
679
675
  const createTable = {
@@ -681,7 +677,7 @@ var ChangeMaker = class {
681
677
  spec,
682
678
  metadata: getMetadata(spec)
683
679
  };
684
- if (!update.event.tag.startsWith("CREATE")) createTable.backfill = mapValues(spec.columns, ({ pos: attNum }) => ({ attNum }));
680
+ if (!tag.startsWith("CREATE")) createTable.backfill = mapValues(spec.columns, ({ pos: attNum }) => ({ attNum }));
685
681
  changes.push(createTable);
686
682
  }
687
683
  for (const id of createdIdx) {
@@ -693,7 +689,7 @@ var ChangeMaker = class {
693
689
  }
694
690
  return changes;
695
691
  } catch (e) {
696
- throw new UnsupportedSchemaChangeError(String(e), update, { cause: e });
692
+ throw new UnsupportedSchemaChangeError(String(e), event, { cause: e });
697
693
  }
698
694
  }
699
695
  #getTableChanges(oldTable, newTable, ddlTag) {