@rocicorp/zero 0.18.2025032401 → 0.18.2025032800

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 (234) hide show
  1. package/out/advanced.js +0 -1
  2. package/out/{chunk-5WXONOGR.js → chunk-3S3SDA44.js} +205 -140
  3. package/out/chunk-3S3SDA44.js.map +7 -0
  4. package/out/{chunk-2B2QE5AT.js → chunk-MB3DEFRC.js} +25 -2
  5. package/out/{chunk-2B2QE5AT.js.map → chunk-MB3DEFRC.js.map} +2 -2
  6. package/out/{chunk-DSUPSGE4.js → chunk-NBZURO2P.js} +81 -26
  7. package/out/{chunk-DSUPSGE4.js.map → chunk-NBZURO2P.js.map} +4 -4
  8. package/out/{inspector-ROITQB3J.js → inspector-SH2ZK7O3.js} +253 -102
  9. package/out/inspector-SH2ZK7O3.js.map +7 -0
  10. package/out/react.js +2 -3
  11. package/out/react.js.map +2 -2
  12. package/out/shared/src/sentinels.d.ts +3 -0
  13. package/out/shared/src/sentinels.d.ts.map +1 -0
  14. package/out/solid.js +3 -4
  15. package/out/solid.js.map +2 -2
  16. package/out/z2s/src/compiler.d.ts +5 -3
  17. package/out/z2s/src/compiler.d.ts.map +1 -1
  18. package/out/z2s/src/compiler.js +116 -16
  19. package/out/z2s/src/compiler.js.map +1 -1
  20. package/out/z2s/src/sql.d.ts +8 -0
  21. package/out/z2s/src/sql.d.ts.map +1 -1
  22. package/out/z2s/src/sql.js +205 -11
  23. package/out/z2s/src/sql.js.map +1 -1
  24. package/out/zero/src/zero-cache-dev.d.ts +1 -1
  25. package/out/zero/src/zero-cache-dev.d.ts.map +1 -1
  26. package/out/zero/src/zero-cache-dev.js +1 -1
  27. package/out/zero/src/zero-cache-dev.js.map +1 -1
  28. package/out/zero-cache/src/auth/load-permissions.d.ts.map +1 -1
  29. package/out/zero-cache/src/auth/load-permissions.js +2 -1
  30. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  31. package/out/zero-cache/src/config/zero-config.d.ts +1 -1
  32. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  33. package/out/zero-cache/src/config/zero-config.js +6 -3
  34. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  35. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  36. package/out/zero-cache/src/db/migration-lite.js +9 -9
  37. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  38. package/out/zero-cache/src/scripts/deploy-permissions.d.ts +1 -1
  39. package/out/zero-cache/src/scripts/deploy-permissions.d.ts.map +1 -1
  40. package/out/zero-cache/src/scripts/deploy-permissions.js +1 -1
  41. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  42. package/out/zero-cache/src/server/multi/config.d.ts +1 -1
  43. package/out/zero-cache/src/server/multi/main.d.ts +1 -1
  44. package/out/zero-cache/src/server/multi/main.d.ts.map +1 -1
  45. package/out/zero-cache/src/server/multi/main.js +1 -1
  46. package/out/zero-cache/src/server/multi/main.js.map +1 -1
  47. package/out/zero-cache/src/server/multi/run-worker.d.ts +1 -1
  48. package/out/zero-cache/src/server/multi/run-worker.d.ts.map +1 -1
  49. package/out/zero-cache/src/server/multi/run-worker.js +1 -1
  50. package/out/zero-cache/src/server/multi/run-worker.js.map +1 -1
  51. package/out/zero-cache/src/server/syncer.js +1 -1
  52. package/out/zero-cache/src/server/syncer.js.map +1 -1
  53. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +1 -1
  54. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  55. package/out/zero-cache/src/services/change-source/pg/change-source.js +96 -42
  56. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  57. package/out/zero-cache/src/services/change-source/pg/decommission.d.ts.map +1 -1
  58. package/out/zero-cache/src/services/change-source/pg/decommission.js +16 -5
  59. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  60. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +1 -2
  61. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  62. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +18 -31
  63. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  64. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +7 -35
  65. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  66. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +42 -74
  67. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  68. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +1 -1
  69. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  70. package/out/zero-cache/src/services/change-source/pg/schema/init.js +69 -21
  71. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  72. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +54 -27
  73. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  74. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +53 -16
  75. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  76. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +7 -5
  77. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  78. package/out/zero-cache/src/services/mutagen/mutagen.js +20 -5
  79. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  80. package/out/zero-cache/src/services/mutagen/pusher.d.ts +1 -1
  81. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  82. package/out/zero-cache/src/services/mutagen/pusher.js +24 -10
  83. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  84. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  85. package/out/zero-cache/src/services/replicator/change-processor.js +25 -14
  86. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  87. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +8 -4
  88. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  89. package/out/zero-cache/src/services/view-syncer/client-handler.js +47 -23
  90. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  91. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  92. package/out/zero-cache/src/services/view-syncer/client-schema.js +8 -2
  93. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  94. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +2 -0
  95. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  96. package/out/zero-cache/src/services/view-syncer/cvr-store.js +35 -0
  97. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  98. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +3 -0
  99. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  100. package/out/zero-cache/src/services/view-syncer/view-syncer.js +32 -20
  101. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  102. package/out/zero-cache/src/types/bigint-json.d.ts +1 -1
  103. package/out/zero-cache/src/types/bigint-json.d.ts.map +1 -1
  104. package/out/zero-cache/src/types/bigint-json.js.map +1 -1
  105. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  106. package/out/zero-cache/src/types/lite.js +4 -3
  107. package/out/zero-cache/src/types/lite.js.map +1 -1
  108. package/out/zero-cache/src/types/shards.d.ts +4 -0
  109. package/out/zero-cache/src/types/shards.d.ts.map +1 -1
  110. package/out/zero-cache/src/types/shards.js +1 -1
  111. package/out/zero-cache/src/types/shards.js.map +1 -1
  112. package/out/zero-cache/src/workers/connection.d.ts +1 -2
  113. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  114. package/out/zero-cache/src/workers/connection.js +64 -21
  115. package/out/zero-cache/src/workers/connection.js.map +1 -1
  116. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  117. package/out/zero-cache/src/workers/replicator.js +4 -8
  118. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  119. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  120. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +16 -7
  121. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  122. package/out/zero-client/src/client/custom.d.ts +9 -11
  123. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  124. package/out/zero-client/src/client/inspector/inspector.d.ts +2 -1
  125. package/out/zero-client/src/client/inspector/inspector.d.ts.map +1 -1
  126. package/out/zero-client/src/client/inspector/types.d.ts +7 -2
  127. package/out/zero-client/src/client/inspector/types.d.ts.map +1 -1
  128. package/out/zero-client/src/client/mutation-tracker.d.ts +23 -8
  129. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  130. package/out/zero-client/src/client/options.d.ts +7 -2
  131. package/out/zero-client/src/client/options.d.ts.map +1 -1
  132. package/out/zero-client/src/client/query-manager.d.ts +2 -1
  133. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  134. package/out/zero-client/src/client/zero.d.ts +1 -1
  135. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  136. package/out/zero-client/src/mod.d.ts +7 -1
  137. package/out/zero-client/src/mod.d.ts.map +1 -1
  138. package/out/zero-pg/src/custom.d.ts +2 -13
  139. package/out/zero-pg/src/custom.d.ts.map +1 -1
  140. package/out/zero-pg/src/custom.js +11 -14
  141. package/out/zero-pg/src/custom.js.map +1 -1
  142. package/out/zero-pg/src/mod.d.ts +1 -2
  143. package/out/zero-pg/src/mod.d.ts.map +1 -1
  144. package/out/zero-pg/src/mod.js +1 -1
  145. package/out/zero-pg/src/mod.js.map +1 -1
  146. package/out/zero-pg/src/query.d.ts +2 -2
  147. package/out/zero-pg/src/query.d.ts.map +1 -1
  148. package/out/zero-pg/src/query.js +8 -15
  149. package/out/zero-pg/src/query.js.map +1 -1
  150. package/out/zero-pg/src/web.d.ts +3 -7
  151. package/out/zero-pg/src/web.d.ts.map +1 -1
  152. package/out/zero-pg/src/web.js +9 -15
  153. package/out/zero-pg/src/web.js.map +1 -1
  154. package/out/zero-protocol/src/client-schema.d.ts +1 -1
  155. package/out/zero-protocol/src/client-schema.d.ts.map +1 -1
  156. package/out/zero-protocol/src/client-schema.js +1 -1
  157. package/out/zero-protocol/src/client-schema.js.map +1 -1
  158. package/out/zero-protocol/src/down.d.ts +19 -4
  159. package/out/zero-protocol/src/down.d.ts.map +1 -1
  160. package/out/zero-protocol/src/down.js +2 -2
  161. package/out/zero-protocol/src/down.js.map +1 -1
  162. package/out/zero-protocol/src/inspect-down.d.ts +59 -0
  163. package/out/zero-protocol/src/inspect-down.d.ts.map +1 -0
  164. package/out/zero-protocol/src/inspect-down.js +23 -0
  165. package/out/zero-protocol/src/inspect-down.js.map +1 -0
  166. package/out/zero-protocol/src/inspect-up.d.ts +21 -0
  167. package/out/zero-protocol/src/inspect-up.d.ts.map +1 -0
  168. package/out/zero-protocol/src/inspect-up.js +12 -0
  169. package/out/zero-protocol/src/inspect-up.js.map +1 -0
  170. package/out/zero-protocol/src/mutation-type-enum.d.ts +1 -0
  171. package/out/zero-protocol/src/mutation-type-enum.d.ts.map +1 -1
  172. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  173. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  174. package/out/zero-protocol/src/protocol-version.js +3 -1
  175. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  176. package/out/zero-protocol/src/push.d.ts +31 -6
  177. package/out/zero-protocol/src/push.d.ts.map +1 -1
  178. package/out/zero-protocol/src/push.js +7 -2
  179. package/out/zero-protocol/src/push.js.map +1 -1
  180. package/out/zero-protocol/src/up.d.ts +5 -1
  181. package/out/zero-protocol/src/up.d.ts.map +1 -1
  182. package/out/zero-protocol/src/up.js +2 -1
  183. package/out/zero-protocol/src/up.js.map +1 -1
  184. package/out/zero-react/src/use-query.d.ts +1 -2
  185. package/out/zero-react/src/use-query.d.ts.map +1 -1
  186. package/out/zero-schema/src/builder/table-builder.d.ts +13 -0
  187. package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
  188. package/out/zero-schema/src/builder/table-builder.js +17 -0
  189. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  190. package/out/zero-schema/src/permissions.d.ts.map +1 -1
  191. package/out/zero-schema/src/table-schema.d.ts +3 -1
  192. package/out/zero-schema/src/table-schema.d.ts.map +1 -1
  193. package/out/zero-schema/src/table-schema.js.map +1 -1
  194. package/out/zero-solid/src/create-zero.d.ts.map +1 -1
  195. package/out/zero-solid/src/solid-view.d.ts +1 -2
  196. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  197. package/out/zero-solid/src/use-query.d.ts +1 -2
  198. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  199. package/out/zero.js +7 -4
  200. package/out/zql/src/mutate/custom.d.ts +0 -1
  201. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  202. package/out/zql/src/mutate/custom.js.map +1 -1
  203. package/out/zql/src/query/query-impl.d.ts +9 -6
  204. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  205. package/out/zql/src/query/query-impl.js +16 -18
  206. package/out/zql/src/query/query-impl.js.map +1 -1
  207. package/out/zql/src/query/query-internal.d.ts +2 -9
  208. package/out/zql/src/query/query-internal.d.ts.map +1 -1
  209. package/out/zql/src/query/query.d.ts +5 -0
  210. package/out/zql/src/query/query.d.ts.map +1 -1
  211. package/out/zql/src/query/static-query.d.ts +1 -1
  212. package/out/zql/src/query/static-query.d.ts.map +1 -1
  213. package/out/zql/src/query/static-query.js +2 -2
  214. package/out/zql/src/query/static-query.js.map +1 -1
  215. package/out/zql/src/query/ttl.d.ts +1 -1
  216. package/out/zql/src/query/ttl.d.ts.map +1 -1
  217. package/out/zql/src/query/ttl.js +1 -1
  218. package/out/zql/src/query/ttl.js.map +1 -1
  219. package/out/zqlite/src/table-source.d.ts.map +1 -1
  220. package/out/zqlite/src/table-source.js +8 -0
  221. package/out/zqlite/src/table-source.js.map +1 -1
  222. package/package.json +4 -5
  223. package/out/chunk-5WXONOGR.js.map +0 -7
  224. package/out/chunk-ULOTOBTC.js +0 -1
  225. package/out/chunk-ULOTOBTC.js.map +0 -7
  226. package/out/inspector-ROITQB3J.js.map +0 -7
  227. package/out/zero-protocol/src/warm.d.ts +0 -10
  228. package/out/zero-protocol/src/warm.d.ts.map +0 -1
  229. package/out/zero-protocol/src/warm.js +0 -6
  230. package/out/zero-protocol/src/warm.js.map +0 -1
  231. package/out/zero-schema/src/mod.d.ts +0 -5
  232. package/out/zero-schema/src/mod.d.ts.map +0 -1
  233. package/out/zql/src/query/query-internal.js +0 -2
  234. package/out/zql/src/query/query-internal.js.map +0 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../ast-to-zql/src/ast-to-zql.ts", "../../z2s/src/sql.ts", "../../zero-cache/src/types/bigint-json.ts", "../../z2s/src/compiler.ts", "../../zero-client/src/client/inspector/inspector.ts"],
4
+ "sourcesContent": ["import {unreachable} from '../../shared/src/asserts.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Condition,\n Conjunction,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Disjunction,\n LiteralReference,\n Ordering,\n Parameter,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {SUBQ_PREFIX} from '../../zql/src/query/query-impl.ts';\n\n/**\n * Converts an AST to the equivalent query builder code.\n * This is useful for debugging and understanding queries.\n *\n * @example\n * ```\n * const ast = query.issue.where('id', '=', 123)[astForTestingSymbol];\n * console.log(astToZQL(ast)); // outputs: .where('id', '=', 123)\n * ```\n */\nexport function astToZQL(ast: AST): string {\n let code = '';\n\n // Handle where conditions\n if (ast.where) {\n code += transformCondition(ast.where, '.where', new Set());\n }\n\n // Handle related subqueries\n if (ast.related && ast.related.length > 0) {\n for (const related of ast.related) {\n if (!related.hidden) {\n code += transformRelated(related);\n }\n }\n }\n\n // Handle orderBy\n if (ast.orderBy && ast.orderBy.length > 0) {\n code += transformOrder(ast.orderBy);\n }\n\n // Handle limit\n if (ast.limit !== undefined) {\n code += `.limit(${ast.limit})`;\n }\n\n // Handle start\n if (ast.start) {\n const {row, exclusive} = ast.start;\n code += `.start(${JSON.stringify(row)}${\n exclusive ? '' : ', { inclusive: true }'\n })`;\n }\n\n return code;\n}\n\ntype Args = Set<string>;\n\ntype Prefix = '.where' | 'cmp';\n\nfunction transformCondition(\n condition: Condition,\n prefix: Prefix,\n args: Args,\n): string {\n switch (condition.type) {\n case 'simple':\n return transformSimpleCondition(condition, prefix);\n case 'and':\n case 'or':\n return transformLogicalCondition(condition, prefix, args);\n case 'correlatedSubquery':\n return transformExistsCondition(condition, prefix, args);\n default:\n unreachable(condition);\n }\n}\n\nfunction transformSimpleCondition(\n condition: SimpleCondition,\n prefix: Prefix,\n): string {\n const {left, op, right} = condition;\n\n const leftCode = transformValuePosition(left);\n const rightCode = transformValuePosition(right);\n\n // Handle the shorthand form for equals\n if (op === '=') {\n return `${prefix}(${leftCode}, ${rightCode})`;\n }\n\n return `${prefix}(${leftCode}, '${op}', ${rightCode})`;\n}\n\nfunction transformLogicalCondition(\n condition: Conjunction | Disjunction,\n prefix: Prefix,\n args: Args,\n): string {\n const {type, conditions} = condition;\n\n // For single condition, no need for logical operator\n if (conditions.length === 1) {\n return transformCondition(conditions[0], prefix, args);\n }\n\n // Generate multiple where calls for top-level AND conditions\n if (type === 'and') {\n const parts = conditions.map(c => transformCondition(c, prefix, args));\n // Simply concatenate the where conditions\n if (prefix === '.where') {\n return parts.join('');\n }\n args.add('and');\n return 'and(' + parts.join(', ') + ')';\n }\n\n args = new Set<string>();\n\n // Handle nested conditions with a callback for OR conditions and nested ANDs/ORs\n const conditionsCode = conditions\n .map(c => transformCondition(c, 'cmp', args))\n .join(', ');\n\n args.add('cmp');\n args.add(type);\n const argsCode = [...args].sort().join(', ');\n\n return `.where(({${argsCode}}) => ${type}(${conditionsCode}))`;\n}\n\nfunction transformExistsCondition(\n condition: CorrelatedSubqueryCondition,\n prefix: '.where' | 'cmp',\n args: Set<string>,\n): string {\n const {related, op} = condition;\n const relationship = extractRelationshipName(related);\n\n // Check if subquery has additional properties\n const hasSubQueryProps =\n related.subquery.where ||\n (related.subquery.related && related.subquery.related.length > 0) ||\n related.subquery.orderBy ||\n related.subquery.limit;\n\n if (op === 'EXISTS') {\n if (!hasSubQueryProps) {\n if (prefix === '.where') {\n return `.whereExists('${relationship}')`;\n }\n args.add('exists');\n return `exists('${relationship}')`;\n }\n\n if (prefix === '.where') {\n return `.whereExists('${relationship}', q => q${astToZQL(\n related.subquery,\n )}))`;\n }\n prefix satisfies 'cmp';\n args.add('exists');\n return `exists('${relationship}', q => q${astToZQL(related.subquery)})`;\n }\n\n op satisfies 'NOT EXISTS';\n\n if (hasSubQueryProps) {\n if (prefix === '.where') {\n return `.where(({exists, not}) => not(exists('${relationship}', q => q${astToZQL(\n related.subquery,\n )})))`;\n }\n prefix satisfies 'cmp';\n args.add('not');\n args.add('exists');\n return `not(exists('${relationship}', q => q${astToZQL(\n related.subquery,\n )}))`;\n }\n\n if (prefix === '.where') {\n return `.where(({exists, not}) => not(exists('${relationship}')))`;\n }\n args.add('not');\n args.add('exists');\n\n return `not(exists('${relationship}')))`;\n}\n\nfunction extractRelationshipName(related: CorrelatedSubquery): string {\n const alias = must(related.subquery.alias);\n return alias.startsWith(SUBQ_PREFIX)\n ? alias.substring(SUBQ_PREFIX.length)\n : alias;\n}\n\nfunction transformRelated(related: CorrelatedSubquery): string {\n const {alias} = related.subquery;\n if (!alias) return '';\n\n const relationship = alias;\n let code = `.related('${relationship}'`;\n\n // If the subquery has additional filters or configurations\n if (\n related.subquery.where ||\n (related.subquery.related && related.subquery.related.length > 0) ||\n related.subquery.orderBy ||\n related.subquery.limit\n ) {\n code += ', q => q' + astToZQL(related.subquery);\n }\n\n code += ')';\n return code;\n}\n\nfunction transformOrder(orderBy: Ordering): string {\n let code = '';\n for (const [field, direction] of orderBy) {\n code += `.orderBy('${field}', '${direction}')`;\n }\n return code;\n}\n\nfunction transformValuePosition(value: ValuePosition): string {\n switch (value.type) {\n case 'literal':\n return transformLiteral(value);\n case 'column':\n return `'${value.name}'`;\n case 'static':\n return transformParameter(value);\n default:\n unreachable(value);\n }\n}\n\nfunction transformLiteral(literal: LiteralReference): string {\n if (literal.value === null) {\n return 'null';\n }\n if (Array.isArray(literal.value)) {\n return JSON.stringify(literal.value);\n }\n if (typeof literal.value === 'string') {\n return `'${literal.value.replace(/'/g, \"\\\\'\")}'`;\n }\n return String(literal.value);\n}\n\nfunction transformParameter(param: Parameter): string {\n const fieldStr = Array.isArray(param.field)\n ? `[${param.field.map(f => `'${f}'`).join(', ')}]`\n : `'${param.field}'`;\n\n return `authParam(${fieldStr})`;\n}\n", "import type {SQLQuery, FormatConfig, SQLItem} from '@databases/sql';\nimport baseSql, {SQLItemType} from '@databases/sql';\nimport {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {ValueType} from '../../zero-protocol/src/client-schema.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport type {TypeNameToTypeMap} from '../../zero-schema/src/table-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');\ntype SqlConvertArg = {\n [sqlConvert]: true;\n type: ValueType;\n value: unknown;\n plural: boolean;\n};\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertArg<T extends ValueType, P extends boolean = false>(\n type: T,\n value: true extends P ? TypeNameToTypeMap[T][] : TypeNameToTypeMap[T],\n // plural is an explicit argument so we do not get confused by a singular JSON array vs\n // an array of JSON.\n plural?: P,\n): SQLQuery {\n return sql.value({[sqlConvert]: true, type, value, plural});\n}\n\nexport function sqlConvertArgUnsafe(\n type: ValueType,\n value: unknown,\n plural?: boolean,\n): SQLQuery {\n return sqlConvertArg(type, value as never, plural);\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 {\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n\n switch (arg.type) {\n case 'json':\n return JSON.stringify(arg.value);\n case 'boolean':\n return arg.value ? 'true' : 'false';\n case 'number':\n case 'date':\n case 'timestamp':\n return (arg.value as number).toString();\n case 'string':\n return arg.value as string;\n case 'null':\n return 'null';\n default:\n unreachable(arg.type);\n }\n}\n\nclass SQLConvertFormat 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 assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const key = value.value;\n if (this.#seen.has(key)) {\n return {\n placeholder: this.#createPlaceholder(this.#seen.get(key)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(key, this.#seen.size + 1);\n return {\n placeholder: this.#createPlaceholder(this.#seen.size, value),\n value: stringify(value),\n };\n };\n\n #createPlaceholder(index: number, value: SqlConvertArg) {\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\n const sqlType = pgType(value.type);\n\n if (!value.plural) {\n switch (value.type) {\n case 'json':\n // We use JSONB since that can be used as a primary key type\n // whereas JSON cannot. So JSONB covers more cases.\n return `$${index}::text::${sqlType}`;\n case 'boolean':\n return `$${index}::text::${sqlType}`;\n case 'number':\n return `$${index}::text::${sqlType}`;\n case 'string':\n return `$${index}::text`;\n case 'date':\n case 'timestamp':\n return `to_timestamp($${index}::text::${sqlType} / 1000.0) AT TIME ZONE 'UTC'`;\n case 'null':\n return 'NULL';\n default:\n unreachable(value.type);\n }\n }\n\n switch (value.type) {\n case 'json':\n case 'boolean':\n case 'number':\n return `ARRAY(\n SELECT value::${sqlType} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n case 'string':\n return `ARRAY(\n SELECT value FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n case 'date':\n case 'timestamp':\n return `ARRAY(\n SELECT to_timestamp(value::bigint / 1000.0)\n FROM jsonb_array_elements_text($${index}::text::jsonb)\n )::timestamp[]`;\n case 'null':\n throw new Error('unsupported null');\n default:\n unreachable(value.type);\n }\n }\n}\n\nfunction pgType(type: ValueType) {\n switch (type) {\n case 'json':\n return 'jsonb';\n case 'boolean':\n return 'boolean';\n case 'number':\n return 'numeric';\n case 'string':\n return 'text';\n case 'date':\n case 'timestamp':\n return 'bigint';\n case 'null':\n return 'null';\n default:\n unreachable(type);\n }\n}\n\nexport const sql = baseSql.default;\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\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 text += item.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 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.filter(l => l.trim() !== '').map(l => /^\\s*/.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", "/**\n * Background for using `json-custom-numbers`:\n *\n * https://neon.tech/blog/parsing-json-from-postgres-in-js\n */\nimport {\n parse as customParse,\n stringify as customStringify,\n} from 'json-custom-numbers';\nimport * as v from '../../../shared/src/valita.ts';\n\nfunction numberParser(_: unknown, v: string) {\n const n = +v;\n if (n >= Number.MIN_SAFE_INTEGER && n <= Number.MAX_SAFE_INTEGER) return n;\n if (v.indexOf('.') !== -1 || v.indexOf('e') !== -1 || v.indexOf('E') !== -1)\n return n;\n return BigInt(v);\n}\n\n// Variant of postgres.JSONValue adapted to include bigints\nexport type JSONValue =\n | null\n | string\n | number\n | bigint\n | boolean\n | readonly JSONValue[]\n | JSONObject;\n\nexport type JSONObject = {readonly [prop: string]: JSONValue | undefined};\n\nexport const jsonValueSchema: v.Type<JSONValue> = v.lazy(() => {\n const jsonObjectSchema = v.readonly(v.record(jsonValueSchema));\n\n return v.union(\n v.null(),\n v.string(),\n v.number(),\n v.bigint(),\n v.boolean(),\n v.readonly(v.array(jsonValueSchema)),\n jsonObjectSchema,\n );\n});\n\nexport const jsonObjectSchema = v.readonly(v.record(jsonValueSchema));\n\n/**\n * Parses JSON strings that may contain arbitrarily large integers. Integers\n * larger than {@link Number.MAX_SAFE_INTEGER} are deserialized as a `bigint`.\n */\nexport function parse(\n str: string,\n reviver?: (k: string, v: unknown) => unknown,\n): JSONValue {\n return customParse(str, reviver, numberParser);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction customSerializer(_: string, v: any, type: string) {\n if (type === 'bigint') return v.toString();\n}\n\n/**\n * Stringifies objects to JSON, supporting objects containing bigint values.\n * Note that the resulting JSON string may not be deserializable by\n * all environments, but it is supported by Postgres. The string should be\n * deserialized with the corresponding {@link parse} method that will represent\n * large numbers as bigints. From there it is up to the application to suitably\n * handle bigints passed to downstream logic.\n */\nexport function stringify(\n obj: unknown,\n replacer?:\n | (string | number)[]\n | ((key: string, value: unknown) => unknown)\n | null,\n indent?: string | number,\n) {\n return customStringify(obj, replacer, indent, customSerializer);\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const BigIntJSON = {\n parse,\n stringify,\n} as const;\n", "import type {SQLQuery} from '@databases/sql';\nimport {zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n CorrelatedSubqueryCondition,\n Correlation,\n Ordering,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n type AST,\n type Condition,\n type CorrelatedSubquery,\n type SimpleCondition,\n} from '../../zero-protocol/src/ast.ts';\nimport {clientToServer, NameMapper} from '../../zero-schema/src/name-mapper.ts';\nimport type {\n TableSchema,\n ValueType,\n} from '../../zero-schema/src/table-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {sql, sqlConvertArg, sqlConvertArgUnsafe} from './sql.ts';\nimport {\n type JSONValue as BigIntJSONValue,\n parse as parseBigIntJson,\n} from '../../zero-cache/src/types/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\n\ntype Tables = Record<string, TableSchema>;\n\nconst ZQL_RESULT_KEY = 'zql_result';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: 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\n/**\n * Compiles to the Postgres dialect of SQL\n * - IS, IS NOT can only compare against `NULL`, `TRUE`, `FALSE` so use\n * `IS DISTINCT FROM` and `IS NOT DISTINCT FROM` instead\n * - IN is changed to ANY to allow binding array literals\n * - subqueries are aggregated using PG's `array_agg` and `row_to_json` functions\n */\nexport function compile(\n ast: AST,\n tables: Tables,\n format?: Format | undefined,\n): SQLQuery {\n const compiler = new Compiler(tables);\n return compiler.compile(ast, format);\n}\n\nexport class Compiler {\n readonly #tables: Tables;\n readonly #nameMapper: NameMapper;\n\n constructor(tables: Tables) {\n this.#tables = tables;\n this.#nameMapper = clientToServer(tables);\n }\n\n compile(ast: AST, format?: Format | undefined): SQLQuery {\n return sql`SELECT ${this.#toJSON(\n `root`,\n format?.singular,\n )}::TEXT as ${sql.ident(ZQL_RESULT_KEY)} FROM (${this.select(\n ast,\n format,\n undefined,\n )})${sql.ident(`root`)}`;\n }\n\n select(\n ast: AST,\n // Is this a singular or plural query?\n format: Format | undefined,\n // If a select is being used as a subquery, this is the correlation to the parent query\n correlation: SQLQuery | undefined,\n ): SQLQuery {\n const selectionSet = this.related(ast.related ?? [], format, ast.table);\n const tableSchema = this.#tables[ast.table];\n for (const [column, columnSchema] of Object.entries(tableSchema.columns)) {\n selectionSet.push(this.#selectCol(ast.table, column, columnSchema.type));\n }\n return sql`SELECT ${sql.join(selectionSet, ',')} FROM ${this.#mapTable(\n ast.table,\n )} ${ast.where ? sql`WHERE ${this.where(ast.where, ast.table)}` : sql``} ${\n correlation\n ? sql`${ast.where ? sql`AND` : sql`WHERE`} (${correlation})`\n : sql``\n } ${this.orderBy(ast.orderBy, ast.table)} ${\n format?.singular ? this.limit(1) : this.limit(ast.limit)\n }`;\n }\n\n orderBy(orderBy: Ordering | undefined, table: string): 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 be 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`${sql.ident(table)}.${this.#mapColumnNoAlias(table, col)} ASC`\n : sql`${sql.ident(table)}.${this.#mapColumnNoAlias(table, col)} DESC`,\n ),\n ', ',\n )}`;\n }\n\n limit(limit: number | undefined): SQLQuery {\n if (!limit) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertArg('number', limit)}`;\n }\n\n related(\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: string,\n ): SQLQuery[] {\n return relationships.map(relationship =>\n this.relationshipSubquery(\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n }\n\n relationshipSubquery(\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: string,\n ): SQLQuery {\n if (relationship.hidden) {\n const [join, lastAlias, lastLimit, lastTable] =\n this.makeJunctionJoin(relationship);\n const lastClientColumns = Object.keys(this.#tables[lastTable].columns);\n /**\n * This aggregates the relationship subquery into an array of objects.\n * This looks roughly like:\n *\n * SELECT COALESCE(json_agg(row_to_json(\"inner_owner\")) , '[]'::json) FROM\n * (SELECT mytable.col as client_col, mytable.col2 as client_col2 FROM mytable) inner_mytable\n */\n return sql`(\n SELECT ${this.#toJSON(\n `inner_${relationship.subquery.alias}`,\n format?.singular,\n )} FROM (SELECT ${sql.join(\n lastClientColumns.map(\n c => sql`${sql.ident(lastAlias)}.${this.#mapColumn(lastTable, c)}`,\n ),\n ',',\n )} FROM ${join} WHERE (${this.correlate(\n parentTable,\n parentTable,\n relationship.correlation.parentField,\n relationship.subquery.table,\n relationship.subquery.table,\n relationship.correlation.childField,\n )}) ${\n relationship.subquery.where\n ? sql`AND ${this.where(\n relationship.subquery.where,\n relationship.subquery.table,\n )}`\n : sql``\n } ${this.orderBy(\n relationship.subquery.orderBy,\n relationship.subquery.table,\n )} ${\n format?.singular ? this.limit(1) : this.limit(lastLimit)\n } ) ${sql.ident(`inner_${relationship.subquery.alias}`)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n return sql`(\n SELECT ${\n format?.singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(`inner_${relationship.subquery.alias}`)})) ${\n format?.singular ? sql`` : sql`, '[]'::json)`\n } FROM (${this.select(\n relationship.subquery,\n format,\n this.correlate(\n parentTable,\n parentTable,\n relationship.correlation.parentField,\n relationship.subquery.table,\n relationship.subquery.table,\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(`inner_${relationship.subquery.alias}`)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n pullTablesForJunction(\n relationship: CorrelatedSubquery,\n tables: [string, Correlation, number | undefined][] = [],\n ) {\n tables.push([\n relationship.subquery.table,\n relationship.correlation,\n relationship.subquery.limit,\n ]);\n assert(\n relationship.subquery.related?.length || 0 <= 1,\n 'Too many related tables for a junction edge',\n );\n for (const subRelationship of relationship.subquery.related ?? []) {\n this.pullTablesForJunction(subRelationship, tables);\n }\n return tables;\n }\n\n makeJunctionJoin(\n relationship: CorrelatedSubquery,\n ): [\n join: SQLQuery,\n lastAlis: string,\n lastLimit: number | undefined,\n lastTable: string,\n ] {\n const participatingTables = this.pullTablesForJunction(relationship);\n const joins: SQLQuery[] = [];\n\n function alias(index: number) {\n if (index === 0) {\n return participatingTables[0][0];\n }\n return `table_${index}`;\n }\n\n for (const [table, _correlation] of participatingTables) {\n if (joins.length === 0) {\n joins.push(this.#mapTable(table));\n continue;\n }\n joins.push(\n sql` JOIN ${this.#mapTableNoAlias(table)} as ${sql.ident(\n alias(joins.length),\n )} ON ${this.correlate(\n participatingTables[joins.length - 1][0],\n alias(joins.length - 1),\n participatingTables[joins.length][1].parentField,\n participatingTables[joins.length][0],\n alias(joins.length),\n participatingTables[joins.length][1].childField,\n )}`,\n );\n }\n\n return [\n sql.join(joins, ''),\n alias(joins.length - 1),\n participatingTables[participatingTables.length - 1][2],\n participatingTables[participatingTables.length - 1][0],\n ] as const;\n }\n\n where(condition: Condition | undefined, table: string): 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 => this.where(c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => this.where(c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n return this.exists(condition, table);\n case 'simple':\n return this.simple(condition, table);\n }\n }\n\n simple(condition: SimpleCondition, table: string): SQLQuery {\n switch (condition.op) {\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE':\n return sql`${this.valuePosition(\n condition.left,\n table,\n this.#extractType(table, condition.left, condition.right),\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${this.valuePosition(\n condition.right,\n table,\n this.#extractType(table, condition.right, condition.left),\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return this.any(condition, table);\n case 'IS':\n case 'IS NOT':\n return this.distinctFrom(condition, table);\n }\n }\n\n distinctFrom(condition: SimpleCondition, table: string): SQLQuery {\n return sql`${this.valuePosition(condition.left, table, this.#extractType(table, condition.left, condition.right), false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${this.valuePosition(condition.right, table, this.#extractType(table, condition.right, condition.left), false)}`;\n }\n\n any(condition: SimpleCondition, table: string): SQLQuery {\n return sql`${this.valuePosition(condition.left, table, this.#extractType(table, condition.left, condition.right), false)} ${\n condition.op === 'IN' ? sql`= ANY` : sql`!= ANY`\n } (${this.valuePosition(condition.right, table, this.#extractType(table, condition.right, condition.left), true)})`;\n }\n\n valuePosition(\n value: ValuePosition,\n table: string,\n valueType: ValueType,\n plural: boolean,\n ): SQLQuery {\n switch (value.type) {\n case 'column':\n return this.#mapColumnNoAlias(table, value.name);\n case 'literal':\n return sqlConvertArgUnsafe(valueType, value.value, plural);\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n }\n }\n\n exists(\n condition: CorrelatedSubqueryCondition,\n parentTable: string,\n ): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${this.select(\n condition.related.subquery,\n undefined,\n this.correlate(\n parentTable,\n parentTable,\n condition.related.correlation.parentField,\n condition.related.subquery.table,\n condition.related.subquery.table,\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${this.select(\n condition.related.subquery,\n undefined,\n undefined,\n )})`;\n }\n }\n\n correlate(\n // The table being correlated could be aliased to some other name\n // in the case of a junction. Hence we pass `xTableAlias`. The original\n // name of the table is required so we can look up the server names of the columns\n // to be used in the correlation.\n parentTable: string,\n parentTableAlias: string,\n parentColumns: readonly string[],\n childTable: string,\n childTableAlias: string,\n childColumns: readonly string[],\n ): SQLQuery {\n return sql.join(\n zip(parentColumns, childColumns).map(\n ([parentColumn, childColumn]) =>\n sql`${sql.ident(parentTableAlias)}.${this.#mapColumnNoAlias(\n parentTable,\n parentColumn,\n )} = ${sql.ident(childTableAlias)}.${this.#mapColumnNoAlias(\n childTable,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n }\n\n #mapColumn(table: string, column: string) {\n const mapped = this.#nameMapper.columnName(table, column);\n if (mapped === column) {\n return sql.ident(column);\n }\n\n return sql`${sql.ident(mapped)} as ${sql.ident(column)}`;\n }\n\n #mapColumnNoAlias(table: string, column: string) {\n const mapped = this.#nameMapper.columnName(table, column);\n return sql.ident(mapped);\n }\n\n #mapTable(table: string) {\n const mapped = this.#nameMapper.tableName(table);\n if (mapped === table) {\n return sql.ident(table);\n }\n\n return sql`${sql.ident(mapped)} as ${sql.ident(table)}`;\n }\n\n #mapTableNoAlias(table: string) {\n const mapped = this.#nameMapper.tableName(table);\n return sql.ident(mapped);\n }\n\n #selectCol(table: string, column: string, type: ValueType) {\n if (type === 'date' || type === 'timestamp') {\n return sql`EXTRACT(EPOCH FROM ${sql.ident(\n table,\n )}.${this.#mapColumnNoAlias(\n table,\n column,\n )}::timestamp AT TIME ZONE 'UTC') * 1000 as ${sql.ident(column)}`;\n }\n return sql`${sql.ident(table)}.${this.#mapColumn(table, column)}`;\n }\n\n #toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)})) ${\n singular ? sql`` : sql`, '[]'::json)`\n }`;\n }\n\n #extractType(\n table: string,\n // first takes precedence over second in terms of type discovery\n first: ValuePosition,\n second: ValuePosition,\n ): ValueType {\n // Derive the type from the table schema first if able\n const column =\n first.type === 'column'\n ? first.name\n : second.type === 'column'\n ? second.name\n : undefined;\n if (column) {\n return this.#tables[table].columns[column].type;\n }\n\n // We're comparing two literals? Derive the type from the JS type itself.\n const literalValue =\n first.type === 'literal'\n ? first.value\n : second.type === 'literal'\n ? second.value\n : undefined;\n\n assert(literalValue, 'Literal value not found');\n\n if (literalValue === null) {\n return 'null';\n }\n\n const jsType = typeof literalValue;\n switch (jsType) {\n case 'boolean':\n case 'number':\n case 'string':\n return jsType;\n case 'object':\n case 'bigint':\n case 'function':\n case 'symbol':\n case 'undefined':\n throw new Error('Unsupported type: ' + jsType);\n default:\n unreachable(jsType);\n }\n }\n}\n", "import {astToZQL} from '../../../../ast-to-zql/src/ast-to-zql.ts';\nimport type {BTreeRead} from '../../../../replicache/src/btree/read.ts';\nimport {type Read} from '../../../../replicache/src/dag/store.ts';\nimport {readFromHash} from '../../../../replicache/src/db/read.ts';\nimport * as FormatVersion from '../../../../replicache/src/format-version-enum.ts';\nimport {getClientGroup} from '../../../../replicache/src/persist/client-groups.ts';\nimport {\n getClient,\n getClients,\n type ClientMap,\n} from '../../../../replicache/src/persist/clients.ts';\nimport type {ReplicacheImpl} from '../../../../replicache/src/replicache-impl.ts';\nimport {withRead} from '../../../../replicache/src/with-transactions.ts';\nimport {assert} from '../../../../shared/src/asserts.ts';\nimport type {ReadonlyJSONValue} from '../../../../shared/src/json.ts';\nimport * as valita from '../../../../shared/src/valita.ts';\nimport {compile} from '../../../../z2s/src/compiler.ts';\nimport {formatPg} from '../../../../z2s/src/sql.ts';\nimport type {AST} from '../../../../zero-protocol/src/ast.ts';\nimport type {Row} from '../../../../zero-protocol/src/data.ts';\nimport {\n inspectQueriesDownSchema,\n type InspectDownBody,\n type InspectQueryRow,\n} from '../../../../zero-protocol/src/inspect-down.ts';\nimport type {\n InspectQueriesUpBody,\n InspectUpBody,\n InspectUpMessage,\n} from '../../../../zero-protocol/src/inspect-up.ts';\nimport type {Schema} from '../../../../zero-schema/src/builder/schema-builder.ts';\nimport type {Format} from '../../../../zql/src/ivm/view.ts';\nimport {normalizeTTL, type TTL} from '../../../../zql/src/query/ttl.ts';\nimport {nanoid} from '../../util/nanoid.ts';\nimport {ENTITIES_KEY_PREFIX} from '../keys.ts';\nimport type {MutatorDefs} from '../replicache-types.ts';\nimport type {\n ClientGroup as ClientGroupInterface,\n Client as ClientInterface,\n Inspector as InspectorInterface,\n Query as QueryInterface,\n} from './types.ts';\n\ntype Rep = ReplicacheImpl<MutatorDefs>;\n\ntype GetWebSocket = () => WebSocket | undefined;\n\nexport async function newInspector(\n rep: Rep,\n schema: Schema,\n socket: GetWebSocket,\n): Promise<InspectorInterface> {\n const clientGroupID = await rep.clientGroupID;\n return new Inspector(rep, schema, rep.clientID, clientGroupID, socket);\n}\n\nclass Inspector implements InspectorInterface {\n readonly #rep: Rep;\n readonly client: Client;\n readonly clientGroup: ClientGroup;\n readonly #schema: Schema;\n readonly socket: GetWebSocket;\n\n constructor(\n rep: ReplicacheImpl,\n schema: Schema,\n clientID: string,\n clientGroupID: string,\n socket: GetWebSocket,\n ) {\n this.#rep = rep;\n this.#schema = schema;\n this.client = new Client(rep, schema, socket, clientID, clientGroupID);\n this.clientGroup = this.client.clientGroup;\n this.socket = socket;\n }\n\n clients(): Promise<ClientInterface[]> {\n return withDagRead(this.#rep, dagRead =>\n clients(this.#rep, this.socket, this.#schema, dagRead),\n );\n }\n\n clientsWithQueries(): Promise<ClientInterface[]> {\n return withDagRead(this.#rep, dagRead =>\n clientsWithQueries(this.#rep, this.socket, this.#schema, dagRead),\n );\n }\n}\n\nfunction rpc<T extends InspectDownBody>(\n socket: WebSocket | undefined,\n arg: Omit<InspectUpBody, 'id'>,\n downSchema: valita.Type<T>,\n): Promise<T['value']> {\n assert(socket, 'WebSocket not available');\n return new Promise((resolve, reject) => {\n const id = nanoid();\n const f = (ev: MessageEvent) => {\n const msg = JSON.parse(ev.data);\n if (msg[0] === 'inspect') {\n const body = msg[1];\n if (body.id !== id) {\n return;\n }\n const res = valita.test(body, downSchema);\n if (res.ok) {\n resolve(res.value.value);\n } else {\n reject(res.error);\n }\n socket.removeEventListener('message', f);\n }\n };\n socket.addEventListener('message', f);\n socket.send(\n JSON.stringify(['inspect', {...arg, id}] satisfies InspectUpMessage),\n );\n });\n}\n\nclass Client implements ClientInterface {\n readonly #rep: Rep;\n readonly id: string;\n readonly clientGroup: ClientGroup;\n readonly #schema: Schema;\n readonly #socket: GetWebSocket;\n\n constructor(\n rep: Rep,\n schema: Schema,\n socket: GetWebSocket,\n id: string,\n clientGroupID: string,\n ) {\n this.#rep = rep;\n this.#schema = schema;\n this.#socket = socket;\n this.id = id;\n this.clientGroup = new ClientGroup(rep, socket, schema, clientGroupID);\n }\n\n async queries(): Promise<QueryInterface[]> {\n const rows: InspectQueryRow[] = await rpc(\n this.#socket(),\n {op: 'queries', clientID: this.id} as InspectQueriesUpBody,\n inspectQueriesDownSchema,\n );\n return rows.map(row => new Query(row, this.#schema));\n }\n\n map(): Promise<Map<string, ReadonlyJSONValue>> {\n return withDagRead(this.#rep, async dagRead => {\n const tree = await getBTree(dagRead, this.id);\n const map = new Map<string, ReadonlyJSONValue>();\n for await (const [key, value] of tree.scan('')) {\n map.set(key, value);\n }\n return map;\n });\n }\n\n rows(tableName: string): Promise<Row[]> {\n return withDagRead(this.#rep, async dagRead => {\n const prefix = ENTITIES_KEY_PREFIX + tableName;\n const tree = await getBTree(dagRead, this.id);\n const rows: Row[] = [];\n for await (const [key, value] of tree.scan(prefix)) {\n if (!key.startsWith(prefix)) {\n break;\n }\n rows.push(value as Row);\n }\n return rows;\n });\n }\n}\n\nclass ClientGroup implements ClientGroupInterface {\n readonly #rep: Rep;\n readonly id: string;\n readonly #schema: Schema;\n readonly #socket: GetWebSocket;\n\n constructor(rep: Rep, socket: GetWebSocket, schema: Schema, id: string) {\n this.#rep = rep;\n this.#socket = socket;\n this.#schema = schema;\n this.id = id;\n }\n\n clients(): Promise<ClientInterface[]> {\n return withDagRead(this.#rep, dagRead =>\n clients(\n this.#rep,\n this.#socket,\n this.#schema,\n dagRead,\n ([_, v]) => v.clientGroupID === this.id,\n ),\n );\n }\n\n clientsWithQueries(): Promise<ClientInterface[]> {\n return withDagRead(this.#rep, dagRead =>\n clientsWithQueries(\n this.#rep,\n this.#socket,\n this.#schema,\n dagRead,\n ([_, v]) => v.clientGroupID === this.id,\n ),\n );\n }\n\n async queries(): Promise<QueryInterface[]> {\n const rows: InspectQueryRow[] = await rpc(\n this.#socket(),\n {op: 'queries'},\n inspectQueriesDownSchema,\n );\n return rows.map(row => new Query(row, this.#schema));\n }\n}\n\nasync function withDagRead<T>(\n rep: Rep,\n f: (dagRead: Read) => Promise<T>,\n): Promise<T> {\n await rep.refresh();\n await rep.persist();\n return withRead(rep.perdag, f);\n}\n\nasync function getBTree(dagRead: Read, clientID: string): Promise<BTreeRead> {\n const client = await getClient(clientID, dagRead);\n assert(client, `Client not found: ${clientID}`);\n const {clientGroupID} = client;\n const clientGroup = await getClientGroup(clientGroupID, dagRead);\n assert(clientGroup, `Client group not found: ${clientGroupID}`);\n const dbRead = await readFromHash(\n clientGroup.headHash,\n dagRead,\n FormatVersion.Latest,\n );\n return dbRead.map;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MapEntry<T extends ReadonlyMap<any, any>> =\n T extends ReadonlyMap<infer K, infer V> ? readonly [K, V] : never;\n\nasync function clients(\n rep: Rep,\n socket: GetWebSocket,\n schema: Schema,\n dagRead: Read,\n predicate: (entry: MapEntry<ClientMap>) => boolean = () => true,\n): Promise<ClientInterface[]> {\n const clients = await getClients(dagRead);\n return [...clients.entries()]\n .filter(predicate)\n .map(\n ([clientID, {clientGroupID}]) =>\n new Client(rep, schema, socket, clientID, clientGroupID),\n );\n}\n\nasync function clientsWithQueries(\n rep: Rep,\n socket: GetWebSocket,\n schema: Schema,\n dagRead: Read,\n predicate: (entry: MapEntry<ClientMap>) => boolean = () => true,\n): Promise<ClientInterface[]> {\n const allClients = await clients(rep, socket, schema, dagRead, predicate);\n const clientsWithQueries: ClientInterface[] = [];\n await Promise.all(\n allClients.map(async client => {\n const queries = await client.queries();\n if (queries.length > 0) {\n clientsWithQueries.push(client);\n }\n }),\n );\n return clientsWithQueries;\n}\n\nclass Query implements QueryInterface {\n readonly ast: AST;\n readonly got: boolean;\n readonly ttl: TTL;\n readonly inactivatedAt: Date | null;\n readonly rowCount: number;\n readonly deleted: boolean;\n readonly id: string;\n readonly sql: string;\n readonly zql: string;\n readonly clientID: string;\n\n constructor(row: InspectQueryRow, schema: Schema) {\n // Use own properties to make this more useful in dev tools. For example, in\n // Chrome dev tools, if you do console.table(queries) you'll see the\n // properties in the table, if these were getters you would not see them in the table.\n this.clientID = row.clientID;\n this.id = row.queryID;\n this.inactivatedAt =\n row.inactivatedAt === null ? null : new Date(row.inactivatedAt);\n this.ttl = normalizeTTL(row.ttl);\n this.ast = row.ast;\n this.got = row.got;\n this.rowCount = row.rowCount;\n this.deleted = row.deleted;\n\n const format: Format = {\n singular: false,\n relationships: {},\n };\n const sqlQuery = formatPg(compile(this.ast, schema.tables, format));\n this.sql = sqlQuery.text;\n this.zql = this.ast.table + astToZQL(this.ast);\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,SAAS,SAAS,KAAkB;AACzC,MAAI,OAAO;AAGX,MAAI,IAAI,OAAO;AACb,YAAQ,mBAAmB,IAAI,OAAO,UAAU,oBAAI,IAAI,CAAC;AAAA,EAC3D;AAGA,MAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,GAAG;AACzC,eAAW,WAAW,IAAI,SAAS;AACjC,UAAI,CAAC,QAAQ,QAAQ;AACnB,gBAAQ,iBAAiB,OAAO;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAGA,MAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,GAAG;AACzC,YAAQ,eAAe,IAAI,OAAO;AAAA,EACpC;AAGA,MAAI,IAAI,UAAU,QAAW;AAC3B,YAAQ,UAAU,IAAI,KAAK;AAAA,EAC7B;AAGA,MAAI,IAAI,OAAO;AACb,UAAM,EAAC,KAAK,UAAS,IAAI,IAAI;AAC7B,YAAQ,UAAU,KAAK,UAAU,GAAG,CAAC,GACnC,YAAY,KAAK,uBACnB;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,mBACP,WACA,QACA,MACQ;AACR,UAAQ,UAAU,MAAM;AAAA,IACtB,KAAK;AACH,aAAO,yBAAyB,WAAW,MAAM;AAAA,IACnD,KAAK;AAAA,IACL,KAAK;AACH,aAAO,0BAA0B,WAAW,QAAQ,IAAI;AAAA,IAC1D,KAAK;AACH,aAAO,yBAAyB,WAAW,QAAQ,IAAI;AAAA,IACzD;AACE,kBAAY,SAAS;AAAA,EACzB;AACF;AAEA,SAAS,yBACP,WACA,QACQ;AACR,QAAM,EAAC,MAAM,IAAI,MAAK,IAAI;AAE1B,QAAM,WAAW,uBAAuB,IAAI;AAC5C,QAAM,YAAY,uBAAuB,KAAK;AAG9C,MAAI,OAAO,KAAK;AACd,WAAO,GAAG,MAAM,IAAI,QAAQ,KAAK,SAAS;AAAA,EAC5C;AAEA,SAAO,GAAG,MAAM,IAAI,QAAQ,MAAM,EAAE,MAAM,SAAS;AACrD;AAEA,SAAS,0BACP,WACA,QACA,MACQ;AACR,QAAM,EAAC,MAAM,WAAU,IAAI;AAG3B,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO,mBAAmB,WAAW,CAAC,GAAG,QAAQ,IAAI;AAAA,EACvD;AAGA,MAAI,SAAS,OAAO;AAClB,UAAM,QAAQ,WAAW,IAAI,OAAK,mBAAmB,GAAG,QAAQ,IAAI,CAAC;AAErE,QAAI,WAAW,UAAU;AACvB,aAAO,MAAM,KAAK,EAAE;AAAA,IACtB;AACA,SAAK,IAAI,KAAK;AACd,WAAO,SAAS,MAAM,KAAK,IAAI,IAAI;AAAA,EACrC;AAEA,SAAO,oBAAI,IAAY;AAGvB,QAAM,iBAAiB,WACpB,IAAI,OAAK,mBAAmB,GAAG,OAAO,IAAI,CAAC,EAC3C,KAAK,IAAI;AAEZ,OAAK,IAAI,KAAK;AACd,OAAK,IAAI,IAAI;AACb,QAAM,WAAW,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI;AAE3C,SAAO,YAAY,QAAQ,SAAS,IAAI,IAAI,cAAc;AAC5D;AAEA,SAAS,yBACP,WACA,QACA,MACQ;AACR,QAAM,EAAC,SAAS,GAAE,IAAI;AACtB,QAAM,eAAe,wBAAwB,OAAO;AAGpD,QAAM,mBACJ,QAAQ,SAAS,SAChB,QAAQ,SAAS,WAAW,QAAQ,SAAS,QAAQ,SAAS,KAC/D,QAAQ,SAAS,WACjB,QAAQ,SAAS;AAEnB,MAAI,OAAO,UAAU;AACnB,QAAI,CAAC,kBAAkB;AACrB,UAAI,WAAW,UAAU;AACvB,eAAO,iBAAiB,YAAY;AAAA,MACtC;AACA,WAAK,IAAI,QAAQ;AACjB,aAAO,WAAW,YAAY;AAAA,IAChC;AAEA,QAAI,WAAW,UAAU;AACvB,aAAO,iBAAiB,YAAY,YAAY;AAAA,QAC9C,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA;AACA,SAAK,IAAI,QAAQ;AACjB,WAAO,WAAW,YAAY,YAAY,SAAS,QAAQ,QAAQ,CAAC;AAAA,EACtE;AAEA;AAEA,MAAI,kBAAkB;AACpB,QAAI,WAAW,UAAU;AACvB,aAAO,yCAAyC,YAAY,YAAY;AAAA,QACtE,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA;AACA,SAAK,IAAI,KAAK;AACd,SAAK,IAAI,QAAQ;AACjB,WAAO,eAAe,YAAY,YAAY;AAAA,MAC5C,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,MAAI,WAAW,UAAU;AACvB,WAAO,yCAAyC,YAAY;AAAA,EAC9D;AACA,OAAK,IAAI,KAAK;AACd,OAAK,IAAI,QAAQ;AAEjB,SAAO,eAAe,YAAY;AACpC;AAEA,SAAS,wBAAwB,SAAqC;AACpE,QAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK;AACzC,SAAO,MAAM,WAAW,WAAW,IAC/B,MAAM,UAAU,YAAY,MAAM,IAClC;AACN;AAEA,SAAS,iBAAiB,SAAqC;AAC7D,QAAM,EAAC,MAAK,IAAI,QAAQ;AACxB,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,eAAe;AACrB,MAAI,OAAO,aAAa,YAAY;AAGpC,MACE,QAAQ,SAAS,SAChB,QAAQ,SAAS,WAAW,QAAQ,SAAS,QAAQ,SAAS,KAC/D,QAAQ,SAAS,WACjB,QAAQ,SAAS,OACjB;AACA,YAAQ,aAAa,SAAS,QAAQ,QAAQ;AAAA,EAChD;AAEA,UAAQ;AACR,SAAO;AACT;AAEA,SAAS,eAAe,SAA2B;AACjD,MAAI,OAAO;AACX,aAAW,CAAC,OAAO,SAAS,KAAK,SAAS;AACxC,YAAQ,aAAa,KAAK,OAAO,SAAS;AAAA,EAC5C;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,OAA8B;AAC5D,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,iBAAiB,KAAK;AAAA,IAC/B,KAAK;AACH,aAAO,IAAI,MAAM,IAAI;AAAA,IACvB,KAAK;AACH,aAAO,mBAAmB,KAAK;AAAA,IACjC;AACE,kBAAY,KAAK;AAAA,EACrB;AACF;AAEA,SAAS,iBAAiB,SAAmC;AAC3D,MAAI,QAAQ,UAAU,MAAM;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,QAAQ,KAAK,GAAG;AAChC,WAAO,KAAK,UAAU,QAAQ,KAAK;AAAA,EACrC;AACA,MAAI,OAAO,QAAQ,UAAU,UAAU;AACrC,WAAO,IAAI,QAAQ,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC/C;AACA,SAAO,OAAO,QAAQ,KAAK;AAC7B;AAEA,SAAS,mBAAmB,OAA0B;AACpD,QAAM,WAAW,MAAM,QAAQ,MAAM,KAAK,IACtC,IAAI,MAAM,MAAM,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,MAC7C,IAAI,MAAM,KAAK;AAEnB,SAAO,aAAa,QAAQ;AAC9B;;;AC3QA,OAAO,WAAU,mBAAkB;AACnC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAKA,SAAS,SAASA,MAAe;AACtC,QAAM,SAAS,IAAI,cAAc,wBAAwB;AACzD,SAAOA,KAAI,OAAO,CAAC,UAA8B,SAAS,OAAO,MAAM,CAAC;AAC1E;AAYA,IAAM,aAAa,OAAO,UAAU;AAW7B,SAAS,cACd,MACA,OAGA,QACU;AACV,SAAO,IAAI,MAAM,EAAC,CAAC,UAAU,GAAG,MAAM,MAAM,OAAO,OAAM,CAAC;AAC5D;AAEO,SAAS,oBACd,MACA,OACA,QACU;AACV,SAAO,cAAc,MAAM,OAAgB,MAAM;AACnD;AAEA,IAAM,gBAAN,MAA4C;AAAA,EACjC,QAA8B,oBAAI,IAAI;AAAA,EACtC;AAAA,EAET,YAAY,kBAA2C;AACrD,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,cAAc,CAAC,UAAmB;AAChC,QAAI,KAAK,MAAM,IAAI,KAAK,GAAG;AACzB,aAAO;AAAA,QACL,aAAa,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC;AAAA,QACtC,OAAO;AAAA,MACT;AAAA,IACF;AACA,SAAK,MAAM,IAAI,OAAO,KAAK,MAAM,OAAO,CAAC;AACzC,WAAO,EAAC,aAAa,IAAI,KAAK,MAAM,IAAI,IAAI,MAAK;AAAA,EACnD;AACF;AA8HO,IAAM,MAAM,QAAQ;AAE3B,IAAM,wBAAwB,OAAO,uBAAuB;AAC5D,SAAS,SACP,OACA,EAAC,kBAAkB,YAAW,GAI9B;AAEA,MAAI,OAAO;AACX,QAAM,SAAS,CAAC;AAEhB,QAAM,mBAAmB,oBAAI,IAAqB;AAElD,aAAW,QAAQ,OAAO;AACxB,YAAQ,KAAK,MAAM;AAAA;AAAA,MAEjB,KAAK,YAAY,KAAK;AACpB,gBAAQ,KAAK;AACb;AAAA,MACF;AAAA;AAAA;AAAA,MAIA,KAAK,YAAY,OAAO;AACtB,cAAM,EAAC,aAAa,MAAK,IAAI,YAAY,KAAK,OAAO,OAAO,MAAM;AAClE,gBAAQ;AACR,YAAI,UAAU,uBAAuB;AACnC,iBAAO,KAAK,KAAK;AAAA,QACnB;AAEA;AAAA,MACF;AAAA;AAAA;AAAA,MAIA,KAAK,YAAY,YAAY;AAC3B,gBAAQ,KAAK,MACV,IAAI,CAAC,SAAiB;AACrB,cAAI,OAAO,SAAS,SAAU,QAAO,iBAAiB,IAAI;AAE1D,cAAI,CAAC,iBAAiB,IAAI,IAAI;AAC5B,6BAAiB,IAAI,MAAM,WAAW,iBAAiB,IAAI,IAAI;AAEjE,iBAAO,iBAAiB,iBAAiB,IAAI,IAAI,CAAE;AAAA,QACrD,CAAC,EACA,KAAK,GAAG;AACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,KAAK,GAAG;AACf,UAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,UAAM,MAAM,KAAK;AAAA,MACf,GAAG,MAAM,OAAO,OAAK,EAAE,KAAK,MAAM,EAAE,EAAE,IAAI,OAAK,OAAO,KAAK,CAAC,EAAG,CAAC,EAAE,MAAM;AAAA,IAC1E;AACA,QAAI,KAAK;AACP,aAAO,MAAM,IAAI,UAAQ,KAAK,OAAO,GAAG,CAAC,EAAE,KAAK,IAAI;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,KAAK,KAAK;AAAA,IAChB;AAAA,EACF;AACF;;;ACpQA;AAAA,EACE,SAAS;AAAA,EACT,aAAa;AAAA,OACR;AAuBA,IAAM,kBAAuC,oBAAK,MAAM;AAC7D,QAAMC,oBAAqB,SAAW,sBAAO,eAAe,CAAC;AAE7D,SAAS;AAAA,IACL,oBAAK;AAAA,IACL,sBAAO;AAAA,IACP,sBAAO;AAAA,IACP,sBAAO;AAAA,IACP,uBAAQ;AAAA,IACR,SAAW,qBAAM,eAAe,CAAC;AAAA,IACnCA;AAAA,EACF;AACF,CAAC;AAEM,IAAM,mBAAqB,SAAW,sBAAO,eAAe,CAAC;;;ACbpE,IAAM,iBAAiB;AA+DhB,SAAS,QACd,KACA,QACA,QACU;AACV,QAAM,WAAW,IAAI,SAAS,MAAM;AACpC,SAAO,SAAS,QAAQ,KAAK,MAAM;AACrC;AAEO,IAAM,WAAN,MAAe;AAAA,EACX;AAAA,EACA;AAAA,EAET,YAAY,QAAgB;AAC1B,SAAK,UAAU;AACf,SAAK,cAAc,eAAe,MAAM;AAAA,EAC1C;AAAA,EAEA,QAAQ,KAAU,QAAuC;AACvD,WAAO,aAAa,KAAK;AAAA,MACvB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC,aAAa,IAAI,MAAM,cAAc,CAAC,UAAU,KAAK;AAAA,MACpD;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,EACxB;AAAA,EAEA,OACE,KAEA,QAEA,aACU;AACV,UAAM,eAAe,KAAK,QAAQ,IAAI,WAAW,CAAC,GAAG,QAAQ,IAAI,KAAK;AACtE,UAAM,cAAc,KAAK,QAAQ,IAAI,KAAK;AAC1C,eAAW,CAAC,QAAQ,YAAY,KAAK,OAAO,QAAQ,YAAY,OAAO,GAAG;AACxE,mBAAa,KAAK,KAAK,WAAW,IAAI,OAAO,QAAQ,aAAa,IAAI,CAAC;AAAA,IACzE;AACA,WAAO,aAAa,IAAI,KAAK,cAAc,GAAG,CAAC,SAAS,KAAK;AAAA,MAC3D,IAAI;AAAA,IACN,CAAC,IAAI,IAAI,QAAQ,YAAY,KAAK,MAAM,IAAI,OAAO,IAAI,KAAK,CAAC,KAAK,KAAK,IACrE,cACI,MAAM,IAAI,QAAQ,WAAW,UAAU,KAAK,WAAW,MACvD,KACN,IAAI,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,CAAC,IACtC,QAAQ,WAAW,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CACzD;AAAA,EACF;AAAA,EAEA,QAAQ,SAA+B,OAAyB;AAC9D,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,WAAO,eAAe,IAAI;AAAA,MACxB,QAAQ;AAAA,QAAI,CAAC,CAAC,KAAK,GAAG,MACpB,QAAQ;AAAA;AAAA;AAAA,UAGJ,MAAM,IAAI,MAAM,KAAK,CAAC,IAAI,KAAK,kBAAkB,OAAO,GAAG,CAAC;AAAA,YAC5D,MAAM,IAAI,MAAM,KAAK,CAAC,IAAI,KAAK,kBAAkB,OAAO,GAAG,CAAC;AAAA,MAClE;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAqC;AACzC,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AACA,WAAO,YAAY,cAAc,UAAU,KAAK,CAAC;AAAA,EACnD;AAAA,EAEA,QACE,eACA,QACA,aACY;AACZ,WAAO,cAAc;AAAA,MAAI,kBACvB,KAAK;AAAA,QACH;AAAA,QACA,QAAQ,cAAc,KAAK,aAAa,SAAS,KAAK,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,qBACE,cACA,QACA,aACU;AACV,QAAI,aAAa,QAAQ;AACvB,YAAM,CAAC,MAAM,WAAW,WAAW,SAAS,IAC1C,KAAK,iBAAiB,YAAY;AACpC,YAAM,oBAAoB,OAAO,KAAK,KAAK,QAAQ,SAAS,EAAE,OAAO;AAQrE,aAAO;AAAA,iBACI,KAAK;AAAA,QACZ,SAAS,aAAa,SAAS,KAAK;AAAA,QACpC,QAAQ;AAAA,MACV,CAAC,iBAAiB,IAAI;AAAA,QACpB,kBAAkB;AAAA,UAChB,OAAK,MAAM,IAAI,MAAM,SAAS,CAAC,IAAI,KAAK,WAAW,WAAW,CAAC,CAAC;AAAA,QAClE;AAAA,QACA;AAAA,MACF,CAAC,SAAS,IAAI,WAAW,KAAK;AAAA,QAC5B;AAAA,QACA;AAAA,QACA,aAAa,YAAY;AAAA,QACzB,aAAa,SAAS;AAAA,QACtB,aAAa,SAAS;AAAA,QACtB,aAAa,YAAY;AAAA,MAC3B,CAAC,KACC,aAAa,SAAS,QAClB,UAAU,KAAK;AAAA,QACb,aAAa,SAAS;AAAA,QACtB,aAAa,SAAS;AAAA,MACxB,CAAC,KACD,KACN,IAAI,KAAK;AAAA,QACP,aAAa,SAAS;AAAA,QACtB,aAAa,SAAS;AAAA,MACxB,CAAC,IACC,QAAQ,WAAW,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,SAAS,CACzD,MAAM,IAAI,MAAM,SAAS,aAAa,SAAS,KAAK,EAAE,CAAC;AAAA,aAClD,IAAI,MAAM,aAAa,SAAS,KAAK,CAAC;AAAA,IAC/C;AACA,WAAO;AAAA,eAEH,QAAQ,WAAW,QAAQ,sBAC7B,gBAAgB,IAAI,MAAM,SAAS,aAAa,SAAS,KAAK,EAAE,CAAC,MAC/D,QAAQ,WAAW,QAAQ,kBAC7B,UAAU,KAAK;AAAA,MACb,aAAa;AAAA,MACb;AAAA,MACA,KAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA,aAAa,YAAY;AAAA,QACzB,aAAa,SAAS;AAAA,QACtB,aAAa,SAAS;AAAA,QACtB,aAAa,YAAY;AAAA,MAC3B;AAAA,IACF,CAAC,KAAK,IAAI,MAAM,SAAS,aAAa,SAAS,KAAK,EAAE,CAAC;AAAA,WAClD,IAAI,MAAM,aAAa,SAAS,KAAK,CAAC;AAAA,EAC/C;AAAA,EAEA,sBACE,cACA,SAAsD,CAAC,GACvD;AACA,WAAO,KAAK;AAAA,MACV,aAAa,SAAS;AAAA,MACtB,aAAa;AAAA,MACb,aAAa,SAAS;AAAA,IACxB,CAAC;AACD;AAAA,MACE,aAAa,SAAS,SAAS,UAAU,KAAK;AAAA,MAC9C;AAAA,IACF;AACA,eAAW,mBAAmB,aAAa,SAAS,WAAW,CAAC,GAAG;AACjE,WAAK,sBAAsB,iBAAiB,MAAM;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,iBACE,cAMA;AACA,UAAM,sBAAsB,KAAK,sBAAsB,YAAY;AACnE,UAAM,QAAoB,CAAC;AAE3B,aAAS,MAAM,OAAe;AAC5B,UAAI,UAAU,GAAG;AACf,eAAO,oBAAoB,CAAC,EAAE,CAAC;AAAA,MACjC;AACA,aAAO,SAAS,KAAK;AAAA,IACvB;AAEA,eAAW,CAAC,OAAO,YAAY,KAAK,qBAAqB;AACvD,UAAI,MAAM,WAAW,GAAG;AACtB,cAAM,KAAK,KAAK,UAAU,KAAK,CAAC;AAChC;AAAA,MACF;AACA,YAAM;AAAA,QACJ,YAAY,KAAK,iBAAiB,KAAK,CAAC,OAAO,IAAI;AAAA,UACjD,MAAM,MAAM,MAAM;AAAA,QACpB,CAAC,OAAO,KAAK;AAAA,UACX,oBAAoB,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,UACvC,MAAM,MAAM,SAAS,CAAC;AAAA,UACtB,oBAAoB,MAAM,MAAM,EAAE,CAAC,EAAE;AAAA,UACrC,oBAAoB,MAAM,MAAM,EAAE,CAAC;AAAA,UACnC,MAAM,MAAM,MAAM;AAAA,UAClB,oBAAoB,MAAM,MAAM,EAAE,CAAC,EAAE;AAAA,QACvC,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI,KAAK,OAAO,EAAE;AAAA,MAClB,MAAM,MAAM,SAAS,CAAC;AAAA,MACtB,oBAAoB,oBAAoB,SAAS,CAAC,EAAE,CAAC;AAAA,MACrD,oBAAoB,oBAAoB,SAAS,CAAC,EAAE,CAAC;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAM,WAAkC,OAAyB;AAC/D,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,YAAQ,UAAU,MAAM;AAAA,MACtB,KAAK;AACH,eAAO,OAAO,IAAI;AAAA,UAChB,UAAU,WAAW,IAAI,OAAK,KAAK,MAAM,GAAG,KAAK,CAAC;AAAA,UAClD;AAAA,QACF,CAAC;AAAA,MACH,KAAK;AACH,eAAO,OAAO,IAAI;AAAA,UAChB,UAAU,WAAW,IAAI,OAAK,KAAK,MAAM,GAAG,KAAK,CAAC;AAAA,UAClD;AAAA,QACF,CAAC;AAAA,MACH,KAAK;AACH,eAAO,KAAK,OAAO,WAAW,KAAK;AAAA,MACrC,KAAK;AACH,eAAO,KAAK,OAAO,WAAW,KAAK;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,OAAO,WAA4B,OAAyB;AAC1D,YAAQ,UAAU,IAAI;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,MAAM,KAAK;AAAA,UAChB,UAAU;AAAA,UACV;AAAA,UACA,KAAK,aAAa,OAAO,UAAU,MAAM,UAAU,KAAK;AAAA,UACxD;AAAA,QACF,CAAC,IAAI,IAAI,sBAAsB,UAAU,EAAE,CAAC,IAAI,KAAK;AAAA,UACnD,UAAU;AAAA,UACV;AAAA,UACA,KAAK,aAAa,OAAO,UAAU,OAAO,UAAU,IAAI;AAAA,UACxD;AAAA,QACF,CAAC;AAAA,MACH,KAAK;AAAA,MACL,KAAK;AACH,eAAO,KAAK,IAAI,WAAW,KAAK;AAAA,MAClC,KAAK;AAAA,MACL,KAAK;AACH,eAAO,KAAK,aAAa,WAAW,KAAK;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,aAAa,WAA4B,OAAyB;AAChE,WAAO,MAAM,KAAK,cAAc,UAAU,MAAM,OAAO,KAAK,aAAa,OAAO,UAAU,MAAM,UAAU,KAAK,GAAG,KAAK,CAAC,IACtH,UAAU,OAAO,OAAO,4BAA4B,qBACtD,IAAI,KAAK,cAAc,UAAU,OAAO,OAAO,KAAK,aAAa,OAAO,UAAU,OAAO,UAAU,IAAI,GAAG,KAAK,CAAC;AAAA,EAClH;AAAA,EAEA,IAAI,WAA4B,OAAyB;AACvD,WAAO,MAAM,KAAK,cAAc,UAAU,MAAM,OAAO,KAAK,aAAa,OAAO,UAAU,MAAM,UAAU,KAAK,GAAG,KAAK,CAAC,IACtH,UAAU,OAAO,OAAO,aAAa,WACvC,KAAK,KAAK,cAAc,UAAU,OAAO,OAAO,KAAK,aAAa,OAAO,UAAU,OAAO,UAAU,IAAI,GAAG,IAAI,CAAC;AAAA,EAClH;AAAA,EAEA,cACE,OACA,OACA,WACA,QACU;AACV,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,eAAO,KAAK,kBAAkB,OAAO,MAAM,IAAI;AAAA,MACjD,KAAK;AACH,eAAO,oBAAoB,WAAW,MAAM,OAAO,MAAM;AAAA,MAC3D,KAAK;AACH,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,OACE,WACA,aACU;AACV,YAAQ,UAAU,IAAI;AAAA,MACpB,KAAK;AACH,eAAO,cAAc,KAAK;AAAA,UACxB,UAAU,QAAQ;AAAA,UAClB;AAAA,UACA,KAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA,UAAU,QAAQ,YAAY;AAAA,YAC9B,UAAU,QAAQ,SAAS;AAAA,YAC3B,UAAU,QAAQ,SAAS;AAAA,YAC3B,UAAU,QAAQ,YAAY;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH,KAAK;AACH,eAAO,kBAAkB,KAAK;AAAA,UAC5B,UAAU,QAAQ;AAAA,UAClB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,UAKE,aACA,kBACA,eACA,YACA,iBACA,cACU;AACV,WAAO,IAAI;AAAA,MACT,IAAI,eAAe,YAAY,EAAE;AAAA,QAC/B,CAAC,CAAC,cAAc,WAAW,MACzB,MAAM,IAAI,MAAM,gBAAgB,CAAC,IAAI,KAAK;AAAA,UACxC;AAAA,UACA;AAAA,QACF,CAAC,MAAM,IAAI,MAAM,eAAe,CAAC,IAAI,KAAK;AAAA,UACxC;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,OAAe,QAAgB;AACxC,UAAM,SAAS,KAAK,YAAY,WAAW,OAAO,MAAM;AACxD,QAAI,WAAW,QAAQ;AACrB,aAAO,IAAI,MAAM,MAAM;AAAA,IACzB;AAEA,WAAO,MAAM,IAAI,MAAM,MAAM,CAAC,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,EACxD;AAAA,EAEA,kBAAkB,OAAe,QAAgB;AAC/C,UAAM,SAAS,KAAK,YAAY,WAAW,OAAO,MAAM;AACxD,WAAO,IAAI,MAAM,MAAM;AAAA,EACzB;AAAA,EAEA,UAAU,OAAe;AACvB,UAAM,SAAS,KAAK,YAAY,UAAU,KAAK;AAC/C,QAAI,WAAW,OAAO;AACpB,aAAO,IAAI,MAAM,KAAK;AAAA,IACxB;AAEA,WAAO,MAAM,IAAI,MAAM,MAAM,CAAC,OAAO,IAAI,MAAM,KAAK,CAAC;AAAA,EACvD;AAAA,EAEA,iBAAiB,OAAe;AAC9B,UAAM,SAAS,KAAK,YAAY,UAAU,KAAK;AAC/C,WAAO,IAAI,MAAM,MAAM;AAAA,EACzB;AAAA,EAEA,WAAW,OAAe,QAAgB,MAAiB;AACzD,QAAI,SAAS,UAAU,SAAS,aAAa;AAC3C,aAAO,yBAAyB,IAAI;AAAA,QAClC;AAAA,MACF,CAAC,IAAI,KAAK;AAAA,QACR;AAAA,QACA;AAAA,MACF,CAAC,6CAA6C,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO,MAAM,IAAI,MAAM,KAAK,CAAC,IAAI,KAAK,WAAW,OAAO,MAAM,CAAC;AAAA,EACjE;AAAA,EAEA,QAAQ,OAAe,WAAW,OAAiB;AACjD,WAAO,MACL,WAAW,QAAQ,sBACrB,gBAAgB,IAAI,MAAM,KAAK,CAAC,MAC9B,WAAW,QAAQ,kBACrB;AAAA,EACF;AAAA,EAEA,aACE,OAEA,OACA,QACW;AAEX,UAAM,SACJ,MAAM,SAAS,WACX,MAAM,OACN,OAAO,SAAS,WACd,OAAO,OACP;AACR,QAAI,QAAQ;AACV,aAAO,KAAK,QAAQ,KAAK,EAAE,QAAQ,MAAM,EAAE;AAAA,IAC7C;AAGA,UAAM,eACJ,MAAM,SAAS,YACX,MAAM,QACN,OAAO,SAAS,YACd,OAAO,QACP;AAER,WAAO,cAAc,yBAAyB;AAE9C,QAAI,iBAAiB,MAAM;AACzB,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,OAAO;AACtB,YAAQ,QAAQ;AAAA,MACd,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,cAAM,IAAI,MAAM,uBAAuB,MAAM;AAAA,MAC/C;AACE,oBAAY,MAAM;AAAA,IACtB;AAAA,EACF;AACF;;;ACtfA,eAAsB,aACpB,KACA,QACA,QAC6B;AAC7B,QAAM,gBAAgB,MAAM,IAAI;AAChC,SAAO,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,eAAe,MAAM;AACvE;AAEA,IAAM,YAAN,MAA8C;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,KACA,QACA,UACA,eACA,QACA;AACA,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,SAAS,IAAI,OAAO,KAAK,QAAQ,QAAQ,UAAU,aAAa;AACrE,SAAK,cAAc,KAAK,OAAO;AAC/B,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,UAAsC;AACpC,WAAO;AAAA,MAAY,KAAK;AAAA,MAAM,aAC5B,QAAQ,KAAK,MAAM,KAAK,QAAQ,KAAK,SAAS,OAAO;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,qBAAiD;AAC/C,WAAO;AAAA,MAAY,KAAK;AAAA,MAAM,aAC5B,mBAAmB,KAAK,MAAM,KAAK,QAAQ,KAAK,SAAS,OAAO;AAAA,IAClE;AAAA,EACF;AACF;AAEA,SAAS,IACP,QACA,KACA,YACqB;AACrB,SAAO,QAAQ,yBAAyB;AACxC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,KAAK,OAAO;AAClB,UAAM,IAAI,CAAC,OAAqB;AAC9B,YAAM,MAAM,KAAK,MAAM,GAAG,IAAI;AAC9B,UAAI,IAAI,CAAC,MAAM,WAAW;AACxB,cAAM,OAAO,IAAI,CAAC;AAClB,YAAI,KAAK,OAAO,IAAI;AAClB;AAAA,QACF;AACA,cAAM,MAAa,KAAK,MAAM,UAAU;AACxC,YAAI,IAAI,IAAI;AACV,kBAAQ,IAAI,MAAM,KAAK;AAAA,QACzB,OAAO;AACL,iBAAO,IAAI,KAAK;AAAA,QAClB;AACA,eAAO,oBAAoB,WAAW,CAAC;AAAA,MACzC;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,CAAC;AACpC,WAAO;AAAA,MACL,KAAK,UAAU,CAAC,WAAW,EAAC,GAAG,KAAK,GAAE,CAAC,CAA4B;AAAA,IACrE;AAAA,EACF,CAAC;AACH;AAEA,IAAM,SAAN,MAAwC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,KACA,QACA,QACA,IACA,eACA;AACA,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,KAAK;AACV,SAAK,cAAc,IAAI,YAAY,KAAK,QAAQ,QAAQ,aAAa;AAAA,EACvE;AAAA,EAEA,MAAM,UAAqC;AACzC,UAAM,OAA0B,MAAM;AAAA,MACpC,KAAK,QAAQ;AAAA,MACb,EAAC,IAAI,WAAW,UAAU,KAAK,GAAE;AAAA,MACjC;AAAA,IACF;AACA,WAAO,KAAK,IAAI,SAAO,IAAI,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,EACrD;AAAA,EAEA,MAA+C;AAC7C,WAAO,YAAY,KAAK,MAAM,OAAM,YAAW;AAC7C,YAAM,OAAO,MAAM,SAAS,SAAS,KAAK,EAAE;AAC5C,YAAM,MAAM,oBAAI,IAA+B;AAC/C,uBAAiB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,GAAG;AAC9C,YAAI,IAAI,KAAK,KAAK;AAAA,MACpB;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,KAAK,WAAmC;AACtC,WAAO,YAAY,KAAK,MAAM,OAAM,YAAW;AAC7C,YAAM,SAAS,sBAAsB;AACrC,YAAM,OAAO,MAAM,SAAS,SAAS,KAAK,EAAE;AAC5C,YAAM,OAAc,CAAC;AACrB,uBAAiB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,GAAG;AAClD,YAAI,CAAC,IAAI,WAAW,MAAM,GAAG;AAC3B;AAAA,QACF;AACA,aAAK,KAAK,KAAY;AAAA,MACxB;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,IAAM,cAAN,MAAkD;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,KAAU,QAAsB,QAAgB,IAAY;AACtE,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,UAAsC;AACpC,WAAO;AAAA,MAAY,KAAK;AAAA,MAAM,aAC5B;AAAA,QACE,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,KAAK;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,qBAAiD;AAC/C,WAAO;AAAA,MAAY,KAAK;AAAA,MAAM,aAC5B;AAAA,QACE,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL;AAAA,QACA,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,KAAK;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,UAAqC;AACzC,UAAM,OAA0B,MAAM;AAAA,MACpC,KAAK,QAAQ;AAAA,MACb,EAAC,IAAI,UAAS;AAAA,MACd;AAAA,IACF;AACA,WAAO,KAAK,IAAI,SAAO,IAAI,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,EACrD;AACF;AAEA,eAAe,YACb,KACA,GACY;AACZ,QAAM,IAAI,QAAQ;AAClB,QAAM,IAAI,QAAQ;AAClB,SAAO,SAAS,IAAI,QAAQ,CAAC;AAC/B;AAEA,eAAe,SAAS,SAAe,UAAsC;AAC3E,QAAM,SAAS,MAAM,UAAU,UAAU,OAAO;AAChD,SAAO,QAAQ,qBAAqB,QAAQ,EAAE;AAC9C,QAAM,EAAC,cAAa,IAAI;AACxB,QAAM,cAAc,MAAM,eAAe,eAAe,OAAO;AAC/D,SAAO,aAAa,2BAA2B,aAAa,EAAE;AAC9D,QAAM,SAAS,MAAM;AAAA,IACnB,YAAY;AAAA,IACZ;AAAA,IACc;AAAA,EAChB;AACA,SAAO,OAAO;AAChB;AAMA,eAAe,QACb,KACA,QACA,QACA,SACA,YAAqD,MAAM,MAC/B;AAC5B,QAAMC,WAAU,MAAM,WAAW,OAAO;AACxC,SAAO,CAAC,GAAGA,SAAQ,QAAQ,CAAC,EACzB,OAAO,SAAS,EAChB;AAAA,IACC,CAAC,CAAC,UAAU,EAAC,cAAa,CAAC,MACzB,IAAI,OAAO,KAAK,QAAQ,QAAQ,UAAU,aAAa;AAAA,EAC3D;AACJ;AAEA,eAAe,mBACb,KACA,QACA,QACA,SACA,YAAqD,MAAM,MAC/B;AAC5B,QAAM,aAAa,MAAM,QAAQ,KAAK,QAAQ,QAAQ,SAAS,SAAS;AACxE,QAAMC,sBAAwC,CAAC;AAC/C,QAAM,QAAQ;AAAA,IACZ,WAAW,IAAI,OAAM,WAAU;AAC7B,YAAM,UAAU,MAAM,OAAO,QAAQ;AACrC,UAAI,QAAQ,SAAS,GAAG;AACtB,QAAAA,oBAAmB,KAAK,MAAM;AAAA,MAChC;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAOA;AACT;AAEA,IAAM,QAAN,MAAsC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,KAAsB,QAAgB;AAIhD,SAAK,WAAW,IAAI;AACpB,SAAK,KAAK,IAAI;AACd,SAAK,gBACH,IAAI,kBAAkB,OAAO,OAAO,IAAI,KAAK,IAAI,aAAa;AAChE,SAAK,MAAM,aAAa,IAAI,GAAG;AAC/B,SAAK,MAAM,IAAI;AACf,SAAK,MAAM,IAAI;AACf,SAAK,WAAW,IAAI;AACpB,SAAK,UAAU,IAAI;AAEnB,UAAM,SAAiB;AAAA,MACrB,UAAU;AAAA,MACV,eAAe,CAAC;AAAA,IAClB;AACA,UAAM,WAAW,SAAS,QAAQ,KAAK,KAAK,OAAO,QAAQ,MAAM,CAAC;AAClE,SAAK,MAAM,SAAS;AACpB,SAAK,MAAM,KAAK,IAAI,QAAQ,SAAS,KAAK,GAAG;AAAA,EAC/C;AACF;",
6
+ "names": ["sql", "jsonObjectSchema", "clients", "clientsWithQueries"]
7
+ }
package/out/react.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_TTL,
3
3
  hasOwn
4
- } from "./chunk-2B2QE5AT.js";
4
+ } from "./chunk-MB3DEFRC.js";
5
5
  import "./chunk-424PT5DM.js";
6
6
 
7
7
  // ../zero-react/src/use-query.tsx
@@ -76,9 +76,8 @@ function useQuery(query, options) {
76
76
  } else if (options) {
77
77
  ({ enabled = true, ttl = DEFAULT_TTL } = options);
78
78
  }
79
- const advancedQuery = query;
80
79
  const z = useZero();
81
- const view = viewStore.getView(z.clientID, advancedQuery, enabled, ttl);
80
+ const view = viewStore.getView(z.clientID, query, enabled, ttl);
82
81
  return useSyncExternalStore(
83
82
  view.subscribeReactInternals,
84
83
  view.getSnapshot,
package/out/react.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../zero-react/src/use-query.tsx", "../../shared/src/deep-clone.ts", "../../zero-react/src/use-zero.tsx"],
4
- "sourcesContent": ["import {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {AdvancedQuery} from '../../zql/src/query/query-internal.ts';\nimport {type HumanReadable, type Query} from '../../zql/src/query/query.ts';\nimport {DEFAULT_TTL, type TTL} from '../../zql/src/query/ttl.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './use-zero.tsx';\n\nexport type QueryResultDetails = Readonly<{\n type: ResultType;\n}>;\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 10 seconds.\n */\n ttl?: TTL | undefined;\n};\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL} = options);\n }\n const advancedQuery = query as AdvancedQuery<TSchema, TTable, TReturn>;\n\n const z = useZero();\n const view = viewStore.getView(z.clientID, advancedQuery, enabled, ttl);\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: string,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n return (resultType === 'complete'\n ? emptySnapshotSingularComplete\n : emptySnapshotSingularUnknown) as unknown as QueryResult<TReturn>;\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n return (\n resultType === 'complete'\n ? emptySnapshotPluralComplete\n : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n }\n\n return [\n data,\n resultType === 'complete' ? resultTypeComplete : resultTypeUnknown,\n ];\n}\n\ndeclare const TESTING: boolean;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n clientID: string,\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n } {\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(query.format.singular),\n subscribeReactInternals: disabledSubscriber,\n };\n }\n\n const hash = query.hash() + clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(\n query,\n ttl,\n view => {\n const lastView = this.#views.get(hash);\n // I don't think this can happen\n // but lets guard against it so we don't\n // leak resources.\n if (lastView && lastView !== view) {\n throw new Error('View already exists');\n }\n this.#views.set(hash, view);\n },\n () => {\n this.#views.delete(hash);\n },\n ) as ViewWrapper<TSchema, TTable, TReturn>;\n this.#views.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #onMaterialized;\n readonly #query: AdvancedQuery<TSchema, TTable, TReturn>;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n #ttl: TTL;\n\n constructor(\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n ttl: TTL,\n onMaterialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n onDematerialized: () => void,\n ) {\n this.#query = query;\n this.#ttl = ttl;\n this.#onMaterialized = onMaterialized;\n this.#onDematerialized = onDematerialized;\n this.#snapshot = getDefaultSnapshot(query.format.singular);\n this.#reactInternals = new Set();\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(this.#query.format.singular, data, resultType);\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#query.materialize(this.#ttl);\n this.#view.addListener(this.#onData);\n\n this.#onMaterialized(this);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n this.#view?.destroy();\n this.#view = undefined;\n this.#onDematerialized();\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n this.#ttl = ttl;\n this.#query.updateTTL(ttl);\n }\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {createContext, useContext} from 'react';\nimport type {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>(): Zero<S, MD> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>({children, zero}: {children: React.ReactNode; zero: Zero<S, MD>}) {\n return <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport {type HumanReadable, type Query} from '../../zql/src/query/query.ts';\nimport {DEFAULT_TTL, type TTL} from '../../zql/src/query/ttl.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './use-zero.tsx';\n\nexport type QueryResultDetails = Readonly<{\n type: ResultType;\n}>;\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 10 seconds.\n */\n ttl?: TTL | undefined;\n};\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL} = options);\n }\n\n const z = useZero();\n const view = viewStore.getView(z.clientID, query, enabled, ttl);\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: string,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n return (resultType === 'complete'\n ? emptySnapshotSingularComplete\n : emptySnapshotSingularUnknown) as unknown as QueryResult<TReturn>;\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n return (\n resultType === 'complete'\n ? emptySnapshotPluralComplete\n : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n }\n\n return [\n data,\n resultType === 'complete' ? resultTypeComplete : resultTypeUnknown,\n ];\n}\n\ndeclare const TESTING: boolean;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n clientID: string,\n query: Query<TSchema, TTable, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n } {\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(query.format.singular),\n subscribeReactInternals: disabledSubscriber,\n };\n }\n\n const hash = query.hash() + clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(\n query,\n ttl,\n view => {\n const lastView = this.#views.get(hash);\n // I don't think this can happen\n // but lets guard against it so we don't\n // leak resources.\n if (lastView && lastView !== view) {\n throw new Error('View already exists');\n }\n this.#views.set(hash, view);\n },\n () => {\n this.#views.delete(hash);\n },\n ) as ViewWrapper<TSchema, TTable, TReturn>;\n this.#views.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #onMaterialized;\n readonly #query: Query<TSchema, TTable, TReturn>;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n #ttl: TTL;\n\n constructor(\n query: Query<TSchema, TTable, TReturn>,\n ttl: TTL,\n onMaterialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n onDematerialized: () => void,\n ) {\n this.#query = query;\n this.#ttl = ttl;\n this.#onMaterialized = onMaterialized;\n this.#onDematerialized = onDematerialized;\n this.#snapshot = getDefaultSnapshot(query.format.singular);\n this.#reactInternals = new Set();\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(this.#query.format.singular, data, resultType);\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#query.materialize(this.#ttl);\n this.#view.addListener(this.#onData);\n\n this.#onMaterialized(this);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n this.#view?.destroy();\n this.#view = undefined;\n this.#onDematerialized();\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n this.#ttl = ttl;\n this.#query.updateTTL(ttl);\n }\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {createContext, useContext} from 'react';\nimport type {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>(): Zero<S, MD> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>({children, zero}: {children: React.ReactNode; zero: Zero<S, MD>}) {\n return <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,3 @@
1
+ export declare function emptyFunction(): void;
2
+ export declare const emptyObject: Readonly<{}>;
3
+ //# sourceMappingURL=sentinels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentinels.d.ts","sourceRoot":"","sources":["../../../../shared/src/sentinels.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,SAAK;AAClC,eAAO,MAAM,WAAW,cAAoB,CAAC"}
package/out/solid.js CHANGED
@@ -1,11 +1,10 @@
1
1
  import {
2
2
  Zero
3
- } from "./chunk-5WXONOGR.js";
4
- import "./chunk-ULOTOBTC.js";
5
- import "./chunk-DSUPSGE4.js";
3
+ } from "./chunk-3S3SDA44.js";
4
+ import "./chunk-NBZURO2P.js";
6
5
  import {
7
6
  DEFAULT_TTL
8
- } from "./chunk-2B2QE5AT.js";
7
+ } from "./chunk-MB3DEFRC.js";
9
8
  import {
10
9
  applyChange,
11
10
  must
package/out/solid.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../zero-solid/src/create-zero.ts", "../../zero-solid/src/use-query.ts", "../../shared/src/ref-count.ts", "../../zero-solid/src/solid-view.ts"],
4
- "sourcesContent": ["import {batch} from 'solid-js';\nimport type {ZeroAdvancedOptions} from '../../zero/src/advanced.ts';\nimport {Zero, type Schema, type ZeroOptions} from '../../zero/src/zero.ts';\n\nexport function createZero<S extends Schema>(options: ZeroOptions<S>): Zero<S> {\n const opts: ZeroAdvancedOptions<S> = {\n ...options,\n batchViewUpdates: batch,\n };\n return new Zero(opts);\n}\n", "import {createMemo, onCleanup, type Accessor} from 'solid-js';\nimport {RefCount} from '../../shared/src/ref-count.ts';\nimport type {\n AdvancedQuery,\n HumanReadable,\n Query,\n} from '../../zero/src/advanced.ts';\nimport {DEFAULT_TTL, type Schema, type TTL} from '../../zero/src/zero.ts';\nimport {\n solidViewFactory,\n type QueryResultDetails,\n type SolidView,\n} from './solid-view.ts';\n\nexport type QueryResult<TReturn> = readonly [\n Accessor<HumanReadable<TReturn>>,\n Accessor<QueryResultDetails>,\n];\n\nexport type UseQueryOptions = {\n ttl?: TTL | undefined;\n};\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n querySignal: () => Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | Accessor<UseQueryOptions>,\n): QueryResult<TReturn> {\n // Wrap in in createMemo to ensure a new view is created if the querySignal changes.\n const view = createMemo(() => {\n const query = querySignal() as AdvancedQuery<TSchema, TTable, TReturn>;\n const ttl = normalize(options)?.ttl ?? DEFAULT_TTL;\n const view = getView(query, ttl);\n\n // Use queueMicrotask to allow cleanup/create in the current microtask to\n // reuse the view.\n onCleanup(() => queueMicrotask(() => releaseView(query, view)));\n return view;\n });\n\n return [() => view().data, () => view().resultDetails];\n}\n\ntype UnknownSolidView = SolidView<HumanReadable<unknown>>;\n\nconst views = new WeakMap<WeakKey, UnknownSolidView>();\n\nconst viewRefCount = new RefCount<UnknownSolidView>();\n\nfunction getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n ttl: TTL,\n): SolidView<HumanReadable<TReturn>> {\n // TODO(arv): Use the hash of the query instead of the query object itself... but\n // we need the clientID to do that in a reasonable way.\n let view = views.get(query);\n if (!view) {\n view = query.materialize(solidViewFactory, ttl);\n views.set(query, view);\n } else {\n query.updateTTL(ttl);\n }\n viewRefCount.inc(view);\n return view as SolidView<HumanReadable<TReturn>>;\n}\n\nfunction releaseView(query: WeakKey, view: UnknownSolidView) {\n if (viewRefCount.dec(view)) {\n views.delete(query);\n view.destroy();\n }\n}\n\nfunction normalize<T>(\n options?: T | Accessor<T | undefined> | undefined,\n): T | undefined {\n return typeof options === 'function' ? (options as Accessor<T>)() : options;\n}\n", "import {must} from './must.ts';\n\n/**\n * This is a basic ref count implementation that uses a WeakMap to store the\n * reference count for each value.\n */\nexport class RefCount<T extends WeakKey = WeakKey> {\n readonly #map = new WeakMap<T, number>();\n\n /**\n * Returns true if the value was added.\n */\n inc(value: T): boolean {\n const rc = this.#map.get(value) ?? 0;\n this.#map.set(value, rc + 1);\n return rc === 0;\n }\n\n /**\n * Returns true if the value was removed.\n */\n dec(value: T): boolean {\n const rc = must(this.#map.get(value));\n if (rc === 1) {\n return this.#map.delete(value);\n }\n this.#map.set(value, rc - 1);\n return false;\n }\n}\n", "import {\n createStore,\n produce,\n type SetStoreFunction,\n type Store,\n} from 'solid-js/store';\nimport {\n applyChange,\n type Change,\n type Entry,\n type Format,\n type HumanReadable,\n type Input,\n type Node,\n type Output,\n type Query,\n type ResultType,\n type Stream,\n type ViewChange,\n type ViewFactory,\n} from '../../zero-advanced/src/mod.js';\nimport type {Schema} from '../../zero-schema/src/mod.js';\n\nexport type QueryResultDetails = {\n readonly type: ResultType;\n};\n\ntype State = [Entry, QueryResultDetails];\n\nconst complete = {type: 'complete'} as const;\nconst unknown = {type: 'unknown'} as const;\n\nexport class SolidView<V> implements Output {\n readonly #input: Input;\n readonly #format: Format;\n readonly #onDestroy: () => void;\n\n #state: Store<State>;\n #setState: SetStoreFunction<State>;\n\n // Optimization: if the store is currently empty we build up\n // the view on a plain old JS object stored at #builderRoot, and return\n // that for the new state on transaction commit. This avoids building up\n // large views from scratch via solid produce. The proxy object used by\n // solid produce is slow and in this case we don't care about solid tracking\n // the fine grained changes (everything has changed, it's all new). For a\n // test case with a view with 3000 rows, each row having 2 children, this\n // optimization reduced #applyChanges time from 743ms to 133ms.\n #builderRoot: Entry | undefined;\n #pendingChanges: ViewChange[] = [];\n\n constructor(\n input: Input,\n onTransactionCommit: (cb: () => void) => void,\n format: Format,\n onDestroy: () => void,\n queryComplete: true | Promise<true>,\n ) {\n this.#input = input;\n onTransactionCommit(this.#onTransactionCommit);\n this.#format = format;\n this.#onDestroy = onDestroy;\n input.setOutput(this);\n\n const initialRoot = this.#createEmptyRoot();\n this.#applyChangesToRoot(\n input.fetch({}),\n node => ({type: 'add', node}),\n initialRoot,\n );\n [this.#state, this.#setState] = createStore<State>([\n initialRoot,\n queryComplete === true ? complete : unknown,\n ]);\n if (isEmptyRoot(initialRoot)) {\n this.#builderRoot = this.#createEmptyRoot();\n }\n\n if (queryComplete !== true) {\n void queryComplete.then(() => {\n this.#setState(oldState => [oldState[0], complete]);\n });\n }\n }\n\n get data(): V {\n return this.#state[0][''] as V;\n }\n\n get resultDetails(): QueryResultDetails {\n return this.#state[1];\n }\n\n destroy(): void {\n this.#onDestroy();\n }\n\n #onTransactionCommit = () => {\n const builderRoot = this.#builderRoot;\n if (builderRoot) {\n if (!isEmptyRoot(builderRoot)) {\n this.#setState(oldState => [builderRoot, oldState[1]]);\n this.#builderRoot = undefined;\n }\n } else {\n try {\n this.#applyChanges(this.#pendingChanges, c => c);\n } finally {\n this.#pendingChanges = [];\n }\n }\n };\n\n push(change: Change): void {\n // Delay updating the solid store state until the transaction commit\n // (because each update of the solid store is quite expensive). If\n // this.#builderRoot is defined apply the changes to it (we are building\n // from an empty root), otherwise queue the changes to be applied\n // using produce at the end of the transaction but read the relationships\n // now as they are only valid to read when the push is received.\n if (this.#builderRoot) {\n this.#applyChangeToRoot(change, this.#builderRoot);\n } else {\n this.#pendingChanges.push(materializeRelationships(change));\n }\n }\n\n #applyChanges<T>(changes: Iterable<T>, mapper: (v: T) => ViewChange): void {\n this.#setState(\n produce((draftState: State) => {\n this.#applyChangesToRoot<T>(changes, mapper, draftState[0]);\n if (isEmptyRoot(draftState[0])) {\n this.#builderRoot = this.#createEmptyRoot();\n }\n }),\n );\n }\n\n #applyChangesToRoot<T>(\n changes: Iterable<T>,\n mapper: (v: T) => ViewChange,\n root: Entry,\n ) {\n for (const change of changes) {\n this.#applyChangeToRoot(mapper(change), root);\n }\n }\n\n #applyChangeToRoot(change: ViewChange, root: Entry) {\n applyChange(root, change, this.#input.getSchema(), '', this.#format);\n }\n\n #createEmptyRoot(): Entry {\n return {\n '': this.#format.singular ? undefined : [],\n };\n }\n}\n\nfunction materializeRelationships(change: Change): ViewChange {\n switch (change.type) {\n case 'add':\n return {type: 'add', node: materializeNodeRelationships(change.node)};\n case 'remove':\n return {type: 'remove', node: materializeNodeRelationships(change.node)};\n case 'child':\n return {\n type: 'child',\n node: {row: change.node.row},\n child: {\n relationshipName: change.child.relationshipName,\n change: materializeRelationships(change.child.change),\n },\n };\n case 'edit':\n return {\n type: 'edit',\n node: {row: change.node.row},\n oldNode: {row: change.oldNode.row},\n };\n }\n}\n\nfunction materializeNodeRelationships(node: Node): Node {\n const relationships: Record<string, () => Stream<Node>> = {};\n for (const relationship in node.relationships) {\n const materialized: Node[] = [];\n for (const n of node.relationships[relationship]()) {\n materialized.push(materializeNodeRelationships(n));\n }\n relationships[relationship] = () => materialized;\n }\n return {\n row: node.row,\n relationships,\n };\n}\n\nfunction isEmptyRoot(entry: Entry) {\n const data = entry[''];\n return data === undefined || (Array.isArray(data) && data.length === 0);\n}\n\nexport function solidViewFactory<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n _query: Query<TSchema, TTable, TReturn>,\n input: Input,\n format: Format,\n onDestroy: () => void,\n onTransactionCommit: (cb: () => void) => void,\n queryComplete: true | Promise<true>,\n) {\n return new SolidView<HumanReadable<TReturn>>(\n input,\n onTransactionCommit,\n format,\n onDestroy,\n queryComplete,\n );\n}\n\nsolidViewFactory satisfies ViewFactory<Schema, string, unknown, unknown>;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {batch} from 'solid-js';\nimport {Zero, type Schema, type ZeroOptions} from '../../zero/src/zero.ts';\n\nexport function createZero<S extends Schema>(options: ZeroOptions<S>): Zero<S> {\n const opts = {\n ...options,\n batchViewUpdates: batch,\n };\n return new Zero(opts);\n}\n", "import {createMemo, onCleanup, type Accessor} from 'solid-js';\nimport {RefCount} from '../../shared/src/ref-count.ts';\nimport {\n DEFAULT_TTL,\n type HumanReadable,\n type Query,\n type Schema,\n type TTL,\n} from '../../zero/src/zero.ts';\nimport {\n solidViewFactory,\n type QueryResultDetails,\n type SolidView,\n} from './solid-view.ts';\n\nexport type QueryResult<TReturn> = readonly [\n Accessor<HumanReadable<TReturn>>,\n Accessor<QueryResultDetails>,\n];\n\nexport type UseQueryOptions = {\n ttl?: TTL | undefined;\n};\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n querySignal: () => Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | Accessor<UseQueryOptions>,\n): QueryResult<TReturn> {\n // Wrap in in createMemo to ensure a new view is created if the querySignal changes.\n const view = createMemo(() => {\n const query = querySignal();\n const ttl = normalize(options)?.ttl ?? DEFAULT_TTL;\n const view = getView(query, ttl);\n\n // Use queueMicrotask to allow cleanup/create in the current microtask to\n // reuse the view.\n onCleanup(() => queueMicrotask(() => releaseView(query, view)));\n return view;\n });\n\n return [() => view().data, () => view().resultDetails];\n}\n\ntype UnknownSolidView = SolidView<HumanReadable<unknown>>;\n\nconst views = new WeakMap<WeakKey, UnknownSolidView>();\n\nconst viewRefCount = new RefCount<UnknownSolidView>();\n\nfunction getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n ttl: TTL,\n): SolidView<HumanReadable<TReturn>> {\n // TODO(arv): Use the hash of the query instead of the query object itself... but\n // we need the clientID to do that in a reasonable way.\n let view = views.get(query);\n if (!view) {\n view = query.materialize(solidViewFactory, ttl);\n views.set(query, view);\n } else {\n query.updateTTL(ttl);\n }\n viewRefCount.inc(view);\n return view as SolidView<HumanReadable<TReturn>>;\n}\n\nfunction releaseView(query: WeakKey, view: UnknownSolidView) {\n if (viewRefCount.dec(view)) {\n views.delete(query);\n view.destroy();\n }\n}\n\nfunction normalize<T>(\n options?: T | Accessor<T | undefined> | undefined,\n): T | undefined {\n return typeof options === 'function' ? (options as Accessor<T>)() : options;\n}\n", "import {must} from './must.ts';\n\n/**\n * This is a basic ref count implementation that uses a WeakMap to store the\n * reference count for each value.\n */\nexport class RefCount<T extends WeakKey = WeakKey> {\n readonly #map = new WeakMap<T, number>();\n\n /**\n * Returns true if the value was added.\n */\n inc(value: T): boolean {\n const rc = this.#map.get(value) ?? 0;\n this.#map.set(value, rc + 1);\n return rc === 0;\n }\n\n /**\n * Returns true if the value was removed.\n */\n dec(value: T): boolean {\n const rc = must(this.#map.get(value));\n if (rc === 1) {\n return this.#map.delete(value);\n }\n this.#map.set(value, rc - 1);\n return false;\n }\n}\n", "import {\n createStore,\n produce,\n type SetStoreFunction,\n type Store,\n} from 'solid-js/store';\nimport {\n applyChange,\n type Change,\n type Entry,\n type Format,\n type HumanReadable,\n type Input,\n type Node,\n type Output,\n type Query,\n type ResultType,\n type Schema,\n type Stream,\n type ViewChange,\n type ViewFactory,\n} from '../../zero-client/src/mod.js';\n\nexport type QueryResultDetails = {\n readonly type: ResultType;\n};\n\ntype State = [Entry, QueryResultDetails];\n\nconst complete = {type: 'complete'} as const;\nconst unknown = {type: 'unknown'} as const;\n\nexport class SolidView<V> implements Output {\n readonly #input: Input;\n readonly #format: Format;\n readonly #onDestroy: () => void;\n\n #state: Store<State>;\n #setState: SetStoreFunction<State>;\n\n // Optimization: if the store is currently empty we build up\n // the view on a plain old JS object stored at #builderRoot, and return\n // that for the new state on transaction commit. This avoids building up\n // large views from scratch via solid produce. The proxy object used by\n // solid produce is slow and in this case we don't care about solid tracking\n // the fine grained changes (everything has changed, it's all new). For a\n // test case with a view with 3000 rows, each row having 2 children, this\n // optimization reduced #applyChanges time from 743ms to 133ms.\n #builderRoot: Entry | undefined;\n #pendingChanges: ViewChange[] = [];\n\n constructor(\n input: Input,\n onTransactionCommit: (cb: () => void) => void,\n format: Format,\n onDestroy: () => void,\n queryComplete: true | Promise<true>,\n ) {\n this.#input = input;\n onTransactionCommit(this.#onTransactionCommit);\n this.#format = format;\n this.#onDestroy = onDestroy;\n input.setOutput(this);\n\n const initialRoot = this.#createEmptyRoot();\n this.#applyChangesToRoot(\n input.fetch({}),\n node => ({type: 'add', node}),\n initialRoot,\n );\n [this.#state, this.#setState] = createStore<State>([\n initialRoot,\n queryComplete === true ? complete : unknown,\n ]);\n if (isEmptyRoot(initialRoot)) {\n this.#builderRoot = this.#createEmptyRoot();\n }\n\n if (queryComplete !== true) {\n void queryComplete.then(() => {\n this.#setState(oldState => [oldState[0], complete]);\n });\n }\n }\n\n get data(): V {\n return this.#state[0][''] as V;\n }\n\n get resultDetails(): QueryResultDetails {\n return this.#state[1];\n }\n\n destroy(): void {\n this.#onDestroy();\n }\n\n #onTransactionCommit = () => {\n const builderRoot = this.#builderRoot;\n if (builderRoot) {\n if (!isEmptyRoot(builderRoot)) {\n this.#setState(oldState => [builderRoot, oldState[1]]);\n this.#builderRoot = undefined;\n }\n } else {\n try {\n this.#applyChanges(this.#pendingChanges, c => c);\n } finally {\n this.#pendingChanges = [];\n }\n }\n };\n\n push(change: Change): void {\n // Delay updating the solid store state until the transaction commit\n // (because each update of the solid store is quite expensive). If\n // this.#builderRoot is defined apply the changes to it (we are building\n // from an empty root), otherwise queue the changes to be applied\n // using produce at the end of the transaction but read the relationships\n // now as they are only valid to read when the push is received.\n if (this.#builderRoot) {\n this.#applyChangeToRoot(change, this.#builderRoot);\n } else {\n this.#pendingChanges.push(materializeRelationships(change));\n }\n }\n\n #applyChanges<T>(changes: Iterable<T>, mapper: (v: T) => ViewChange): void {\n this.#setState(\n produce((draftState: State) => {\n this.#applyChangesToRoot<T>(changes, mapper, draftState[0]);\n if (isEmptyRoot(draftState[0])) {\n this.#builderRoot = this.#createEmptyRoot();\n }\n }),\n );\n }\n\n #applyChangesToRoot<T>(\n changes: Iterable<T>,\n mapper: (v: T) => ViewChange,\n root: Entry,\n ) {\n for (const change of changes) {\n this.#applyChangeToRoot(mapper(change), root);\n }\n }\n\n #applyChangeToRoot(change: ViewChange, root: Entry) {\n applyChange(root, change, this.#input.getSchema(), '', this.#format);\n }\n\n #createEmptyRoot(): Entry {\n return {\n '': this.#format.singular ? undefined : [],\n };\n }\n}\n\nfunction materializeRelationships(change: Change): ViewChange {\n switch (change.type) {\n case 'add':\n return {type: 'add', node: materializeNodeRelationships(change.node)};\n case 'remove':\n return {type: 'remove', node: materializeNodeRelationships(change.node)};\n case 'child':\n return {\n type: 'child',\n node: {row: change.node.row},\n child: {\n relationshipName: change.child.relationshipName,\n change: materializeRelationships(change.child.change),\n },\n };\n case 'edit':\n return {\n type: 'edit',\n node: {row: change.node.row},\n oldNode: {row: change.oldNode.row},\n };\n }\n}\n\nfunction materializeNodeRelationships(node: Node): Node {\n const relationships: Record<string, () => Stream<Node>> = {};\n for (const relationship in node.relationships) {\n const materialized: Node[] = [];\n for (const n of node.relationships[relationship]()) {\n materialized.push(materializeNodeRelationships(n));\n }\n relationships[relationship] = () => materialized;\n }\n return {\n row: node.row,\n relationships,\n };\n}\n\nfunction isEmptyRoot(entry: Entry) {\n const data = entry[''];\n return data === undefined || (Array.isArray(data) && data.length === 0);\n}\n\nexport function solidViewFactory<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n _query: Query<TSchema, TTable, TReturn>,\n input: Input,\n format: Format,\n onDestroy: () => void,\n onTransactionCommit: (cb: () => void) => void,\n queryComplete: true | Promise<true>,\n) {\n return new SolidView<HumanReadable<TReturn>>(\n input,\n onTransactionCommit,\n format,\n onDestroy,\n queryComplete,\n );\n}\n\nsolidViewFactory satisfies ViewFactory<Schema, string, unknown, unknown>;\n"],
5
+ "mappings": "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",
6
6
  "names": ["view"]
7
7
  }
@@ -1,9 +1,11 @@
1
+ import type { SQLQuery } from '@databases/sql';
2
+ import { type JSONValue } from '../../shared/src/json.ts';
1
3
  import type { CorrelatedSubqueryCondition, Correlation, Ordering, ValuePosition } from '../../zero-protocol/src/ast.ts';
2
4
  import { type AST, type Condition, type CorrelatedSubquery, type SimpleCondition } from '../../zero-protocol/src/ast.ts';
3
- import type { TableSchema } from '../../zero-schema/src/table-schema.ts';
5
+ import type { TableSchema, ValueType } from '../../zero-schema/src/table-schema.ts';
4
6
  import type { Format } from '../../zql/src/ivm/view.ts';
5
- import type { SQLQuery } from '@databases/sql';
6
7
  type Tables = Record<string, TableSchema>;
8
+ export declare function extractZqlResult(pgResult: any): JSONValue;
7
9
  /**
8
10
  * Compiles to the Postgres dialect of SQL
9
11
  * - IS, IS NOT can only compare against `NULL`, `TRUE`, `FALSE` so use
@@ -32,7 +34,7 @@ export declare class Compiler {
32
34
  simple(condition: SimpleCondition, table: string): SQLQuery;
33
35
  distinctFrom(condition: SimpleCondition, table: string): SQLQuery;
34
36
  any(condition: SimpleCondition, table: string): SQLQuery;
35
- valuePosition(value: ValuePosition, table: string): SQLQuery;
37
+ valuePosition(value: ValuePosition, table: string, valueType: ValueType, plural: boolean): SQLQuery;
36
38
  exists(condition: CorrelatedSubqueryCondition, parentTable: string): SQLQuery;
37
39
  correlate(parentTable: string, parentTableAlias: string, parentColumns: readonly string[], childTable: string, childTableAlias: string, childColumns: readonly string[]): SQLQuery;
38
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,2BAA2B,EAC3B,WAAW,EACX,QAAQ,EACR,aAAa,EACd,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AAEtD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAE7C,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE1C;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,YAG5E;AAED,qBAAa,QAAQ;;gBAIP,MAAM,EAAE,MAAM;IAK1B,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS;IAI7C,MAAM,CACJ,GAAG,EAAE,GAAG,EAER,MAAM,EAAE,MAAM,GAAG,SAAS,EAE1B,WAAW,EAAE,QAAQ,GAAG,SAAS;IAoBnC,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IAgB/D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ;IAO1C,OAAO,CACL,aAAa,EAAE,SAAS,kBAAkB,EAAE,EAC5C,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,MAAM,GAClB,QAAQ,EAAE;IAUb,oBAAoB,CAClB,YAAY,EAAE,kBAAkB,EAChC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,MAAM;IAiErB,qBAAqB,CACnB,YAAY,EAAE,kBAAkB,EAChC,MAAM,GAAE,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC,EAAO;IAiB1D,gBAAgB,CACd,YAAY,EAAE,kBAAkB,GAC/B;QACD,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,MAAM,GAAG,SAAS;QAC7B,SAAS,EAAE,MAAM;KAClB;IAsCD,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IAuBhE,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IA4B3D,YAAY,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IAMjE,GAAG,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IAMxD,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ;IAa5D,MAAM,CACJ,SAAS,EAAE,2BAA2B,EACtC,WAAW,EAAE,MAAM,GAClB,QAAQ;IAwBX,SAAS,CAKP,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,SAAS,MAAM,EAAE;CA4ClC"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"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"}