ai-database 2.1.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/README.md +880 -669
  3. package/dist/actions.d.ts +2 -2
  4. package/dist/actions.d.ts.map +1 -1
  5. package/dist/actions.js +1 -1
  6. package/dist/actions.js.map +1 -1
  7. package/dist/ai-promise-db.d.ts +49 -23
  8. package/dist/ai-promise-db.d.ts.map +1 -1
  9. package/dist/ai-promise-db.js +91 -63
  10. package/dist/ai-promise-db.js.map +1 -1
  11. package/dist/authorization.d.ts.map +1 -1
  12. package/dist/authorization.js +38 -30
  13. package/dist/authorization.js.map +1 -1
  14. package/dist/cascade-orchestrator.d.ts +404 -0
  15. package/dist/cascade-orchestrator.d.ts.map +1 -0
  16. package/dist/cascade-orchestrator.js +828 -0
  17. package/dist/cascade-orchestrator.js.map +1 -0
  18. package/dist/cascade-write-strategy.d.ts +584 -0
  19. package/dist/cascade-write-strategy.d.ts.map +1 -0
  20. package/dist/cascade-write-strategy.js +590 -0
  21. package/dist/cascade-write-strategy.js.map +1 -0
  22. package/dist/ch-adapter.d.ts +358 -0
  23. package/dist/ch-adapter.d.ts.map +1 -0
  24. package/dist/ch-adapter.js +929 -0
  25. package/dist/ch-adapter.js.map +1 -0
  26. package/dist/client/index.d.ts +42 -0
  27. package/dist/client/index.d.ts.map +1 -0
  28. package/dist/client/index.js +43 -0
  29. package/dist/client/index.js.map +1 -0
  30. package/dist/client.d.ts +266 -0
  31. package/dist/client.d.ts.map +1 -0
  32. package/dist/client.js +81 -0
  33. package/dist/client.js.map +1 -0
  34. package/dist/constants.d.ts +64 -1
  35. package/dist/constants.d.ts.map +1 -1
  36. package/dist/constants.js +52 -2
  37. package/dist/constants.js.map +1 -1
  38. package/dist/dataloader.d.ts +99 -0
  39. package/dist/dataloader.d.ts.map +1 -0
  40. package/dist/dataloader.js +225 -0
  41. package/dist/dataloader.js.map +1 -0
  42. package/dist/db-provider-port.d.ts +501 -0
  43. package/dist/db-provider-port.d.ts.map +1 -0
  44. package/dist/db-provider-port.js +113 -0
  45. package/dist/db-provider-port.js.map +1 -0
  46. package/dist/digital-objects-provider.d.ts +49 -0
  47. package/dist/digital-objects-provider.d.ts.map +1 -0
  48. package/dist/digital-objects-provider.js +55 -0
  49. package/dist/digital-objects-provider.js.map +1 -0
  50. package/dist/do-sqlite-adapter.d.ts +402 -0
  51. package/dist/do-sqlite-adapter.d.ts.map +1 -0
  52. package/dist/do-sqlite-adapter.js +745 -0
  53. package/dist/do-sqlite-adapter.js.map +1 -0
  54. package/dist/docs-rels/custom-types.d.ts +134 -0
  55. package/dist/docs-rels/custom-types.d.ts.map +1 -0
  56. package/dist/docs-rels/custom-types.js +70 -0
  57. package/dist/docs-rels/custom-types.js.map +1 -0
  58. package/dist/docs-rels/index.d.ts +16 -0
  59. package/dist/docs-rels/index.d.ts.map +1 -0
  60. package/dist/docs-rels/index.js +16 -0
  61. package/dist/docs-rels/index.js.map +1 -0
  62. package/dist/docs-rels/migrations/index.d.ts +30 -0
  63. package/dist/docs-rels/migrations/index.d.ts.map +1 -0
  64. package/dist/docs-rels/migrations/index.js +128 -0
  65. package/dist/docs-rels/migrations/index.js.map +1 -0
  66. package/dist/docs-rels/schema.d.ts +2961 -0
  67. package/dist/docs-rels/schema.d.ts.map +1 -0
  68. package/dist/docs-rels/schema.js +244 -0
  69. package/dist/docs-rels/schema.js.map +1 -0
  70. package/dist/durable-clickhouse.d.ts.map +1 -1
  71. package/dist/durable-clickhouse.js +16 -13
  72. package/dist/durable-clickhouse.js.map +1 -1
  73. package/dist/durable-promise.d.ts.map +1 -1
  74. package/dist/durable-promise.js +34 -15
  75. package/dist/durable-promise.js.map +1 -1
  76. package/dist/errors.d.ts +127 -0
  77. package/dist/errors.d.ts.map +1 -0
  78. package/dist/errors.js +210 -0
  79. package/dist/errors.js.map +1 -0
  80. package/dist/eventbridge.d.ts +117 -0
  81. package/dist/eventbridge.d.ts.map +1 -0
  82. package/dist/eventbridge.js +238 -0
  83. package/dist/eventbridge.js.map +1 -0
  84. package/dist/events.d.ts +2 -2
  85. package/dist/events.d.ts.map +1 -1
  86. package/dist/events.js +1 -1
  87. package/dist/events.js.map +1 -1
  88. package/dist/execution-queue.d.ts.map +1 -1
  89. package/dist/execution-queue.js +4 -5
  90. package/dist/execution-queue.js.map +1 -1
  91. package/dist/index.d.ts +35 -8
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +106 -6
  94. package/dist/index.js.map +1 -1
  95. package/dist/linguistic.d.ts +3 -108
  96. package/dist/linguistic.d.ts.map +1 -1
  97. package/dist/linguistic.js +3 -372
  98. package/dist/linguistic.js.map +1 -1
  99. package/dist/logger.d.ts +132 -0
  100. package/dist/logger.d.ts.map +1 -0
  101. package/dist/logger.js +137 -0
  102. package/dist/logger.js.map +1 -0
  103. package/dist/memory-provider.d.ts +128 -0
  104. package/dist/memory-provider.d.ts.map +1 -1
  105. package/dist/memory-provider.js +592 -257
  106. package/dist/memory-provider.js.map +1 -1
  107. package/dist/pg-adapter.d.ts +424 -0
  108. package/dist/pg-adapter.d.ts.map +1 -0
  109. package/dist/pg-adapter.js +921 -0
  110. package/dist/pg-adapter.js.map +1 -0
  111. package/dist/pipelines-iceberg-emitter.d.ts +327 -0
  112. package/dist/pipelines-iceberg-emitter.d.ts.map +1 -0
  113. package/dist/pipelines-iceberg-emitter.js +351 -0
  114. package/dist/pipelines-iceberg-emitter.js.map +1 -0
  115. package/dist/provider-capabilities.d.ts +146 -0
  116. package/dist/provider-capabilities.d.ts.map +1 -0
  117. package/dist/provider-capabilities.js +214 -0
  118. package/dist/provider-capabilities.js.map +1 -0
  119. package/dist/rdb-provider-adapter.d.ts +195 -0
  120. package/dist/rdb-provider-adapter.d.ts.map +1 -0
  121. package/dist/rdb-provider-adapter.js +291 -0
  122. package/dist/rdb-provider-adapter.js.map +1 -0
  123. package/dist/schema/cascade.d.ts +48 -17
  124. package/dist/schema/cascade.d.ts.map +1 -1
  125. package/dist/schema/cascade.js +477 -278
  126. package/dist/schema/cascade.js.map +1 -1
  127. package/dist/schema/definition-caches.d.ts +24 -0
  128. package/dist/schema/definition-caches.d.ts.map +1 -0
  129. package/dist/schema/definition-caches.js +26 -0
  130. package/dist/schema/definition-caches.js.map +1 -0
  131. package/dist/schema/dependency-graph.d.ts +21 -109
  132. package/dist/schema/dependency-graph.d.ts.map +1 -1
  133. package/dist/schema/dependency-graph.js +25 -333
  134. package/dist/schema/dependency-graph.js.map +1 -1
  135. package/dist/schema/diff.d.ts +103 -0
  136. package/dist/schema/diff.d.ts.map +1 -0
  137. package/dist/schema/diff.js +329 -0
  138. package/dist/schema/diff.js.map +1 -0
  139. package/dist/schema/entity-operations.d.ts +99 -0
  140. package/dist/schema/entity-operations.d.ts.map +1 -0
  141. package/dist/schema/entity-operations.js +818 -0
  142. package/dist/schema/entity-operations.js.map +1 -0
  143. package/dist/schema/index.d.ts +28 -34
  144. package/dist/schema/index.d.ts.map +1 -1
  145. package/dist/schema/index.js +454 -521
  146. package/dist/schema/index.js.map +1 -1
  147. package/dist/schema/migration.d.ts +205 -0
  148. package/dist/schema/migration.d.ts.map +1 -0
  149. package/dist/schema/migration.js +327 -0
  150. package/dist/schema/migration.js.map +1 -0
  151. package/dist/schema/nl-query-generator.d.ts +68 -0
  152. package/dist/schema/nl-query-generator.d.ts.map +1 -0
  153. package/dist/schema/nl-query-generator.js +362 -0
  154. package/dist/schema/nl-query-generator.js.map +1 -0
  155. package/dist/schema/nl-query.d.ts +65 -0
  156. package/dist/schema/nl-query.d.ts.map +1 -0
  157. package/dist/schema/nl-query.js +178 -0
  158. package/dist/schema/nl-query.js.map +1 -0
  159. package/dist/schema/parse.d.ts.map +1 -1
  160. package/dist/schema/parse.js +144 -89
  161. package/dist/schema/parse.js.map +1 -1
  162. package/dist/schema/provider.d.ts +37 -0
  163. package/dist/schema/provider.d.ts.map +1 -1
  164. package/dist/schema/provider.js +15 -7
  165. package/dist/schema/provider.js.map +1 -1
  166. package/dist/schema/resolve.d.ts +46 -5
  167. package/dist/schema/resolve.d.ts.map +1 -1
  168. package/dist/schema/resolve.js +237 -95
  169. package/dist/schema/resolve.js.map +1 -1
  170. package/dist/schema/search-utils.d.ts +76 -0
  171. package/dist/schema/search-utils.d.ts.map +1 -0
  172. package/dist/schema/search-utils.js +86 -0
  173. package/dist/schema/search-utils.js.map +1 -0
  174. package/dist/schema/seed.d.ts +53 -0
  175. package/dist/schema/seed.d.ts.map +1 -0
  176. package/dist/schema/seed.js +94 -0
  177. package/dist/schema/seed.js.map +1 -0
  178. package/dist/schema/semantic.d.ts +10 -0
  179. package/dist/schema/semantic.d.ts.map +1 -1
  180. package/dist/schema/semantic.js +192 -86
  181. package/dist/schema/semantic.js.map +1 -1
  182. package/dist/schema/sub-apis.d.ts +52 -0
  183. package/dist/schema/sub-apis.d.ts.map +1 -0
  184. package/dist/schema/sub-apis.js +216 -0
  185. package/dist/schema/sub-apis.js.map +1 -0
  186. package/dist/schema/system-entities.d.ts +42 -0
  187. package/dist/schema/system-entities.d.ts.map +1 -0
  188. package/dist/schema/system-entities.js +101 -0
  189. package/dist/schema/system-entities.js.map +1 -0
  190. package/dist/schema/types.d.ts +91 -9
  191. package/dist/schema/types.d.ts.map +1 -1
  192. package/dist/schema/union-fallback.d.ts.map +1 -1
  193. package/dist/schema/union-fallback.js +21 -15
  194. package/dist/schema/union-fallback.js.map +1 -1
  195. package/dist/schema/value-generators/ai.d.ts +54 -0
  196. package/dist/schema/value-generators/ai.d.ts.map +1 -0
  197. package/dist/schema/value-generators/ai.js +136 -0
  198. package/dist/schema/value-generators/ai.js.map +1 -0
  199. package/dist/schema/value-generators/index.d.ts +126 -0
  200. package/dist/schema/value-generators/index.d.ts.map +1 -0
  201. package/dist/schema/value-generators/index.js +219 -0
  202. package/dist/schema/value-generators/index.js.map +1 -0
  203. package/dist/schema/value-generators/placeholder.d.ts +52 -0
  204. package/dist/schema/value-generators/placeholder.d.ts.map +1 -0
  205. package/dist/schema/value-generators/placeholder.js +328 -0
  206. package/dist/schema/value-generators/placeholder.js.map +1 -0
  207. package/dist/schema/value-generators/types.d.ts +116 -0
  208. package/dist/schema/value-generators/types.d.ts.map +1 -0
  209. package/dist/schema/value-generators/types.js +11 -0
  210. package/dist/schema/value-generators/types.js.map +1 -0
  211. package/dist/schema/version.d.ts +111 -0
  212. package/dist/schema/version.d.ts.map +1 -0
  213. package/dist/schema/version.js +190 -0
  214. package/dist/schema/version.js.map +1 -0
  215. package/dist/schema.d.ts +1095 -24
  216. package/dist/schema.d.ts.map +1 -1
  217. package/dist/schema.js +2852 -40
  218. package/dist/schema.js.map +1 -1
  219. package/dist/semantic-vectors.d.ts +39 -0
  220. package/dist/semantic-vectors.d.ts.map +1 -0
  221. package/dist/semantic-vectors.js +334 -0
  222. package/dist/semantic-vectors.js.map +1 -0
  223. package/dist/semantic.d.ts +29 -1
  224. package/dist/semantic.d.ts.map +1 -1
  225. package/dist/semantic.js +26 -16
  226. package/dist/semantic.js.map +1 -1
  227. package/dist/telemetry.d.ts +128 -0
  228. package/dist/telemetry.d.ts.map +1 -0
  229. package/dist/telemetry.js +305 -0
  230. package/dist/telemetry.js.map +1 -0
  231. package/dist/tests.d.ts.map +1 -1
  232. package/dist/tests.js +30 -22
  233. package/dist/tests.js.map +1 -1
  234. package/dist/type-guards.d.ts +50 -5
  235. package/dist/type-guards.d.ts.map +1 -1
  236. package/dist/type-guards.js +87 -16
  237. package/dist/type-guards.js.map +1 -1
  238. package/dist/types.d.ts +33 -245
  239. package/dist/types.d.ts.map +1 -1
  240. package/dist/types.js +62 -72
  241. package/dist/types.js.map +1 -1
  242. package/dist/validation.d.ts +2 -5
  243. package/dist/validation.d.ts.map +1 -1
  244. package/dist/validation.js +65 -93
  245. package/dist/validation.js.map +1 -1
  246. package/dist/worker/db-provider.d.ts +168 -0
  247. package/dist/worker/db-provider.d.ts.map +1 -0
  248. package/dist/worker/db-provider.js +277 -0
  249. package/dist/worker/db-provider.js.map +1 -0
  250. package/dist/worker/index.d.ts +35 -0
  251. package/dist/worker/index.d.ts.map +1 -0
  252. package/dist/worker/index.js +37 -0
  253. package/dist/worker/index.js.map +1 -0
  254. package/dist/worker.d.ts +779 -0
  255. package/dist/worker.d.ts.map +1 -0
  256. package/dist/worker.js +2786 -0
  257. package/dist/worker.js.map +1 -0
  258. package/package.json +46 -16
  259. package/src/docs-rels/migrations/0001-init.sql +125 -0
  260. package/LICENSE +0 -21
@@ -0,0 +1,590 @@
1
+ /**
2
+ * Cascade Write Strategy — sharded parallel writes for cascade generation
3
+ *
4
+ * Phase 2 entry point of the cascade epic per
5
+ * [ADR-0003](../../../docs/adr/0003-storage-strategy-pg-clickhouse-default.md)
6
+ * and the
7
+ * [implementation plan](../../../docs/plans/2026-05-05-cascade-storage-execution-implementation.md).
8
+ *
9
+ * This module is **strategy + scaffolding** — the *primitive* the cascade
10
+ * orchestrator (`aip-8yal`) calls. It does not run the orchestration loop
11
+ * itself, does not call LLMs, and does not implement the dual-write to
12
+ * Pipelines/Iceberg fan-out (that's `aip-0ypt`). It does:
13
+ *
14
+ * 1. **Shard-key derivation** — given a cascade context, pick the
15
+ * {@link ShardRef} the next batch should land in. Built-in strategies
16
+ * cover the three sharding models declared on `DBProvider`:
17
+ * `per-cascade` (DO SQLite default), `partitioned-by-tenant` (PG
18
+ * schema-per-tenant or `tenant_id` partition key), `unsharded`.
19
+ *
20
+ * 2. **Bulk-write API** — {@link writeBatch} routes a batch of Things +
21
+ * Actions through the adapter's cascade fast path. For PG, that's the
22
+ * **CTE jsonb-bulk shape** proven by the substrate-write-probes
23
+ * (91 ms p50 for 500 things + 499 actions on Neon HTTP — see
24
+ * `docs/reviews/2026-05-05-cascade-poc-evaluation.md`). For DO SQLite,
25
+ * the routing layer pins the shard and forwards the batch into the
26
+ * per-cascade DO. For ClickHouse, JSONEachRow is the path.
27
+ *
28
+ * 3. **Read-back-during-traversal API** — {@link readShardLocal} performs a
29
+ * point read against the same shard the batch was written to. Cascade
30
+ * generation reads back just-written entities to inform the next
31
+ * generation step; cross-shard reads on the hot path are explicitly
32
+ * not supported.
33
+ *
34
+ * 4. **Pipelines fan-out hook** — a {@link AnalyticalEmitter} callback the
35
+ * caller may pass to {@link writeBatch}. The cascade-write-strategy
36
+ * invokes it post-commit so Stack B's dual-write
37
+ * (DO SQLite local → Pipelines → Iceberg → ClickHouse) can be wired
38
+ * later by `aip-0ypt` without changing this surface.
39
+ *
40
+ * ## Why a separate module
41
+ *
42
+ * The cascade orchestrator is long, has its own retry/validation/policy
43
+ * concerns, and needs swappable storage. Pulling the write-strategy
44
+ * primitive out keeps the orchestration module focused, lets us unit-test
45
+ * shard-key derivation independently of LLM calls, and keeps the
46
+ * provenance of the write shape (the substrate-write-probes verdict)
47
+ * documented in one place rather than scattered through orchestrator code.
48
+ *
49
+ * @see {@link ../docs/adr/0003-storage-strategy-pg-clickhouse-default.md}
50
+ * @see {@link ../docs/reviews/2026-05-05-cascade-poc-evaluation.md}
51
+ * @packageDocumentation
52
+ */
53
+ import { getProviderCapabilities } from './db-provider-port.js';
54
+ /**
55
+ * Built-in cascade sharding strategies.
56
+ *
57
+ * Each maps the abstract {@link ShardingModel} declared on a `DBProvider`
58
+ * to a concrete routing-key derivation. Adapters consult their adapter's
59
+ * declared sharding model via {@link getProviderCapabilities} when
60
+ * picking a default; callers can override.
61
+ *
62
+ * - {@link perCascade} — one shard per cascade. Default for
63
+ * `do-sqlite` adapter (per ADR-0003 enabling pattern). Throws if
64
+ * {@link CascadeShardContext.cascadeId} is missing.
65
+ * - {@link partitionedByTenant} — one shard per tenant. Default for
66
+ * `pg+pgvector` adapter. Throws if {@link CascadeShardContext.tenantId}
67
+ * is missing.
68
+ * - {@link unsharded} — single global shard. Default for `memory` and any
69
+ * adapter that does not declare a sharding model. Always returns the
70
+ * constant key `'__shared__'`.
71
+ */
72
+ export const CascadeShardingStrategies = {
73
+ /**
74
+ * One shard per cascade. Stack B's enabling pattern: every active
75
+ * cascade gets its own DO (or its own PG partition / temp schema)
76
+ * giving full single-shard write throughput in parallel.
77
+ *
78
+ * @param defaultCascadeId - Fallback when the per-op context omits
79
+ * `cascadeId`. Useful when the orchestrator has a stable cascade
80
+ * scope but individual write batches don't restate it.
81
+ */
82
+ perCascade(defaultCascadeId) {
83
+ return (ctx) => {
84
+ const cascadeId = ctx.cascadeId ?? defaultCascadeId;
85
+ if (!cascadeId) {
86
+ throw new Error('CascadeShardingStrategies.perCascade: no cascadeId in context. ' +
87
+ 'Pass `cascadeId` on the CascadeShardContext, or supply a ' +
88
+ 'default via perCascade(defaultCascadeId).');
89
+ }
90
+ return {
91
+ key: `cascade:${cascadeId}`,
92
+ model: 'per-cascade',
93
+ context: { ...ctx, cascadeId },
94
+ };
95
+ };
96
+ },
97
+ /**
98
+ * One shard per tenant. The natural shape for multi-tenant Postgres
99
+ * (schema-per-tenant or `tenant_id` partition key). Many cascades
100
+ * within the same tenant share a partition; tenants are isolated.
101
+ *
102
+ * @param defaultTenantId - Fallback when the per-op context omits
103
+ * `tenantId`.
104
+ */
105
+ partitionedByTenant(defaultTenantId) {
106
+ return (ctx) => {
107
+ const tenantId = ctx.tenantId ?? defaultTenantId;
108
+ if (!tenantId) {
109
+ throw new Error('CascadeShardingStrategies.partitionedByTenant: no tenantId in ' +
110
+ 'context. Pass `tenantId` on the CascadeShardContext, or supply ' +
111
+ 'a default via partitionedByTenant(defaultTenantId).');
112
+ }
113
+ return {
114
+ key: `tenant:${tenantId}`,
115
+ model: 'partitioned-by-tenant',
116
+ context: { ...ctx, tenantId },
117
+ };
118
+ };
119
+ },
120
+ /**
121
+ * Single global shard. Default for in-memory / dev / single small PG
122
+ * deployments. Cascade throughput hits the underlying adapter's
123
+ * single-writer ceiling.
124
+ */
125
+ unsharded() {
126
+ return (ctx) => ({
127
+ key: '__shared__',
128
+ model: 'unsharded',
129
+ context: { ...ctx },
130
+ });
131
+ },
132
+ };
133
+ /**
134
+ * The cascade write strategy primitive.
135
+ *
136
+ * Composes a `DBProvider` adapter with a sharding strategy and exposes
137
+ * the bulk-write + read-back surface the cascade orchestrator
138
+ * (`aip-8yal`) calls per traversal step. This module owns:
139
+ *
140
+ * - Routing-key derivation ({@link pickShard})
141
+ * - Bulk write via the adapter's cascade fast path ({@link writeBatch})
142
+ * - Local read-back from the same shard ({@link readShardLocal})
143
+ * - Analytical fan-out hook (post-commit; opt-in)
144
+ *
145
+ * It does NOT own:
146
+ *
147
+ * - LLM-driven generation (the orchestrator calls it before issuing batches)
148
+ * - Validation / policy / retry (the orchestrator wraps the strategy)
149
+ * - Pipelines→Iceberg dual-write semantics (`aip-0ypt`)
150
+ * - Cross-shard joins (out of scope per ADR-0003 hot-path constraint)
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * import {
155
+ * CascadeWriteStrategy,
156
+ * createPostgresProvider,
157
+ * } from 'ai-database'
158
+ *
159
+ * const adapter = createPostgresProvider({ executor, namespace: 'tenant-9' })
160
+ * const strategy = new CascadeWriteStrategy({
161
+ * adapter,
162
+ * sharding: 'partitioned-by-tenant',
163
+ * defaultTenantId: 'tenant-9',
164
+ * })
165
+ *
166
+ * const shard = strategy.pickShard({
167
+ * rootEntity: { $id: 'fh-1', $type: 'FoundingHypothesis' },
168
+ * tenantId: 'tenant-9',
169
+ * })
170
+ *
171
+ * await strategy.writeBatch(shard, {
172
+ * things: [{ id: 'cust-1', type: 'Customer', data: { name: 'Acme' } }],
173
+ * actions: [{ verb: 'placedBy', subject: 'order-1', object: 'cust-1', status: 'completed' }],
174
+ * })
175
+ * ```
176
+ */
177
+ export class CascadeWriteStrategy {
178
+ adapter;
179
+ strategy;
180
+ maxBatchSize;
181
+ emitter;
182
+ constructor(options) {
183
+ this.adapter = options.adapter;
184
+ this.strategy = resolveShardingStrategy(options);
185
+ this.maxBatchSize = options.maxBatchSize ?? 1000;
186
+ this.emitter = options.analyticalEmitter;
187
+ }
188
+ /**
189
+ * Derive the {@link ShardRef} the next batch should land in. Pure —
190
+ * never touches the adapter.
191
+ *
192
+ * Throws when the active strategy needs context the caller didn't
193
+ * supply (e.g. `'per-cascade'` with no `cascadeId`).
194
+ */
195
+ pickShard(context) {
196
+ return this.strategy(context);
197
+ }
198
+ /**
199
+ * Bulk-commit a batch of Things + Actions to the shard.
200
+ *
201
+ * - When the adapter is {@link BulkCommitCapable}, the entire batch
202
+ * travels in a single fast-path call — for PG that's the CTE
203
+ * jsonb-bulk shape (91 ms p50 / 500 things on Neon HTTP), for CH
204
+ * the JSONEachRow path.
205
+ * - When the adapter is not bulk-capable (in-memory, DO SQLite via
206
+ * the current wire shape), the strategy falls back to per-op
207
+ * `create()` + `relate()` calls. This still flows through the
208
+ * shard-aware adapter so reads land on the same shard, but
209
+ * throughput is the per-op ceiling.
210
+ * - Batches larger than {@link maxBatchSize} are split into rounds.
211
+ * Rounds run sequentially within a single `writeBatch` call to
212
+ * preserve write-order guarantees the orchestrator may rely on
213
+ * (e.g. parents before children). Sibling parallelism is the
214
+ * orchestrator's concern, not this primitive's.
215
+ *
216
+ * Post-commit, if an {@link AnalyticalEmitter} was configured, it is
217
+ * invoked once per chunk so Stack B's analytical fan-out can mirror
218
+ * the same batch into Pipelines→Iceberg. Emitter failures are logged
219
+ * and swallowed — they MUST NOT fail the cascade write.
220
+ */
221
+ async writeBatch(shard, batch) {
222
+ const things = batch.things ?? [];
223
+ const actions = batch.actions ?? [];
224
+ if (things.length === 0 && actions.length === 0) {
225
+ return { thingsInserted: 0, actionsInserted: 0, shard };
226
+ }
227
+ const boundAdapter = this.bindAdapterToShard(shard);
228
+ const chunks = chunkBatch({ things, actions }, this.maxBatchSize);
229
+ let thingsInserted = 0;
230
+ let actionsInserted = 0;
231
+ for (const chunk of chunks) {
232
+ const result = await this.writeChunk(boundAdapter, chunk);
233
+ thingsInserted += result.thingsInserted;
234
+ actionsInserted += result.actionsInserted;
235
+ // Post-commit fan-out hook for aip-0ypt. Failures are non-fatal —
236
+ // the cascade local commit is the source of truth for traversal.
237
+ if (this.emitter) {
238
+ try {
239
+ await this.emitter({ shard, batch: chunk, result });
240
+ }
241
+ catch {
242
+ // Analytical fan-out is best-effort; log site is the caller's
243
+ // concern (we don't pull a logger dependency here).
244
+ }
245
+ }
246
+ }
247
+ return { thingsInserted, actionsInserted, shard };
248
+ }
249
+ /**
250
+ * Read a Thing back from the same shard the batch was written to.
251
+ *
252
+ * Cascade generation reads back just-written entities to inform the
253
+ * next traversal step (e.g. resolve a freshly-written `Customer`
254
+ * before generating its `Orders`). Cross-shard reads are explicitly
255
+ * not supported on the hot path per ADR-0003.
256
+ *
257
+ * Returns `null` if the entity is not in the shard. The caller may
258
+ * still attempt a cross-shard read via the unsharded adapter surface
259
+ * if needed for cold-path reconciliation.
260
+ */
261
+ async readShardLocal(shard, type, id) {
262
+ const boundAdapter = this.bindAdapterToShard(shard);
263
+ return boundAdapter.get(type, id);
264
+ }
265
+ /**
266
+ * Read a list of just-written entities from the shard. Wraps
267
+ * `adapter.list(type)` after binding the shard context.
268
+ *
269
+ * Use when the cascade needs to enumerate all of a type the current
270
+ * cascade has produced (e.g. all `OrderItem` for the current
271
+ * `Order`). For point reads, prefer {@link readShardLocal}.
272
+ */
273
+ async listShardLocal(shard, type, options) {
274
+ const boundAdapter = this.bindAdapterToShard(shard);
275
+ return boundAdapter.list(type, options);
276
+ }
277
+ // ===========================================================================
278
+ // Internal helpers
279
+ // ===========================================================================
280
+ /**
281
+ * Bind the adapter to the shard so subsequent ops route correctly.
282
+ *
283
+ * For DO SQLite, {@link DOSqliteAdapter.withContext} is used to pin
284
+ * the cascade/tenant id. For PG/CH, the `ns` column on the adapter
285
+ * already carries the partition key, so this is a no-op (return
286
+ * `this`).
287
+ */
288
+ bindAdapterToShard(shard) {
289
+ const bindable = this.adapter;
290
+ if (typeof bindable.withContext === 'function') {
291
+ return bindable.withContext({ ...shard.context });
292
+ }
293
+ return this.adapter;
294
+ }
295
+ /**
296
+ * Write a single chunk through the adapter's cascade fast path or
297
+ * the per-op fallback.
298
+ */
299
+ async writeChunk(adapter, chunk) {
300
+ const things = chunk.things ?? [];
301
+ const actions = chunk.actions ?? [];
302
+ const bulkCapable = adapter;
303
+ if (typeof bulkCapable.commitBatch === 'function') {
304
+ // PG / CH fast path. PG uses the CTE jsonb-bulk shape (proven by
305
+ // the substrate-write-probes); CH uses JSONEachRow. Both shapes
306
+ // are documented on the respective adapter.
307
+ return bulkCapable.commitBatch({
308
+ ...(things.length > 0 && { things }),
309
+ ...(actions.length > 0 && {
310
+ actions: actions.map((a) => ({
311
+ ...(a.id !== undefined && { id: a.id }),
312
+ verb: a.verb,
313
+ subject: a.subject,
314
+ object: a.object,
315
+ roles: a.roles,
316
+ data: a.data,
317
+ status: a.status,
318
+ })),
319
+ }),
320
+ });
321
+ }
322
+ // Fallback: per-op writes. Used by DO SQLite (bulk path lives at the
323
+ // DO wire level — out of scope for this bead) and the in-memory
324
+ // adapter. Sequential within a chunk so writes appear in the order
325
+ // the orchestrator emitted them; parallelism is the orchestrator's
326
+ // concern.
327
+ let thingsInserted = 0;
328
+ for (const thing of things) {
329
+ try {
330
+ await adapter.create(thing.type, thing.id, thing.data);
331
+ thingsInserted += 1;
332
+ }
333
+ catch (err) {
334
+ // Best-effort idempotency: swallow already-exists errors so
335
+ // re-runs of a content-hashed cascade don't fail. Surface
336
+ // anything else.
337
+ if (!isAlreadyExistsError(err))
338
+ throw err;
339
+ }
340
+ }
341
+ let actionsInserted = 0;
342
+ for (const action of actions) {
343
+ // Use recordAction when available (SVO surface); fall back to
344
+ // relate() if the adapter only exposes the structural surface.
345
+ const svo = adapter;
346
+ if (typeof svo.recordAction === 'function') {
347
+ await svo.recordAction({
348
+ verb: action.verb,
349
+ ...(action.subject !== undefined && { subject: action.subject }),
350
+ ...(action.object !== undefined && { object: action.object }),
351
+ ...(action.roles !== undefined && { roles: action.roles }),
352
+ ...(action.data !== undefined && { data: action.data }),
353
+ ...(action.status !== undefined && { status: action.status }),
354
+ });
355
+ }
356
+ else if (action.subject && action.object) {
357
+ // Best-effort fallback — the adapter doesn't speak SVO. We have
358
+ // no type information for relate(), which expects fromType /
359
+ // toType; we use the data fields if present, else a generic
360
+ // 'Thing' placeholder. Adapters in this position are dev-only
361
+ // (in-memory tests) so this is acceptable.
362
+ const fromType = action.data?.['fromType'] ?? 'Thing';
363
+ const toType = action.data?.['toType'] ?? 'Thing';
364
+ await adapter.relate(fromType, action.subject, action.verb, toType, action.object);
365
+ }
366
+ actionsInserted += 1;
367
+ }
368
+ return { thingsInserted, actionsInserted };
369
+ }
370
+ }
371
+ // =============================================================================
372
+ // PG-specific bulk-write helper — the proven CTE jsonb-bulk shape
373
+ // =============================================================================
374
+ /**
375
+ * Stand-alone helper that emits the PG cascade-write SQL the
376
+ * substrate-write-probes proved out: a single CTE round-trip with
377
+ * bulk `VALUES (...), (...)` inserts and `ON CONFLICT DO NOTHING`.
378
+ *
379
+ * **This is the shape the canonical PG adapter's
380
+ * {@link PostgresProvider.commitBatch} uses.** The helper is exported so
381
+ * cascade orchestrators that bypass the adapter (e.g. running raw SQL
382
+ * for benchmarking) can still use the proven shape without re-deriving
383
+ * it. The adapter's `commitBatch` remains the recommended path.
384
+ *
385
+ * Returns the SQL text + ordered positional params. Things take 4
386
+ * columns: `(ns, id, type, data)`. Actions take 10 columns:
387
+ * `(ns, id, verb, subject, object, roles, data, status, created_at, completed_at)`.
388
+ *
389
+ * Why: documenting the shape in a stand-alone helper anchors the write
390
+ * shape to the substrate-write-probes evidence (91 ms p50 for 500 docs +
391
+ * 499 rels on Neon HTTP, sublinear scaling above N=100). Future schema
392
+ * changes that invalidate the column list will land here visibly.
393
+ *
394
+ * @internal Use {@link PostgresProvider.commitBatch} for production code.
395
+ */
396
+ export function buildPgCommitBatchSql(input) {
397
+ const { schema, namespace, things, actions, now } = input;
398
+ if (things.length === 0 && actions.length === 0)
399
+ return null;
400
+ const thingCols = 4;
401
+ const actionCols = 10;
402
+ const thingOffset = things.length * thingCols;
403
+ const thingPlaceholders = things
404
+ .map((_, i) => {
405
+ const base = i * thingCols;
406
+ return `($${base + 1}, $${base + 2}, $${base + 3}, $${base + 4}::jsonb)`;
407
+ })
408
+ .join(', ');
409
+ const actionPlaceholders = actions
410
+ .map((_, i) => {
411
+ const base = thingOffset + i * actionCols;
412
+ return `($${base + 1}, $${base + 2}, $${base + 3}, $${base + 4}, $${base + 5}, $${base + 6}::jsonb, $${base + 7}::jsonb, $${base + 8}, $${base + 9}, $${base + 10})`;
413
+ })
414
+ .join(', ');
415
+ const params = [];
416
+ for (const t of things) {
417
+ params.push(namespace, t.id, t.type, JSON.stringify(t.data));
418
+ }
419
+ for (const a of actions) {
420
+ const status = a.status ?? 'pending';
421
+ const completedAt = status === 'completed' || status === 'failed' || status === 'cancelled' ? now : null;
422
+ params.push(namespace, a.id ?? generateId(), a.verb, a.subject ?? null, a.object ?? null, JSON.stringify(a.roles ?? {}), JSON.stringify(a.data ?? {}), status, now, completedAt);
423
+ }
424
+ const ctes = [];
425
+ if (things.length > 0) {
426
+ ctes.push(`inserted_things AS (
427
+ INSERT INTO ${schema}.things (ns, id, type, data) VALUES ${thingPlaceholders}
428
+ ON CONFLICT ON CONSTRAINT things_pk DO NOTHING
429
+ RETURNING 1
430
+ )`);
431
+ }
432
+ if (actions.length > 0) {
433
+ ctes.push(`inserted_actions AS (
434
+ INSERT INTO ${schema}.actions
435
+ (ns, id, verb, subject, object, roles, data, status, created_at, completed_at)
436
+ VALUES ${actionPlaceholders}
437
+ ON CONFLICT ON CONSTRAINT actions_pk DO NOTHING
438
+ RETURNING 1
439
+ )`);
440
+ }
441
+ const sql = `WITH ${ctes.join(', ')}
442
+ SELECT
443
+ ${things.length > 0 ? `(SELECT COUNT(*) FROM inserted_things)::int` : '0'} AS things_inserted,
444
+ ${actions.length > 0 ? `(SELECT COUNT(*) FROM inserted_actions)::int` : '0'} AS actions_inserted`;
445
+ return { sql, params };
446
+ }
447
+ // =============================================================================
448
+ // DO SQLite shard-routing helper
449
+ // =============================================================================
450
+ /**
451
+ * Resolve the DO id name for a given shard from a Cloudflare DO
452
+ * namespace binding.
453
+ *
454
+ * The actual shard pinning happens inside `DOSqliteAdapter` —
455
+ * {@link DOSqliteAdapter.withContext} consumes the `ShardRef.context`
456
+ * when subsequent ops are issued, and the adapter's internal
457
+ * `resolveStub` calls `namespace.idFromName(...).` This helper exposes
458
+ * the same routing logic for callers that need to **manually** route a
459
+ * batch into a per-cascade DO without going through the adapter (e.g.
460
+ * direct fetch into a DO that hasn't been wrapped yet).
461
+ *
462
+ * For canonical use, prefer the adapter — `withContext(shard.context)`
463
+ * encapsulates this.
464
+ *
465
+ * @example
466
+ * ```ts
467
+ * import { resolveDOIdName, CascadeShardingStrategies } from 'ai-database'
468
+ *
469
+ * const strategy = CascadeShardingStrategies.perCascade()
470
+ * const shard = strategy({ cascadeId: 'abc' })
471
+ * const idName = resolveDOIdName(shard) // 'cascade:abc'
472
+ * const id = env.DATABASE.idFromName(idName)
473
+ * const stub = env.DATABASE.get(id)
474
+ * await stub.fetch(...)
475
+ * ```
476
+ */
477
+ export function resolveDOIdName(shard) {
478
+ return shard.key;
479
+ }
480
+ // =============================================================================
481
+ // Helpers — chunking, error classification, id generation, strategy resolution
482
+ // =============================================================================
483
+ /**
484
+ * Split a batch into chunks no larger than `maxBatchSize` rows
485
+ * (Things + Actions counted together).
486
+ *
487
+ * The substrate-write-probes verdict shows sublinear scaling above N=100
488
+ * for the CTE shape — a single round-trip carrying 500 things + 499 rels
489
+ * lands in 91 ms p50. We default to 1000 rows/chunk in the strategy;
490
+ * callers can override via {@link CascadeWriteStrategyOptions.maxBatchSize}.
491
+ *
492
+ * Things and Actions are kept together within a chunk so a parent +
493
+ * child + their relation can fit in one round-trip when the orchestrator
494
+ * emits them as one batch. When the chunk boundary falls inside a
495
+ * Thing/Action group the orchestrator built, callers should size their
496
+ * batches (or the `maxBatchSize`) to avoid splitting groups.
497
+ *
498
+ * @internal exported for tests.
499
+ */
500
+ export function chunkBatch(batch, maxBatchSize) {
501
+ if (maxBatchSize <= 0) {
502
+ throw new Error('chunkBatch: maxBatchSize must be > 0');
503
+ }
504
+ const things = batch.things ?? [];
505
+ const actions = batch.actions ?? [];
506
+ const total = things.length + actions.length;
507
+ if (total <= maxBatchSize)
508
+ return [{ things, actions }];
509
+ const chunks = [];
510
+ let ti = 0;
511
+ let ai = 0;
512
+ while (ti < things.length || ai < actions.length) {
513
+ const remainingThings = things.length - ti;
514
+ const takeThings = Math.min(remainingThings, maxBatchSize);
515
+ const remaining = maxBatchSize - takeThings;
516
+ const takeActions = Math.min(actions.length - ai, remaining);
517
+ chunks.push({
518
+ things: things.slice(ti, ti + takeThings),
519
+ actions: actions.slice(ai, ai + takeActions),
520
+ });
521
+ ti += takeThings;
522
+ ai += takeActions;
523
+ }
524
+ return chunks;
525
+ }
526
+ /**
527
+ * Classify an error as the adapter's idempotent-conflict signal so
528
+ * per-op fallback writes can swallow re-runs.
529
+ */
530
+ function isAlreadyExistsError(err) {
531
+ if (!err)
532
+ return false;
533
+ const msg = err instanceof Error ? err.message : String(err);
534
+ // Loose match — adapters use different wording. Cascade re-runs depend
535
+ // on content-hashed ids, so a true conflict is benign.
536
+ return /already exists|duplicate|unique constraint|conflict/i.test(msg);
537
+ }
538
+ /**
539
+ * Resolve the active sharding strategy from constructor options. Falls
540
+ * back to the adapter's declared {@link ShardingModel} when the caller
541
+ * didn't supply one.
542
+ */
543
+ function resolveShardingStrategy(opts) {
544
+ const sharding = opts.sharding;
545
+ if (typeof sharding === 'function')
546
+ return sharding;
547
+ const declared = sharding ?? getProviderCapabilities(opts.adapter).shardingModel;
548
+ switch (declared) {
549
+ case 'per-cascade':
550
+ return CascadeShardingStrategies.perCascade(opts.defaultCascadeId);
551
+ case 'partitioned-by-tenant':
552
+ return CascadeShardingStrategies.partitionedByTenant(opts.defaultTenantId);
553
+ case 'unsharded':
554
+ return CascadeShardingStrategies.unsharded();
555
+ default:
556
+ // Custom / forward-compat shard models declared by future adapters
557
+ // fall back to unsharded; callers should pass an explicit strategy.
558
+ return CascadeShardingStrategies.unsharded();
559
+ }
560
+ }
561
+ function generateId() {
562
+ if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
563
+ return crypto.randomUUID();
564
+ }
565
+ // Tests in environments without `crypto` get a deterministic prefix +
566
+ // timestamp; production paths always have crypto available.
567
+ return `cascade-${Date.now()}-${Math.random().toString(36).slice(2)}`;
568
+ }
569
+ /**
570
+ * Convenience factory.
571
+ *
572
+ * @example
573
+ * ```ts
574
+ * import {
575
+ * createCascadeWriteStrategy,
576
+ * createPostgresProvider,
577
+ * } from 'ai-database'
578
+ *
579
+ * const adapter = createPostgresProvider({ executor, namespace: 't9' })
580
+ * const strategy = createCascadeWriteStrategy({
581
+ * adapter,
582
+ * sharding: 'partitioned-by-tenant',
583
+ * defaultTenantId: 't9',
584
+ * })
585
+ * ```
586
+ */
587
+ export function createCascadeWriteStrategy(options) {
588
+ return new CascadeWriteStrategy(options);
589
+ }
590
+ //# sourceMappingURL=cascade-write-strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade-write-strategy.js","sourceRoot":"","sources":["../src/cascade-write-strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAIH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAyF/D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC;;;;;;;;OAQG;IACH,UAAU,CAAC,gBAAyB;QAClC,OAAO,CAAC,GAAG,EAAE,EAAE;YACb,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,gBAAgB,CAAA;YACnD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,iEAAiE;oBAC/D,2DAA2D;oBAC3D,2CAA2C,CAC9C,CAAA;YACH,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,WAAW,SAAS,EAAE;gBAC3B,KAAK,EAAE,aAAa;gBACpB,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE;aAC/B,CAAA;QACH,CAAC,CAAA;IACH,CAAC;IAED;;;;;;;OAOG;IACH,mBAAmB,CAAC,eAAwB;QAC1C,OAAO,CAAC,GAAG,EAAE,EAAE;YACb,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,eAAe,CAAA;YAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACb,gEAAgE;oBAC9D,iEAAiE;oBACjE,qDAAqD,CACxD,CAAA;YACH,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,UAAU,QAAQ,EAAE;gBACzB,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE;aAC9B,CAAA;QACH,CAAC,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACf,GAAG,EAAE,YAAY;YACjB,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE;SACpB,CAAC,CAAA;IACJ,CAAC;CACO,CAAA;AA6MV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,OAAO,oBAAoB;IACd,OAAO,CAAY;IACnB,QAAQ,CAAyB;IACzC,YAAY,CAAQ;IACZ,OAAO,CAA+B;IAEvD,YAAY,OAAoC;QAC9C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAqB,CAAA;QAC5C,IAAI,CAAC,QAAQ,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAA;QAChD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAA;QAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAA;IAC1C,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,OAA4B;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC/B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,UAAU,CAAC,KAAe,EAAE,KAAmB;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAA;QACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,CAAA;QACzD,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;QAEjE,IAAI,cAAc,GAAG,CAAC,CAAA;QACtB,IAAI,eAAe,GAAG,CAAC,CAAA;QACvB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;YACzD,cAAc,IAAI,MAAM,CAAC,cAAc,CAAA;YACvC,eAAe,IAAI,MAAM,CAAC,eAAe,CAAA;YACzC,kEAAkE;YAClE,iEAAiE;YACjE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACP,8DAA8D;oBAC9D,oDAAoD;gBACtD,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,EAAE,CAAA;IACnD,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,cAAc,CAClB,KAAe,EACf,IAAY,EACZ,EAAU;QAEV,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QACnD,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACnC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,cAAc,CAClB,KAAe,EACf,IAAY,EACZ,OAA6C;QAE7C,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QACnD,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACzC,CAAC;IAED,8EAA8E;IAC9E,mBAAmB;IACnB,8EAA8E;IAE9E;;;;;;;OAOG;IACK,kBAAkB,CAAC,KAAe;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAwD,CAAA;QAC9E,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAC/C,OAAO,QAAQ,CAAC,WAAW,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACnD,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,UAAU,CACtB,OAAmB,EACnB,KAAmB;QAEnB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAA;QAEnC,MAAM,WAAW,GAAG,OAAkD,CAAA;QACtE,IAAI,OAAO,WAAW,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAClD,iEAAiE;YACjE,gEAAgE;YAChE,4CAA4C;YAC5C,OAAO,WAAW,CAAC,WAAW,CAAC;gBAC7B,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;gBACpC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI;oBACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;wBACvC,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;wBAClB,MAAM,EAAE,CAAC,CAAC,MAAM;wBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;wBACd,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;qBACjB,CAAC,CAAC;iBACJ,CAAC;aACH,CAAC,CAAA;QACJ,CAAC;QAED,qEAAqE;QACrE,gEAAgE;QAChE,mEAAmE;QACnE,mEAAmE;QACnE,WAAW;QACX,IAAI,cAAc,GAAG,CAAC,CAAA;QACtB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;gBACtD,cAAc,IAAI,CAAC,CAAA;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,4DAA4D;gBAC5D,0DAA0D;gBAC1D,iBAAiB;gBACjB,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;oBAAE,MAAM,GAAG,CAAA;YAC3C,CAAC;QACH,CAAC;QACD,IAAI,eAAe,GAAG,CAAC,CAAA;QACvB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,8DAA8D;YAC9D,+DAA+D;YAC/D,MAAM,GAAG,GAAG,OAAuD,CAAA;YACnE,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;gBAC3C,MAAM,GAAG,CAAC,YAAY,CAAC;oBACrB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;oBAChE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;oBAC7D,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;oBAC1D,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;oBACvD,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;iBAC9D,CAAC,CAAA;YACJ,CAAC;iBAAM,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC3C,gEAAgE;gBAChE,6DAA6D;gBAC7D,4DAA4D;gBAC5D,8DAA8D;gBAC9D,2CAA2C;gBAC3C,MAAM,QAAQ,GAAI,MAAM,CAAC,IAAI,EAAE,CAAC,UAAU,CAAY,IAAI,OAAO,CAAA;gBACjE,MAAM,MAAM,GAAI,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAY,IAAI,OAAO,CAAA;gBAC7D,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACpF,CAAC;YACD,eAAe,IAAI,CAAC,CAAA;QACtB,CAAC;QACD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA;IAC5C,CAAC;CACF;AAED,gFAAgF;AAChF,kEAAkE;AAClE,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAOrC;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,CAAA;IACzD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAE5D,MAAM,SAAS,GAAG,CAAC,CAAA;IACnB,MAAM,UAAU,GAAG,EAAE,CAAA;IACrB,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,GAAG,SAAS,CAAA;IAE7C,MAAM,iBAAiB,GAAG,MAAM;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,CAAA;QAC1B,OAAO,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAA;IAC1E,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,kBAAkB,GAAG,OAAO;SAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,WAAW,GAAG,CAAC,GAAG,UAAU,CAAA;QACzC,OAAO,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAC1E,IAAI,GAAG,CACT,aAAa,IAAI,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,GAAG,CAAA;IAC5E,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,MAAM,GAAc,EAAE,CAAA;IAC5B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,SAAS,CAAA;QACpC,MAAM,WAAW,GACf,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;QACtF,MAAM,CAAC,IAAI,CACT,SAAS,EACT,CAAC,CAAC,EAAE,IAAI,UAAU,EAAE,EACpB,CAAC,CAAC,IAAI,EACN,CAAC,CAAC,OAAO,IAAI,IAAI,EACjB,CAAC,CAAC,MAAM,IAAI,IAAI,EAChB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,EAC7B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAC5B,MAAM,EACN,GAAG,EACH,WAAW,CACZ,CAAA;IACH,CAAC;IAED,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CACP;sBACgB,MAAM,uCAAuC,iBAAiB;;;QAG5E,CACH,CAAA;IACH,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CACP;sBACgB,MAAM;;iBAEX,kBAAkB;;;QAG3B,CACH,CAAA;IACH,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;;QAE7B,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,6CAA6C,CAAC,CAAC,CAAC,GAAG;QAEvE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,GACxE,sBAAsB,CAAA;IAE1B,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAA;AACxB,CAAC;AAED,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,eAAe,CAAC,KAAe;IAC7C,OAAO,KAAK,CAAC,GAAG,CAAA;AAClB,CAAC;AAED,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAEhF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAmB,EAAE,YAAoB;IAClE,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;IACzD,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAA;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAA;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;IAC5C,IAAI,KAAK,IAAI,YAAY;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;IAEvD,MAAM,MAAM,GAAmB,EAAE,CAAA;IACjC,IAAI,EAAE,GAAG,CAAC,CAAA;IACV,IAAI,EAAE,GAAG,CAAC,CAAA;IACV,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QACjD,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,CAAA;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;QAC1D,MAAM,SAAS,GAAG,YAAY,GAAG,UAAU,CAAA;QAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,SAAS,CAAC,CAAA;QAC5D,MAAM,CAAC,IAAI,CAAC;YACV,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,UAAU,CAAC;YACzC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,WAAW,CAAC;SAC7C,CAAC,CAAA;QACF,EAAE,IAAI,UAAU,CAAA;QAChB,EAAE,IAAI,WAAW,CAAA;IACnB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,GAAY;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAA;IACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC5D,uEAAuE;IACvE,uDAAuD;IACvD,OAAO,sDAAsD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACzE,CAAC;AAED;;;;GAIG;AACH,SAAS,uBAAuB,CAAC,IAAiC;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,IAAI,OAAO,QAAQ,KAAK,UAAU;QAAE,OAAO,QAAQ,CAAA;IACnD,MAAM,QAAQ,GAAG,QAAQ,IAAI,uBAAuB,CAAC,IAAI,CAAC,OAAqB,CAAC,CAAC,aAAa,CAAA;IAE9F,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa;YAChB,OAAO,yBAAyB,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;QACpE,KAAK,uBAAuB;YAC1B,OAAO,yBAAyB,CAAC,mBAAmB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAC5E,KAAK,WAAW;YACd,OAAO,yBAAyB,CAAC,SAAS,EAAE,CAAA;QAC9C;YACE,mEAAmE;YACnE,oEAAoE;YACpE,OAAO,yBAAyB,CAAC,SAAS,EAAE,CAAA;IAChD,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QAC7E,OAAO,MAAM,CAAC,UAAU,EAAE,CAAA;IAC5B,CAAC;IACD,sEAAsE;IACtE,4DAA4D;IAC5D,OAAO,WAAW,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;AACvE,CAAC;AAcD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAoC;IAEpC,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAA;AAC1C,CAAC"}