@rocicorp/zero 1.12.0-canary.5 → 1.12.0-canary.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/replicache/src/btree/node.js +1 -1
- package/out/replicache/src/deleted-clients.d.ts.map +1 -1
- package/out/replicache/src/deleted-clients.js +2 -1
- package/out/replicache/src/deleted-clients.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +7 -3
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +17 -14
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/z2s/src/compiler.js +3 -3
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/zero/package.js +2 -2
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +2 -2
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +32 -9
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/change-source.d.ts +7 -0
- package/out/zero-cache/src/services/change-source/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +25 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +8 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +33 -16
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +12 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +64 -7
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/fork-request.d.ts +57 -0
- package/out/zero-cache/src/services/change-source/pg/fork-request.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/fork-request.js +54 -0
- package/out/zero-cache/src/services/change-source/pg/fork-request.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +6 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts +3 -0
- package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/status.js +2 -1
- package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +1 -3
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -6
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +41 -2
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +55 -20
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +9 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +27 -8
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +1 -12
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +29 -2
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +80 -11
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts +2 -2
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts +2 -2
- package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/server-start-metrics.d.ts +33 -0
- package/out/zero-cache/src/services/change-streamer/server-start-metrics.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/server-start-metrics.js +42 -0
- package/out/zero-cache/src/services/change-streamer/server-start-metrics.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +17 -6
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +5 -4
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +2 -1
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +27 -27
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","names":["parseBigIntJson"],"sources":["../../../../z2s/src/compiler.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {last, zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n parse as parseBigIntJson,\n type JSONValue as BigIntJSONValue,\n} from '../../shared/src/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Bound,\n Condition,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Correlation,\n LiteralReference,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n clientToServer,\n type NameMapper,\n} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../zero-types/src/server-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {completeOrdering} from '../../zql/src/query/complete-ordering.ts';\nimport {\n sql,\n sqlConvertColumnArg,\n sqlConvertPluralLiteralArg,\n sqlConvertSingularLiteralArg,\n type PluralLiteralType,\n} from './sql.ts';\n\ntype Table = {\n zql: string;\n alias: string;\n};\n\ntype QualifiedColumn = {\n table: Table;\n zql: string;\n};\n\ntype ServerSpec = {\n schema: ServerSchema;\n // maps zql names to server names\n mapper: NameMapper;\n};\n\nexport type Spec = {\n server: ServerSpec;\n zql: Schema['tables'];\n aliasCount: number;\n};\n\nconst ZQL_RESULT_KEY = 'zql_result';\nconst ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);\n\nconst ZQL_RESULT_TABLE_KEY = 'zql_root';\nconst ZQL_RESULT_TABLE_IDENT = sql.ident(ZQL_RESULT_TABLE_KEY);\n\nexport function compile(\n serverSchema: ServerSchema,\n zqlSchema: Schema,\n ast: AST,\n format?: Format,\n): SQLQuery {\n ast = completeOrdering(\n ast,\n tableName => zqlSchema.tables[tableName].primaryKey,\n );\n const spec: Spec = {\n aliasCount: 0,\n server: {\n schema: serverSchema,\n mapper: clientToServer(zqlSchema.tables),\n },\n zql: zqlSchema.tables,\n };\n return sql`SELECT \n ${toJSON(ZQL_RESULT_TABLE_KEY, format?.singular)}::text AS ${ZQL_RESULT_KEY_IDENT}\n FROM (${select(spec, ast, format)}) ${ZQL_RESULT_TABLE_IDENT}`;\n}\n\nfunction select(\n spec: Spec,\n ast: AST,\n format: Format | undefined,\n correlate?: (childTable: Table) => SQLQuery,\n): SQLQuery {\n const table = makeTable(spec, ast.table);\n const selectionSet = related(spec, ast.related ?? [], format, table);\n const tableSchema = spec.zql[ast.table];\n const usedAliases = new Set<string>(\n ast.related?.map(r => r.subquery.alias ?? ''),\n );\n for (const column of Object.keys(tableSchema.columns)) {\n if (!usedAliases.has(column)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table,\n zql: column,\n }),\n );\n }\n }\n\n let appliedWhere = false;\n function maybeWhere(test: unknown) {\n if (!test) {\n return sql``;\n }\n\n const ret = appliedWhere ? sql`AND` : sql`WHERE`;\n appliedWhere = true;\n return ret;\n }\n\n return sql`SELECT ${sql.join(selectionSet, ',')}\n FROM ${fromIdent(spec.server, table)}\n ${maybeWhere(ast.where)} ${where(spec, ast.where, table)}${\n ast.start\n ? sql`\n ${maybeWhere(ast.start)} ${start(spec, ast.start, ast.orderBy, table)}`\n : sql``\n }\n ${maybeWhere(correlate)} ${correlate ? correlate(table) : sql``}\n ${orderBy(spec, ast.orderBy, table)}\n ${limit(ast.limit, format?.singular)}`;\n}\n\nexport function limit(\n limit: number | undefined,\n singular: boolean | undefined,\n): SQLQuery {\n if (limit === 0) {\n return sql`LIMIT 0`;\n }\n if (singular) {\n return sql`LIMIT 1`;\n }\n if (limit === undefined) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertSingularLiteralArg(limit)}`;\n}\n\nfunction makeTable(spec: Spec, zql: string, alias?: string): Table {\n alias = alias ?? zql + '_' + spec.aliasCount++;\n return {\n zql,\n alias,\n };\n}\n\nexport function orderBy(\n spec: Spec,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!orderBy) {\n return sql``;\n }\n return sql`ORDER BY ${sql.join(\n orderBy.map(([col, dir]) =>\n dir === 'asc'\n ? // Oh postgres. The table must be referred to by client name but the column by server name.\n // E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`\n sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} ASC NULLS FIRST`\n : sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} DESC NULLS LAST`,\n ),\n ', ',\n )}`;\n}\n\nexport function start(\n spec: Spec,\n bound: Bound | undefined,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!bound) {\n return sql``;\n }\n assert(\n orderBy !== undefined && orderBy.length > 0,\n 'start requires ordering',\n );\n\n const constraints: SQLQuery[] = [];\n for (let i = 0; i < orderBy.length; i++) {\n const group: SQLQuery[] = [];\n const [iField, iDirection] = orderBy[i];\n for (let j = 0; j <= i; j++) {\n const [field] = orderBy[j];\n if (j === i) {\n group.push(\n startRangeComparison(\n spec,\n table,\n iField,\n bound.row[iField] ?? null,\n iDirection === 'asc' ? '>' : '<',\n ),\n );\n } else {\n group.push(startEquality(spec, table, field, bound.row[field] ?? null));\n }\n }\n constraints.push(sql`(${sql.join(group, ' AND ')})`);\n }\n\n if (!bound.exclusive) {\n constraints.push(\n sql`(${sql.join(\n orderBy.map(([field]) =>\n startEquality(spec, table, field, bound.row[field] ?? null),\n ),\n ' AND ',\n )})`,\n );\n }\n\n return sql`(${sql.join(constraints, ' OR ')})`;\n}\n\nfunction related(\n spec: Spec,\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery[] {\n return relationships.map(relationship =>\n relationshipSubquery(\n spec,\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n}\n\nfunction relationshipSubquery(\n spec: Spec,\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery {\n const innerAlias = `inner_${relationship.subquery.alias}`;\n if (relationship.hidden) {\n const {join, participatingTables} = makeJunctionJoin(spec, relationship);\n const lastTable = must(last(participatingTables)).table;\n\n assert(\n relationship.subquery.related,\n 'hidden relationship must be a junction',\n );\n const nestedAst = relationship.subquery.related[0].subquery;\n const selectionSet = related(\n spec,\n nestedAst.related ?? [],\n format,\n lastTable,\n );\n const tableSchema = spec.zql[nestedAst.table];\n for (const column of Object.keys(tableSchema.columns)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table: lastTable,\n zql: column,\n }),\n );\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (SELECT ${sql.join(\n selectionSet,\n ',',\n )} FROM ${join} WHERE (${makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n )(participatingTables[0].table)}) ${\n nestedAst.where\n ? sql`AND ${where(spec, nestedAst.where, lastTable)}`\n : sql``\n }${\n nestedAst.start\n ? sql` AND ${start(\n spec,\n nestedAst.start,\n nestedAst.orderBy,\n lastTable,\n )}`\n : sql``\n } ${orderBy(spec, nestedAst.orderBy, lastTable)} ${limit(\n last(participatingTables)?.limit,\n format?.singular,\n )} ) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (${select(\n spec,\n relationship.subquery,\n format,\n makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n}\n\nfunction where(\n spec: Spec,\n condition: Condition | undefined,\n table: Table,\n): SQLQuery {\n if (!condition) {\n return sql``;\n }\n\n switch (condition.type) {\n case 'and':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n // `scalar` is deliberately ignored here. It is a planner hint for the\n // IVM engines, which have no cost-based planner and benefit from\n // pre-resolving an at-most-one-row subquery to a literal comparison\n // (see zqlite's `resolveSimpleScalarSubqueries`). Postgres decorrelates\n // EXISTS into a semi-join on its own, so the hint buys nothing here —\n // and honoring it as `parentField = (SELECT childField … LIMIT 1)` is\n // only sound when the subquery matches at most one row *globally*.\n // Applying it unconditionally silently dropped rows whenever the\n // subquery was not pinned to a unique key.\n return exists(spec, condition, table);\n case 'simple':\n return simple(spec, condition, table);\n }\n}\n\nfunction exists(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n }\n}\n\nexport function makeCorrelator(\n spec: Spec,\n parentFields: readonly QualifiedColumn[],\n childZqlFields: readonly string[],\n): (childTable: Table) => SQLQuery {\n return (childTable: Table) => {\n const childFields = childZqlFields.map(zqlField => ({\n table: childTable,\n zql: zqlField,\n }));\n return sql.join(\n zip(parentFields, childFields).map(\n ([parentColumn, childColumn]) =>\n sql`${colIdent(spec.server, parentColumn)} = ${colIdent(\n spec.server,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n };\n}\n\nexport function simple(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE': {\n // The pattern is a string, not a value of the column's type. Converted\n // to the `bpchar` of a `char(n)` column it would lose its trailing\n // spaces. Like ZQL's own LIKE, non-string patterns match as strings.\n const {right} = condition;\n assert(\n right.type === 'literal',\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${sqlConvertSingularLiteralArg(\n right.value === null ? null : String(right.value),\n )}`;\n }\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n condition.right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(\n spec,\n condition.right,\n table,\n condition.left,\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return any(spec, condition, table);\n case 'IS':\n case 'IS NOT':\n return distinctFrom(spec, condition, table);\n }\n}\n\nexport function any(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${condition.op === 'NOT IN' ? sql`NOT` : sql``}\n (\n ${valueComparison(spec, condition.left, table, condition.right, false)} = ANY \n (${valueComparison(spec, condition.right, table, condition.left, true)})\n )`;\n}\n\nexport function distinctFrom(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${valueComparison(spec, condition.right, table, condition.left, false)}`;\n}\n\nfunction startEquality(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sql`${colIdent(spec.server, {\n table,\n zql: field,\n })} IS NOT DISTINCT FROM ${startValue(spec, table, field, value)}`;\n}\n\nfunction startRangeComparison(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n operator: '>' | '<',\n): SQLQuery {\n const column = colIdent(spec.server, {table, zql: field});\n if (value === null) {\n return operator === '>' ? sql`${column} IS NOT NULL` : sql`FALSE`;\n }\n const typedValue = startValue(spec, table, field, value);\n return operator === '>'\n ? sql`${column} > ${typedValue}`\n : sql`(${column} IS NULL OR ${column} < ${typedValue})`;\n}\n\nfunction startValue(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, field),\n value,\n false,\n true,\n );\n}\n\nfunction valueComparison(\n spec: Spec,\n valuePos: ValuePosition,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const valuePosType = valuePos.type;\n switch (valuePosType) {\n case 'column': {\n const qualified: QualifiedColumn = {\n table,\n zql: valuePos.name,\n };\n return colIdent(spec.server, qualified);\n }\n case 'literal':\n return literalValueComparison(\n spec,\n valuePos,\n table,\n otherValuePos,\n plural,\n );\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(valuePosType);\n break;\n }\n}\n\nfunction literalValueComparison(\n spec: Spec,\n valuePos: LiteralReference,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const otherType = otherValuePos.type;\n switch (otherType) {\n case 'column':\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, otherValuePos.name),\n valuePos.value,\n plural,\n true,\n );\n case 'literal': {\n assert(\n plural === Array.isArray(valuePos.value),\n 'Expected plural flag to match whether value is an array',\n );\n if (Array.isArray(valuePos.value)) {\n if (valuePos.value.length > 0) {\n // If the array is non-empty base its type on its first\n // element\n return sqlConvertPluralLiteralArg(\n typeof valuePos.value[0] as PluralLiteralType,\n valuePos.value as PluralLiteralType[],\n );\n }\n // If the array is empty, base its type on the other value\n // position's type (as long as the other value position is non-null,\n // cannot have a null[]).\n if (otherValuePos.value !== null) {\n return sqlConvertPluralLiteralArg(\n typeof otherValuePos.value as PluralLiteralType,\n [],\n );\n }\n // If the other value position is null, it can be compared to any\n // type of empty array, chose 'string' arbitrarily.\n return sqlConvertPluralLiteralArg('string', []);\n }\n if (\n typeof valuePos.value === 'string' ||\n typeof valuePos.value === 'number' ||\n typeof valuePos.value === 'boolean'\n ) {\n return sqlConvertSingularLiteralArg(valuePos.value);\n }\n throw new Error(`Literal of unexpected type: ${typeof valuePos.value}`);\n }\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(otherType);\n }\n}\n\nexport function makeJunctionJoin(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): {\n join: SQLQuery;\n participatingTables: ReturnType<typeof pullTablesForJunction>;\n} {\n const participatingTables = pullTablesForJunction(spec, relationship);\n const joins: SQLQuery[] = [];\n\n for (const {table} of participatingTables) {\n if (joins.length === 0) {\n joins.push(fromIdent(spec.server, table));\n continue;\n }\n joins.push(\n sql` JOIN ${fromIdent(spec.server, table)} ON ${makeCorrelator(\n spec,\n participatingTables[joins.length].correlation.parentField.map(f => ({\n table: participatingTables[joins.length - 1].table,\n zql: f,\n })),\n participatingTables[joins.length].correlation.childField,\n )(participatingTables[joins.length].table)}`,\n );\n }\n\n return {\n join: sql`${sql.join(joins, '')}`,\n participatingTables,\n // lastTable: participatingTables[participatingTables.length - 1].table,\n // lastLimit: participatingTables[participatingTables.length - 1].limit,\n };\n}\n\nexport function pullTablesForJunction(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): [\n {\n table: Table;\n correlation: Correlation;\n limit: number | undefined;\n },\n {table: Table; correlation: Correlation; limit: number | undefined},\n] {\n assert(\n relationship.subquery.related?.length === 1,\n 'Too many related tables for a junction edge',\n );\n const otherRelationship = relationship.subquery.related[0];\n assert(\n !otherRelationship.hidden,\n 'Expected junction edge relationship to not be hidden',\n );\n return [\n {\n table: makeTable(spec, relationship.subquery.table),\n correlation: relationship.correlation,\n limit: relationship.subquery.limit,\n },\n {\n table: makeTable(spec, otherRelationship.subquery.table),\n correlation: otherRelationship.correlation,\n limit: otherRelationship.subquery.limit,\n },\n ];\n}\n\nfunction toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)}))${singular ? sql`` : sql`, '[]'::json)`}`;\n}\n\nfunction selectIdent(server: ServerSpec, column: QualifiedColumn): SQLQuery {\n const serverColumnSchema =\n server.schema[server.mapper.tableName(column.table.zql)][\n server.mapper.columnName(column.table.zql, column.zql)\n ];\n const serverType = serverColumnSchema.type;\n if (!serverColumnSchema.isEnum) {\n let needsNormalization = false;\n switch (serverType) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timetz':\n needsNormalization = true;\n // fallthrough\n\n case 'date':\n case 'time':\n case 'time without time zone':\n case 'time with time zone':\n case 'timestamp':\n case 'timestamp without time zone':\n case 'timestamp with time zone': {\n // EXTRACT(EPOCH FROM timetz) can be negative when the UTC offset is\n // positive (e.g. 01:00+02 = 23:00 UTC prev day = -3600s). Wrap with\n // modular arithmetic to normalize to 0..86400000.\n const toMs = (epochExpr: SQLQuery): SQLQuery =>\n needsNormalization\n ? sql`((${epochExpr})::bigint + 86400000) % 86400000`\n : epochExpr;\n\n if (serverColumnSchema.isArray) {\n const col = colIdent(server, column);\n return sql`CASE WHEN ${col} IS NULL THEN NULL ELSE ARRAY(SELECT ${toMs(\n sql`EXTRACT(EPOCH FROM unnest(${col})) * 1000`,\n )}) END as ${sql.ident(column.zql)}`;\n }\n\n return sql`${toMs(\n sql`EXTRACT(EPOCH FROM ${colIdent(server, column)}) * 1000`,\n )} as ${sql.ident(column.zql)}`;\n }\n }\n }\n\n return sql`${colIdent(server, column)} as ${sql.ident(column.zql)}`;\n}\n\nfunction colIdent(server: ServerSpec, column: QualifiedColumn) {\n return sql.ident(\n column.table.alias,\n server.mapper.columnName(column.table.zql, column.zql),\n );\n}\n\nfunction fromIdent(server: ServerSpec, table: Table) {\n return sql`${sql.ident(server.mapper.tableName(table.zql))} AS ${sql.ident(table.alias)}`;\n}\n\nfunction getServerColumn(spec: ServerSpec, table: Table, zqlColumn: string) {\n return spec.schema[spec.mapper.tableName(table.zql)][\n spec.mapper.columnName(table.zql, zqlColumn)\n ];\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: Array<any>): JSONValue {\n const bigIntJson: BigIntJSONValue = parseBigIntJson(\n pgResult[0][ZQL_RESULT_KEY],\n );\n assertJSONValue(bigIntJson);\n return bigIntJson;\n}\n\nfunction assertJSONValue(v: BigIntJSONValue): asserts v is JSONValue {\n const path = findPathToBigInt(v);\n if (path) {\n throw new Error(`Value exceeds safe Number range. ${path}`);\n }\n}\n\nfunction findPathToBigInt(v: BigIntJSONValue): string | undefined {\n const typeOfV = typeof v;\n switch (typeOfV) {\n case 'bigint':\n return ` = ${v}`;\n case 'object': {\n if (v === null) {\n return;\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const path = findPathToBigInt(v[i]);\n if (path) {\n return `[${i}]${path}`;\n }\n }\n return undefined;\n }\n\n const o = v as Record<string, BigIntJSONValue>;\n for (const k in o) {\n if (hasOwn(o, k)) {\n const path = findPathToBigInt(o[k]);\n if (path) {\n return `['${k}']${path}`;\n }\n }\n }\n return undefined;\n }\n case 'number':\n return undefined;\n case 'boolean':\n return undefined;\n default:\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compiler.js","names":["parseBigIntJson"],"sources":["../../../../z2s/src/compiler.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {last, zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n parse as parseBigIntJson,\n type JSONValue as BigIntJSONValue,\n} from '../../shared/src/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Bound,\n Condition,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Correlation,\n LiteralReference,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n clientToServer,\n type NameMapper,\n} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../zero-types/src/server-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {completeOrdering} from '../../zql/src/query/complete-ordering.ts';\nimport {\n sql,\n sqlConvertColumnArg,\n sqlConvertPluralLiteralArg,\n sqlConvertSingularLiteralArg,\n type PluralLiteralType,\n} from './sql.ts';\n\ntype Table = {\n zql: string;\n alias: string;\n};\n\ntype QualifiedColumn = {\n table: Table;\n zql: string;\n};\n\ntype ServerSpec = {\n schema: ServerSchema;\n // maps zql names to server names\n mapper: NameMapper;\n};\n\nexport type Spec = {\n server: ServerSpec;\n zql: Schema['tables'];\n aliasCount: number;\n};\n\nconst ZQL_RESULT_KEY = 'zql_result';\nconst ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);\n\nconst ZQL_RESULT_TABLE_KEY = 'zql_root';\nconst ZQL_RESULT_TABLE_IDENT = sql.ident(ZQL_RESULT_TABLE_KEY);\n\nexport function compile(\n serverSchema: ServerSchema,\n zqlSchema: Schema,\n ast: AST,\n format?: Format,\n): SQLQuery {\n ast = completeOrdering(\n ast,\n tableName => zqlSchema.tables[tableName].primaryKey,\n );\n const spec: Spec = {\n aliasCount: 0,\n server: {\n schema: serverSchema,\n mapper: clientToServer(zqlSchema.tables),\n },\n zql: zqlSchema.tables,\n };\n return sql`SELECT \n ${toJSON(ZQL_RESULT_TABLE_KEY, format?.singular)}::text AS ${ZQL_RESULT_KEY_IDENT}\n FROM (${select(spec, ast, format)}) ${ZQL_RESULT_TABLE_IDENT}`;\n}\n\nfunction select(\n spec: Spec,\n ast: AST,\n format: Format | undefined,\n correlate?: (childTable: Table) => SQLQuery,\n): SQLQuery {\n const table = makeTable(spec, ast.table);\n const selectionSet = related(spec, ast.related ?? [], format, table);\n const tableSchema = spec.zql[ast.table];\n const usedAliases = new Set<string>(\n ast.related?.map(r => r.subquery.alias ?? ''),\n );\n for (const column of Object.keys(tableSchema.columns)) {\n if (!usedAliases.has(column)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table,\n zql: column,\n }),\n );\n }\n }\n\n let appliedWhere = false;\n function maybeWhere(test: unknown) {\n if (!test) {\n return sql``;\n }\n\n const ret = appliedWhere ? sql`AND` : sql`WHERE`;\n appliedWhere = true;\n return ret;\n }\n\n return sql`SELECT ${sql.join(selectionSet, ',')}\n FROM ${fromIdent(spec.server, table)}\n ${maybeWhere(ast.where)} ${where(spec, ast.where, table)}${\n ast.start\n ? sql`\n ${maybeWhere(ast.start)} ${start(spec, ast.start, ast.orderBy, table)}`\n : sql``\n }\n ${maybeWhere(correlate)} ${correlate ? correlate(table) : sql``}\n ${orderBy(spec, ast.orderBy, table)}\n ${limit(ast.limit, format?.singular)}`;\n}\n\nexport function limit(\n limit: number | undefined,\n singular: boolean | undefined,\n): SQLQuery {\n if (limit === 0) {\n return sql`LIMIT 0`;\n }\n if (singular) {\n return sql`LIMIT 1`;\n }\n if (limit === undefined) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertSingularLiteralArg(limit)}`;\n}\n\nfunction makeTable(spec: Spec, zql: string, alias?: string): Table {\n alias = alias ?? zql + '_' + spec.aliasCount++;\n return {\n zql,\n alias,\n };\n}\n\nexport function orderBy(\n spec: Spec,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!orderBy) {\n return sql``;\n }\n return sql`ORDER BY ${sql.join(\n orderBy.map(([col, dir]) =>\n dir === 'asc'\n ? // Oh postgres. The table must be referred to by client name but the column by server name.\n // E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`\n sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} ASC NULLS FIRST`\n : sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} DESC NULLS LAST`,\n ),\n ', ',\n )}`;\n}\n\nexport function start(\n spec: Spec,\n bound: Bound | undefined,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!bound) {\n return sql``;\n }\n assert(\n orderBy !== undefined && orderBy.length > 0,\n 'start requires ordering',\n );\n\n const constraints: SQLQuery[] = [];\n for (let i = 0; i < orderBy.length; i++) {\n const group: SQLQuery[] = [];\n const [iField, iDirection] = orderBy[i];\n for (let j = 0; j <= i; j++) {\n const [field] = orderBy[j];\n if (j === i) {\n group.push(\n startRangeComparison(\n spec,\n table,\n iField,\n bound.row[iField] ?? null,\n iDirection === 'asc' ? '>' : '<',\n ),\n );\n } else {\n group.push(startEquality(spec, table, field, bound.row[field] ?? null));\n }\n }\n constraints.push(sql`(${sql.join(group, ' AND ')})`);\n }\n\n if (!bound.exclusive) {\n constraints.push(\n sql`(${sql.join(\n orderBy.map(([field]) =>\n startEquality(spec, table, field, bound.row[field] ?? null),\n ),\n ' AND ',\n )})`,\n );\n }\n\n return sql`(${sql.join(constraints, ' OR ')})`;\n}\n\nfunction related(\n spec: Spec,\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery[] {\n return relationships.map(relationship =>\n relationshipSubquery(\n spec,\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n}\n\nfunction relationshipSubquery(\n spec: Spec,\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery {\n const innerAlias = `inner_${relationship.subquery.alias}`;\n if (relationship.hidden) {\n const {join, participatingTables} = makeJunctionJoin(spec, relationship);\n const lastTable = must(last(participatingTables)).table;\n\n assert(\n relationship.subquery.related,\n 'hidden relationship must be a junction',\n );\n const nestedAst = relationship.subquery.related[0].subquery;\n const selectionSet = related(\n spec,\n nestedAst.related ?? [],\n format,\n lastTable,\n );\n const tableSchema = spec.zql[nestedAst.table];\n for (const column of Object.keys(tableSchema.columns)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table: lastTable,\n zql: column,\n }),\n );\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (SELECT ${sql.join(\n selectionSet,\n ',',\n )} FROM ${join} WHERE (${makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n )(participatingTables[0].table)}) ${\n nestedAst.where\n ? sql`AND ${where(spec, nestedAst.where, lastTable)}`\n : sql``\n }${\n nestedAst.start\n ? sql` AND ${start(\n spec,\n nestedAst.start,\n nestedAst.orderBy,\n lastTable,\n )}`\n : sql``\n } ${orderBy(spec, nestedAst.orderBy, lastTable)} ${limit(\n last(participatingTables)?.limit,\n format?.singular,\n )} ) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (${select(\n spec,\n relationship.subquery,\n format,\n makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n}\n\nfunction where(\n spec: Spec,\n condition: Condition | undefined,\n table: Table,\n): SQLQuery {\n if (!condition) {\n return sql``;\n }\n\n switch (condition.type) {\n case 'and':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n // `scalar` is deliberately ignored here. It is a planner hint for the\n // IVM engines, which have no cost-based planner and benefit from\n // pre-resolving an at-most-one-row subquery to a literal comparison\n // (see zqlite's `resolveSimpleScalarSubqueries`). Postgres decorrelates\n // EXISTS into a semi-join on its own, so the hint buys nothing here —\n // and honoring it as `parentField = (SELECT childField … LIMIT 1)` is\n // only sound when the subquery matches at most one row *globally*.\n // Applying it unconditionally silently dropped rows whenever the\n // subquery was not pinned to a unique key.\n return exists(spec, condition, table);\n case 'simple':\n return simple(spec, condition, table);\n }\n}\n\nfunction exists(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n }\n}\n\nexport function makeCorrelator(\n spec: Spec,\n parentFields: readonly QualifiedColumn[],\n childZqlFields: readonly string[],\n): (childTable: Table) => SQLQuery {\n return (childTable: Table) => {\n const childFields = childZqlFields.map(zqlField => ({\n table: childTable,\n zql: zqlField,\n }));\n return sql.join(\n zip(parentFields, childFields).map(\n ([parentColumn, childColumn]) =>\n sql`${colIdent(spec.server, parentColumn)} = ${colIdent(\n spec.server,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n };\n}\n\nexport function simple(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE': {\n // The pattern is a string, not a value of the column's type. Converted\n // to the `bpchar` of a `char(n)` column it would lose its trailing\n // spaces. Like ZQL's own LIKE, non-string patterns match as strings.\n const {right} = condition;\n assert(\n right.type === 'literal',\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${sqlConvertSingularLiteralArg(\n right.value === null ? null : String(right.value),\n )}`;\n }\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n condition.right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(\n spec,\n condition.right,\n table,\n condition.left,\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return any(spec, condition, table);\n case 'IS':\n case 'IS NOT':\n return distinctFrom(spec, condition, table);\n }\n}\n\nexport function any(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${condition.op === 'NOT IN' ? sql`NOT` : sql``}\n (\n ${valueComparison(spec, condition.left, table, condition.right, false)} = ANY \n (${valueComparison(spec, condition.right, table, condition.left, true)})\n )`;\n}\n\nexport function distinctFrom(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${valueComparison(spec, condition.right, table, condition.left, false)}`;\n}\n\nfunction startEquality(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sql`${colIdent(spec.server, {\n table,\n zql: field,\n })} IS NOT DISTINCT FROM ${startValue(spec, table, field, value)}`;\n}\n\nfunction startRangeComparison(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n operator: '>' | '<',\n): SQLQuery {\n const column = colIdent(spec.server, {table, zql: field});\n if (value === null) {\n return operator === '>' ? sql`${column} IS NOT NULL` : sql`FALSE`;\n }\n const typedValue = startValue(spec, table, field, value);\n return operator === '>'\n ? sql`${column} > ${typedValue}`\n : sql`(${column} IS NULL OR ${column} < ${typedValue})`;\n}\n\nfunction startValue(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, field),\n value,\n false,\n true,\n );\n}\n\nfunction valueComparison(\n spec: Spec,\n valuePos: ValuePosition,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const valuePosType = valuePos.type;\n switch (valuePosType) {\n case 'column': {\n const qualified: QualifiedColumn = {\n table,\n zql: valuePos.name,\n };\n return colIdent(spec.server, qualified);\n }\n case 'literal':\n return literalValueComparison(\n spec,\n valuePos,\n table,\n otherValuePos,\n plural,\n );\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(valuePosType);\n break;\n }\n}\n\nfunction literalValueComparison(\n spec: Spec,\n valuePos: LiteralReference,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const otherType = otherValuePos.type;\n switch (otherType) {\n case 'column':\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, otherValuePos.name),\n valuePos.value,\n plural,\n true,\n );\n case 'literal': {\n assert(\n plural === Array.isArray(valuePos.value),\n 'Expected plural flag to match whether value is an array',\n );\n if (Array.isArray(valuePos.value)) {\n if (valuePos.value.length > 0) {\n // If the array is non-empty base its type on its first\n // element\n return sqlConvertPluralLiteralArg(\n typeof valuePos.value[0] as PluralLiteralType,\n valuePos.value as PluralLiteralType[],\n );\n }\n // If the array is empty, base its type on the other value\n // position's type (as long as the other value position is non-null,\n // cannot have a null[]).\n if (otherValuePos.value !== null) {\n return sqlConvertPluralLiteralArg(\n typeof otherValuePos.value as PluralLiteralType,\n [],\n );\n }\n // If the other value position is null, it can be compared to any\n // type of empty array, chose 'string' arbitrarily.\n return sqlConvertPluralLiteralArg('string', []);\n }\n if (\n typeof valuePos.value === 'string' ||\n typeof valuePos.value === 'number' ||\n typeof valuePos.value === 'boolean'\n ) {\n return sqlConvertSingularLiteralArg(valuePos.value);\n }\n throw new Error(`Literal of unexpected type: ${typeof valuePos.value}`);\n }\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(otherType);\n }\n}\n\nexport function makeJunctionJoin(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): {\n join: SQLQuery;\n participatingTables: ReturnType<typeof pullTablesForJunction>;\n} {\n const participatingTables = pullTablesForJunction(spec, relationship);\n const joins: SQLQuery[] = [];\n\n for (const {table} of participatingTables) {\n if (joins.length === 0) {\n joins.push(fromIdent(spec.server, table));\n continue;\n }\n joins.push(\n sql` JOIN ${fromIdent(spec.server, table)} ON ${makeCorrelator(\n spec,\n participatingTables[joins.length].correlation.parentField.map(f => ({\n table: participatingTables[joins.length - 1].table,\n zql: f,\n })),\n participatingTables[joins.length].correlation.childField,\n )(participatingTables[joins.length].table)}`,\n );\n }\n\n return {\n join: sql`${sql.join(joins, '')}`,\n participatingTables,\n // lastTable: participatingTables[participatingTables.length - 1].table,\n // lastLimit: participatingTables[participatingTables.length - 1].limit,\n };\n}\n\nexport function pullTablesForJunction(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): [\n {\n table: Table;\n correlation: Correlation;\n limit: number | undefined;\n },\n {table: Table; correlation: Correlation; limit: number | undefined},\n] {\n assert(\n relationship.subquery.related?.length === 1,\n 'Too many related tables for a junction edge',\n );\n const otherRelationship = relationship.subquery.related[0];\n assert(\n !otherRelationship.hidden,\n 'Expected junction edge relationship to not be hidden',\n );\n return [\n {\n table: makeTable(spec, relationship.subquery.table),\n correlation: relationship.correlation,\n limit: relationship.subquery.limit,\n },\n {\n table: makeTable(spec, otherRelationship.subquery.table),\n correlation: otherRelationship.correlation,\n limit: otherRelationship.subquery.limit,\n },\n ];\n}\n\nfunction toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)}))${singular ? sql`` : sql`, '[]'::json)`}`;\n}\n\nfunction selectIdent(server: ServerSpec, column: QualifiedColumn): SQLQuery {\n const serverColumnSchema =\n server.schema[server.mapper.tableName(column.table.zql)][\n server.mapper.columnName(column.table.zql, column.zql)\n ];\n const serverType = serverColumnSchema.type;\n if (!serverColumnSchema.isEnum) {\n let needsNormalization = false;\n switch (serverType) {\n case 'timetz':\n // @ts-expect-error Fallthrough intended\n case 'time with time zone':\n needsNormalization = true;\n // fallthrough\n\n case 'date':\n case 'time':\n case 'time without time zone':\n case 'timestamp':\n case 'timestamp without time zone':\n case 'timestamptz':\n case 'timestamp with time zone': {\n // EXTRACT(EPOCH FROM timetz) can be negative when the UTC offset is\n // positive (e.g. 01:00+02 = 23:00 UTC prev day = -3600s). Wrap with\n // modular arithmetic to normalize to 0..86400000.\n const toMs = (epochExpr: SQLQuery): SQLQuery =>\n needsNormalization\n ? sql`((${epochExpr})::bigint + 86400000) % 86400000`\n : epochExpr;\n\n if (serverColumnSchema.isArray) {\n const col = colIdent(server, column);\n return sql`CASE WHEN ${col} IS NULL THEN NULL ELSE ARRAY(SELECT ${toMs(\n sql`EXTRACT(EPOCH FROM unnest(${col})) * 1000`,\n )}) END as ${sql.ident(column.zql)}`;\n }\n\n return sql`${toMs(\n sql`EXTRACT(EPOCH FROM ${colIdent(server, column)}) * 1000`,\n )} as ${sql.ident(column.zql)}`;\n }\n }\n }\n\n return sql`${colIdent(server, column)} as ${sql.ident(column.zql)}`;\n}\n\nfunction colIdent(server: ServerSpec, column: QualifiedColumn) {\n return sql.ident(\n column.table.alias,\n server.mapper.columnName(column.table.zql, column.zql),\n );\n}\n\nfunction fromIdent(server: ServerSpec, table: Table) {\n return sql`${sql.ident(server.mapper.tableName(table.zql))} AS ${sql.ident(table.alias)}`;\n}\n\nfunction getServerColumn(spec: ServerSpec, table: Table, zqlColumn: string) {\n return spec.schema[spec.mapper.tableName(table.zql)][\n spec.mapper.columnName(table.zql, zqlColumn)\n ];\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: Array<any>): JSONValue {\n const bigIntJson: BigIntJSONValue = parseBigIntJson(\n pgResult[0][ZQL_RESULT_KEY],\n );\n assertJSONValue(bigIntJson);\n return bigIntJson;\n}\n\nfunction assertJSONValue(v: BigIntJSONValue): asserts v is JSONValue {\n const path = findPathToBigInt(v);\n if (path) {\n throw new Error(`Value exceeds safe Number range. ${path}`);\n }\n}\n\nfunction findPathToBigInt(v: BigIntJSONValue): string | undefined {\n const typeOfV = typeof v;\n switch (typeOfV) {\n case 'bigint':\n return ` = ${v}`;\n case 'object': {\n if (v === null) {\n return;\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const path = findPathToBigInt(v[i]);\n if (path) {\n return `[${i}]${path}`;\n }\n }\n return undefined;\n }\n\n const o = v as Record<string, BigIntJSONValue>;\n for (const k in o) {\n if (hasOwn(o, k)) {\n const path = findPathToBigInt(o[k]);\n if (path) {\n return `['${k}']${path}`;\n }\n }\n }\n return undefined;\n }\n case 'number':\n return undefined;\n case 'boolean':\n return undefined;\n default:\n return undefined;\n }\n}\n"],"mappings":"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"}
|
package/out/zero/package.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region package.json
|
|
2
2
|
var name = "@rocicorp/zero";
|
|
3
|
-
var version = "1.12.0-canary.
|
|
3
|
+
var version = "1.12.0-canary.6";
|
|
4
4
|
var description = "Zero is a web framework for serverless web development.";
|
|
5
5
|
var homepage = "https://zero.rocicorp.dev";
|
|
6
6
|
var bugs = { "url": "https://bugs.rocicorp.dev" };
|
|
@@ -177,7 +177,7 @@ var devDependencies = {
|
|
|
177
177
|
"typedoc": "^0.28.19",
|
|
178
178
|
"typescript": "~7.0.2",
|
|
179
179
|
"vite": "^8.3.4",
|
|
180
|
-
"vitest": "^5.0.
|
|
180
|
+
"vitest": "^5.0.5",
|
|
181
181
|
"zero-cache": "workspace:*",
|
|
182
182
|
"zero-client": "workspace:*",
|
|
183
183
|
"zero-pg": "workspace:*",
|
package/out/zero/package.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.12.0-canary.
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.12.0-canary.6\",\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 \"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/kysely\": {\n \"types\": \"./out/zero/src/adapters/kysely.d.ts\",\n \"default\": \"./out/zero/src/adapters/kysely.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 --quiet --config ../../oxlint.config.ts 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.5.5\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.66.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.1.0\",\n \"@fastify/websocket\": \"^11.2.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.1\",\n \"@opentelemetry/api-logs\": \"^0.223.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.81.2\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.223.0\",\n \"@opentelemetry/resources\": \"^2.12.0\",\n \"@opentelemetry/sdk-metrics\": \"^2.12.0\",\n \"@opentelemetry/sdk-node\": \"^0.223.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.12.0\",\n \"@opentelemetry/semantic-conventions\": \"^1.43.0\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^6.1.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.1.7\",\n \"@standard-schema/spec\": \"^1.1.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.18.1\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.2\",\n \"chokidar\": \"^4.0.3\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.2\",\n \"command-line-usage\": \"^7.0.4\",\n \"compare-utf8\": \"^0.2.3\",\n \"defu\": \"^6.1.7\",\n \"eventemitter3\": \"^5.0.4\",\n \"fastify\": \"^5.12.7\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.10.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.2\",\n \"nanoid\": \"^5.1.16\",\n \"oxc-parser\": \"^0.129.0\",\n \"oxfmt\": \"^0.74.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.8.0\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.22.0\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \"^18.2.5\",\n \"analyze-query\": \"workspace:*\",\n \"ast-to-zql\": \"workspace:*\",\n \"expo\": \"^58.0.14\",\n \"expo-sqlite\": \"^58.0.13\",\n \"react-native\": \"^0.88.0\",\n \"replicache\": \"workspace:*\",\n \"shared\": \"workspace:*\",\n \"syncpack\": \"^14.3.1\",\n \"typedoc\": \"^0.28.19\",\n \"typescript\": \"~7.0.2\",\n \"vite\": \"^8.3.4\",\n \"vitest\": \"^5.0.5\",\n \"zero-cache\": \"workspace:*\",\n \"zero-client\": \"workspace:*\",\n \"zero-pg\": \"workspace:*\",\n \"zero-react\": \"workspace:*\",\n \"zero-server\": \"workspace:*\",\n \"zero-solid\": \"workspace:*\",\n \"zqlite\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"packageManager\": \"pnpm@11.11.0\"\n}\n"],"mappings":""}
|
|
@@ -990,8 +990,8 @@ var zeroOptions = {
|
|
|
990
990
|
``,
|
|
991
991
|
`When enabled, lag reports are used to gate readiness of servers coming online by waiting`,
|
|
992
992
|
`for lag to fall below the {bold ZERO_REPLICATION_LAG_INITIAL_READINESS_THRESHOLD_MS}.`,
|
|
993
|
-
`
|
|
994
|
-
`the next report
|
|
993
|
+
`A report is requested as soon as a new server has caught up, so its readiness does not`,
|
|
994
|
+
`wait for the next report interval.`,
|
|
995
995
|
``,
|
|
996
996
|
`A negative or 0 value disables lag reporting and the associated readiness gating.`,
|
|
997
997
|
``,
|