@async/db 0.2.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 (398) hide show
  1. package/CHANGELOG.md +167 -0
  2. package/README.md +431 -0
  3. package/SPEC.md +1429 -0
  4. package/db.config.example.mjs +128 -0
  5. package/dist/cli/args.d.ts +8 -0
  6. package/dist/cli/args.js +16 -0
  7. package/dist/cli/commands/create.d.ts +3 -0
  8. package/dist/cli/commands/create.js +13 -0
  9. package/dist/cli/commands/doctor.d.ts +3 -0
  10. package/dist/cli/commands/doctor.js +31 -0
  11. package/dist/cli/commands/generate.d.ts +6 -0
  12. package/dist/cli/commands/generate.js +24 -0
  13. package/dist/cli/commands/operations.d.ts +12 -0
  14. package/dist/cli/commands/operations.js +61 -0
  15. package/dist/cli/commands/schema.d.ts +11 -0
  16. package/dist/cli/commands/schema.js +1086 -0
  17. package/dist/cli/commands/serve.d.ts +9 -0
  18. package/dist/cli/commands/serve.js +18 -0
  19. package/dist/cli/commands/sync.d.ts +3 -0
  20. package/dist/cli/commands/sync.js +11 -0
  21. package/dist/cli/commands/types.d.ts +7 -0
  22. package/dist/cli/commands/types.js +37 -0
  23. package/dist/cli/commands/viewer.d.ts +6 -0
  24. package/dist/cli/commands/viewer.js +29 -0
  25. package/dist/cli/index.d.ts +2 -0
  26. package/dist/cli/index.js +108 -0
  27. package/dist/cli/output.d.ts +25 -0
  28. package/dist/cli/output.js +149 -0
  29. package/dist/cli/schema-prompt.d.ts +20 -0
  30. package/dist/cli/schema-prompt.js +66 -0
  31. package/dist/cli.d.ts +2 -0
  32. package/dist/cli.js +3 -0
  33. package/dist/client-cache.d.ts +105 -0
  34. package/dist/client-cache.js +916 -0
  35. package/dist/client.d.ts +64 -0
  36. package/dist/client.js +405 -0
  37. package/dist/config-public.d.ts +1 -0
  38. package/dist/config-public.js +1 -0
  39. package/dist/config.d.ts +54 -0
  40. package/dist/config.js +2 -0
  41. package/dist/csv.d.ts +1 -0
  42. package/dist/csv.js +1 -0
  43. package/dist/db.d.ts +3 -0
  44. package/dist/db.js +3 -0
  45. package/dist/doctor.d.ts +1 -0
  46. package/dist/doctor.js +1 -0
  47. package/dist/errors.d.ts +1 -0
  48. package/dist/errors.js +1 -0
  49. package/dist/features/config/defaults.d.ts +98 -0
  50. package/dist/features/config/defaults.js +95 -0
  51. package/dist/features/config/load.d.ts +11 -0
  52. package/dist/features/config/load.js +265 -0
  53. package/dist/features/config/public.d.ts +17 -0
  54. package/dist/features/config/public.js +75 -0
  55. package/dist/features/doctor/duplicate-ids.d.ts +18 -0
  56. package/dist/features/doctor/duplicate-ids.js +79 -0
  57. package/dist/features/doctor/field-consistency.d.ts +17 -0
  58. package/dist/features/doctor/field-consistency.js +48 -0
  59. package/dist/features/doctor/index.d.ts +39 -0
  60. package/dist/features/doctor/index.js +177 -0
  61. package/dist/features/doctor/relations.d.ts +22 -0
  62. package/dist/features/doctor/relations.js +90 -0
  63. package/dist/features/doctor/schema-guidance.d.ts +35 -0
  64. package/dist/features/doctor/schema-guidance.js +184 -0
  65. package/dist/features/generate/registry.d.ts +14 -0
  66. package/dist/features/generate/registry.js +37 -0
  67. package/dist/features/http/registry.d.ts +46 -0
  68. package/dist/features/http/registry.js +86 -0
  69. package/dist/features/operations/index.d.ts +49 -0
  70. package/dist/features/operations/index.js +199 -0
  71. package/dist/features/operations/maps.d.ts +1 -0
  72. package/dist/features/operations/maps.js +10 -0
  73. package/dist/features/operations/readiness.d.ts +30 -0
  74. package/dist/features/operations/readiness.js +228 -0
  75. package/dist/features/operations/runtime.d.ts +57 -0
  76. package/dist/features/operations/runtime.js +288 -0
  77. package/dist/features/runtime/collection.d.ts +51 -0
  78. package/dist/features/runtime/collection.js +198 -0
  79. package/dist/features/runtime/db.d.ts +152 -0
  80. package/dist/features/runtime/db.js +824 -0
  81. package/dist/features/runtime/document.d.ts +43 -0
  82. package/dist/features/runtime/document.js +111 -0
  83. package/dist/features/runtime/fanout.d.ts +24 -0
  84. package/dist/features/runtime/fanout.js +77 -0
  85. package/dist/features/runtime/json-pointer.d.ts +5 -0
  86. package/dist/features/runtime/json-pointer.js +49 -0
  87. package/dist/features/runtime/scope-state.d.ts +44 -0
  88. package/dist/features/runtime/scope-state.js +185 -0
  89. package/dist/features/runtime/state.d.ts +1 -0
  90. package/dist/features/runtime/state.js +1 -0
  91. package/dist/features/schema/api.d.ts +107 -0
  92. package/dist/features/schema/api.js +460 -0
  93. package/dist/features/schema/builders.d.ts +86 -0
  94. package/dist/features/schema/builders.js +110 -0
  95. package/dist/features/schema/fields.d.ts +38 -0
  96. package/dist/features/schema/fields.js +296 -0
  97. package/dist/features/schema/generated.d.ts +29 -0
  98. package/dist/features/schema/generated.js +32 -0
  99. package/dist/features/schema/locator.d.ts +16 -0
  100. package/dist/features/schema/locator.js +135 -0
  101. package/dist/features/schema/manifest.d.ts +91 -0
  102. package/dist/features/schema/manifest.js +384 -0
  103. package/dist/features/schema/metadata.d.ts +30 -0
  104. package/dist/features/schema/metadata.js +75 -0
  105. package/dist/features/schema/project.d.ts +46 -0
  106. package/dist/features/schema/project.js +442 -0
  107. package/dist/features/schema/relations.d.ts +38 -0
  108. package/dist/features/schema/relations.js +109 -0
  109. package/dist/features/schema/resolvers.d.ts +36 -0
  110. package/dist/features/schema/resolvers.js +111 -0
  111. package/dist/features/schema/resource.d.ts +75 -0
  112. package/dist/features/schema/resource.js +253 -0
  113. package/dist/features/schema/source-definitions.d.ts +21 -0
  114. package/dist/features/schema/source-definitions.js +29 -0
  115. package/dist/features/schema/sources.d.ts +83 -0
  116. package/dist/features/schema/sources.js +689 -0
  117. package/dist/features/schema/standard-schema.d.ts +57 -0
  118. package/dist/features/schema/standard-schema.js +232 -0
  119. package/dist/features/schema/validation.d.ts +69 -0
  120. package/dist/features/schema/validation.js +434 -0
  121. package/dist/features/storage/events.d.ts +12 -0
  122. package/dist/features/storage/events.js +30 -0
  123. package/dist/features/storage/json.d.ts +112 -0
  124. package/dist/features/storage/json.js +239 -0
  125. package/dist/features/storage/memory.d.ts +30 -0
  126. package/dist/features/storage/memory.js +44 -0
  127. package/dist/features/storage/resource-json.d.ts +31 -0
  128. package/dist/features/storage/resource-json.js +76 -0
  129. package/dist/features/storage/runtime.d.ts +37 -0
  130. package/dist/features/storage/runtime.js +184 -0
  131. package/dist/features/storage/source-metadata.d.ts +20 -0
  132. package/dist/features/storage/source-metadata.js +25 -0
  133. package/dist/features/storage/source.d.ts +37 -0
  134. package/dist/features/storage/source.js +60 -0
  135. package/dist/features/storage/static.d.ts +29 -0
  136. package/dist/features/storage/static.js +42 -0
  137. package/dist/features/sync/defaults.d.ts +21 -0
  138. package/dist/features/sync/defaults.js +21 -0
  139. package/dist/features/sync/index.d.ts +35 -0
  140. package/dist/features/sync/index.js +85 -0
  141. package/dist/features/sync/mirror-state.d.ts +14 -0
  142. package/dist/features/sync/mirror-state.js +4 -0
  143. package/dist/features/sync/runtime-dirs.d.ts +5 -0
  144. package/dist/features/sync/runtime-dirs.js +9 -0
  145. package/dist/features/sync/source-writes.d.ts +15 -0
  146. package/dist/features/sync/source-writes.js +27 -0
  147. package/dist/features/sync/synthetic-seed.d.ts +26 -0
  148. package/dist/features/sync/synthetic-seed.js +83 -0
  149. package/dist/features/viewer/manifest.d.ts +148 -0
  150. package/dist/features/viewer/manifest.js +165 -0
  151. package/dist/fs-utils.d.ts +1 -0
  152. package/dist/fs-utils.js +1 -0
  153. package/dist/generate/hono/app.d.ts +6 -0
  154. package/dist/generate/hono/app.js +51 -0
  155. package/dist/generate/hono/graphql.d.ts +7 -0
  156. package/dist/generate/hono/graphql.js +53 -0
  157. package/dist/generate/hono/index.d.ts +55 -0
  158. package/dist/generate/hono/index.js +140 -0
  159. package/dist/generate/hono/package.d.ts +6 -0
  160. package/dist/generate/hono/package.js +44 -0
  161. package/dist/generate/hono/readme.d.ts +13 -0
  162. package/dist/generate/hono/readme.js +28 -0
  163. package/dist/generate/hono/repository.d.ts +1 -0
  164. package/dist/generate/hono/repository.js +27 -0
  165. package/dist/generate/hono/rest.d.ts +1 -0
  166. package/dist/generate/hono/rest.js +38 -0
  167. package/dist/generate/hono/schema.d.ts +13 -0
  168. package/dist/generate/hono/schema.js +18 -0
  169. package/dist/generate/hono/sqlite.d.ts +20 -0
  170. package/dist/generate/hono/sqlite.js +266 -0
  171. package/dist/generate/hono/validators.d.ts +1 -0
  172. package/dist/generate/hono/validators.js +141 -0
  173. package/dist/generate/hono.d.ts +1 -0
  174. package/dist/generate/hono.js +1 -0
  175. package/dist/graphql/execute.d.ts +14 -0
  176. package/dist/graphql/execute.js +719 -0
  177. package/dist/graphql/http.d.ts +15 -0
  178. package/dist/graphql/http.js +29 -0
  179. package/dist/graphql/index.d.ts +3 -0
  180. package/dist/graphql/index.js +3 -0
  181. package/dist/graphql/parser.d.ts +54 -0
  182. package/dist/graphql/parser.js +433 -0
  183. package/dist/hono.d.ts +77 -0
  184. package/dist/hono.js +1 -0
  185. package/dist/index.d.ts +1065 -0
  186. package/dist/index.js +14 -0
  187. package/dist/integrations/hono.d.ts +136 -0
  188. package/dist/integrations/hono.js +508 -0
  189. package/dist/integrations/kv.d.ts +69 -0
  190. package/dist/integrations/kv.js +69 -0
  191. package/dist/integrations/postgres.d.ts +52 -0
  192. package/dist/integrations/postgres.js +113 -0
  193. package/dist/integrations/sqlite.d.ts +112 -0
  194. package/dist/integrations/sqlite.js +489 -0
  195. package/dist/integrations/vite.d.ts +45 -0
  196. package/dist/integrations/vite.js +111 -0
  197. package/dist/json.d.ts +48 -0
  198. package/dist/json.js +1 -0
  199. package/dist/jsonc.d.ts +1 -0
  200. package/dist/jsonc.js +1 -0
  201. package/dist/kv.d.ts +24 -0
  202. package/dist/kv.js +1 -0
  203. package/dist/mock.d.ts +1 -0
  204. package/dist/mock.js +1 -0
  205. package/dist/names.d.ts +1 -0
  206. package/dist/names.js +1 -0
  207. package/dist/operations.d.ts +3 -0
  208. package/dist/operations.js +3 -0
  209. package/dist/postgres.d.ts +24 -0
  210. package/dist/postgres.js +1 -0
  211. package/dist/redis.d.ts +14 -0
  212. package/dist/redis.js +1 -0
  213. package/dist/rest/formats.d.ts +80 -0
  214. package/dist/rest/formats.js +318 -0
  215. package/dist/rest/handler.d.ts +111 -0
  216. package/dist/rest/handler.js +833 -0
  217. package/dist/rest/shape.d.ts +33 -0
  218. package/dist/rest/shape.js +218 -0
  219. package/dist/schema-builders.d.ts +1 -0
  220. package/dist/schema-builders.js +1 -0
  221. package/dist/schema-manifest.d.ts +1 -0
  222. package/dist/schema-manifest.js +1 -0
  223. package/dist/schema.d.ts +193 -0
  224. package/dist/schema.js +6 -0
  225. package/dist/server.d.ts +116 -0
  226. package/dist/server.js +601 -0
  227. package/dist/shared/csv.d.ts +8 -0
  228. package/dist/shared/csv.js +149 -0
  229. package/dist/shared/errors.d.ts +40 -0
  230. package/dist/shared/errors.js +55 -0
  231. package/dist/shared/fs-utils.d.ts +4 -0
  232. package/dist/shared/fs-utils.js +30 -0
  233. package/dist/shared/jsonc.d.ts +2 -0
  234. package/dist/shared/jsonc.js +99 -0
  235. package/dist/shared/mock.d.ts +40 -0
  236. package/dist/shared/mock.js +83 -0
  237. package/dist/shared/names.d.ts +28 -0
  238. package/dist/shared/names.js +127 -0
  239. package/dist/shared/operations.d.ts +32 -0
  240. package/dist/shared/operations.js +302 -0
  241. package/dist/sqlite.d.ts +24 -0
  242. package/dist/sqlite.js +1 -0
  243. package/dist/state.d.ts +1 -0
  244. package/dist/state.js +1 -0
  245. package/dist/sync.d.ts +1 -0
  246. package/dist/sync.js +1 -0
  247. package/dist/tracing.d.ts +95 -0
  248. package/dist/tracing.js +260 -0
  249. package/dist/types.d.ts +51 -0
  250. package/dist/types.js +285 -0
  251. package/dist/viewer-manifest.d.ts +1 -0
  252. package/dist/viewer-manifest.js +1 -0
  253. package/dist/vite.d.ts +59 -0
  254. package/dist/vite.js +1 -0
  255. package/dist/web/json-viewer.d.ts +5 -0
  256. package/dist/web/json-viewer.js +176 -0
  257. package/dist/web/viewer.d.ts +12 -0
  258. package/dist/web/viewer.js +1015 -0
  259. package/docs/README.md +42 -0
  260. package/docs/architecture.md +112 -0
  261. package/docs/ci-and-release.md +177 -0
  262. package/docs/cms-storage-patterns.md +108 -0
  263. package/docs/concepts.md +141 -0
  264. package/docs/configuration.md +552 -0
  265. package/docs/fixtures-and-schemas.md +527 -0
  266. package/docs/fork-branch-workflows.md +108 -0
  267. package/docs/generated-files.md +174 -0
  268. package/docs/getting-started.md +165 -0
  269. package/docs/integrations.md +206 -0
  270. package/docs/json-production.md +120 -0
  271. package/docs/package-api.md +418 -0
  272. package/docs/prototype-to-production.md +378 -0
  273. package/docs/server-and-viewer.md +466 -0
  274. package/docs/store-graduation.md +120 -0
  275. package/docs/typescript-schema-sources.md +79 -0
  276. package/examples/advanced/README.md +55 -0
  277. package/examples/advanced/db/projects.schema.jsonc +44 -0
  278. package/examples/advanced/db/settings.jsonc +9 -0
  279. package/examples/advanced/db/users.json +23 -0
  280. package/examples/advanced/db/users.schema.mjs +31 -0
  281. package/examples/advanced/db.config.mjs +18 -0
  282. package/examples/advanced/example.json +5 -0
  283. package/examples/advanced/src/generated/db.types.d.ts +64 -0
  284. package/examples/basic/README.md +95 -0
  285. package/examples/basic/db/operations/get-user.jsonc +8 -0
  286. package/examples/basic/db/settings.json +7 -0
  287. package/examples/basic/db/users.schema.jsonc +36 -0
  288. package/examples/basic/db.config.mjs +68 -0
  289. package/examples/basic/example.json +5 -0
  290. package/examples/basic/src/generated/db.types.d.ts +39 -0
  291. package/examples/cms-json-publish/README.md +21 -0
  292. package/examples/cms-json-publish/db/navigation.json +7 -0
  293. package/examples/cms-json-publish/db/pages.json +18 -0
  294. package/examples/cms-json-publish/example.json +5 -0
  295. package/examples/cms-json-publish/src/cms.mjs +104 -0
  296. package/examples/computed-fields/README.md +93 -0
  297. package/examples/computed-fields/db/orders.schema.mjs +62 -0
  298. package/examples/computed-fields/db/posts.schema.mjs +59 -0
  299. package/examples/computed-fields/db/products.schema.mjs +39 -0
  300. package/examples/computed-fields/db/users.schema.mjs +43 -0
  301. package/examples/computed-fields/db.config.mjs +15 -0
  302. package/examples/computed-fields/example.json +5 -0
  303. package/examples/computed-fields/src/generated/db.types.d.ts +81 -0
  304. package/examples/content-collections/README.md +91 -0
  305. package/examples/content-collections/db/authors.json +12 -0
  306. package/examples/content-collections/db/authors.schema.mjs +20 -0
  307. package/examples/content-collections/db/blog/draft-roadmap.mdx +12 -0
  308. package/examples/content-collections/db/blog/index.schema.mjs +61 -0
  309. package/examples/content-collections/db/blog/launch-notes.mdx +15 -0
  310. package/examples/content-collections/db/docs/index.schema.mjs +32 -0
  311. package/examples/content-collections/db/docs/intro.mdx +11 -0
  312. package/examples/content-collections/db/docs/schema-workflow.mdx +10 -0
  313. package/examples/content-collections/db/site.schema.jsonc +21 -0
  314. package/examples/content-collections/db.config.mjs +26 -0
  315. package/examples/content-collections/example.json +5 -0
  316. package/examples/content-collections/src/content-preview.mjs +66 -0
  317. package/examples/content-collections/src/generated/db.types.d.ts +81 -0
  318. package/examples/csv/README.md +52 -0
  319. package/examples/csv/db/customers.csv +4 -0
  320. package/examples/csv/db.config.mjs +13 -0
  321. package/examples/csv/example.json +5 -0
  322. package/examples/data-first/README.md +54 -0
  323. package/examples/data-first/db/posts.json +16 -0
  324. package/examples/data-first/db/settings.json +8 -0
  325. package/examples/data-first/db/users.json +14 -0
  326. package/examples/data-first/db.config.mjs +13 -0
  327. package/examples/data-first/example.json +5 -0
  328. package/examples/diagnostics/README.md +55 -0
  329. package/examples/diagnostics/db/projects.schema.jsonc +27 -0
  330. package/examples/diagnostics/db/users.json +9 -0
  331. package/examples/diagnostics/db/users.schema.jsonc +23 -0
  332. package/examples/diagnostics/db.config.mjs +16 -0
  333. package/examples/diagnostics/example.json +5 -0
  334. package/examples/free-plan-upgrade/README.md +22 -0
  335. package/examples/free-plan-upgrade/db/appSettings.json +4 -0
  336. package/examples/free-plan-upgrade/db/projects.json +7 -0
  337. package/examples/free-plan-upgrade/example.json +5 -0
  338. package/examples/free-plan-upgrade/src/upgrade-tenant-to-paid.mjs +105 -0
  339. package/examples/hono-auth/README.md +74 -0
  340. package/examples/hono-auth/db/pages.schema.jsonc +44 -0
  341. package/examples/hono-auth/db/users.schema.jsonc +42 -0
  342. package/examples/hono-auth/db.config.mjs +17 -0
  343. package/examples/hono-auth/example.json +5 -0
  344. package/examples/hono-auth/package.json +14 -0
  345. package/examples/hono-auth/src/app.mjs +79 -0
  346. package/examples/hono-auth/src/server.mjs +13 -0
  347. package/examples/production-json/README.md +102 -0
  348. package/examples/production-json/db/appSettings.schema.jsonc +41 -0
  349. package/examples/production-json/db/featureFlags.schema.jsonc +84 -0
  350. package/examples/production-json/db/operations/get-control-plane.jsonc +6 -0
  351. package/examples/production-json/db/operations/get-feature-flag.jsonc +9 -0
  352. package/examples/production-json/db/operations/list-feature-flags.jsonc +8 -0
  353. package/examples/production-json/db/operations/read-public-settings.jsonc +8 -0
  354. package/examples/production-json/db.config.mjs +33 -0
  355. package/examples/production-json/example.json +5 -0
  356. package/examples/production-json/src/client-demo.mjs +28 -0
  357. package/examples/production-json/src/generated/db.types.d.ts +60 -0
  358. package/examples/relations/README.md +56 -0
  359. package/examples/relations/db/posts.schema.jsonc +46 -0
  360. package/examples/relations/db/users.schema.jsonc +34 -0
  361. package/examples/relations/db.config.mjs +13 -0
  362. package/examples/relations/example.json +5 -0
  363. package/examples/rest-client/README.md +54 -0
  364. package/examples/rest-client/db/settings.json +5 -0
  365. package/examples/rest-client/db/users.schema.jsonc +42 -0
  366. package/examples/rest-client/db.config.mjs +13 -0
  367. package/examples/rest-client/example.json +5 -0
  368. package/examples/rest-client/src/client-demo.mjs +24 -0
  369. package/examples/schema-first/README.md +55 -0
  370. package/examples/schema-first/db/auditEvents.schema.jsonc +24 -0
  371. package/examples/schema-first/db/settings.schema.jsonc +29 -0
  372. package/examples/schema-first/db/users.schema.jsonc +36 -0
  373. package/examples/schema-first/db.config.mjs +15 -0
  374. package/examples/schema-first/example.json +5 -0
  375. package/examples/schema-first/src/generated/db.types.d.ts +47 -0
  376. package/examples/schema-manifest/README.md +50 -0
  377. package/examples/schema-manifest/db/projects.schema.jsonc +48 -0
  378. package/examples/schema-manifest/db/users.schema.jsonc +35 -0
  379. package/examples/schema-manifest/db.config.mjs +41 -0
  380. package/examples/schema-manifest/example.json +5 -0
  381. package/examples/schema-manifest/src/generated/db.schema.json +130 -0
  382. package/examples/schema-manifest/src/generated/db.types.d.ts +50 -0
  383. package/examples/schema-ui/README.md +103 -0
  384. package/examples/schema-ui/db/pages.schema.jsonc +53 -0
  385. package/examples/schema-ui/db/users.schema.jsonc +30 -0
  386. package/examples/schema-ui/db.config.mjs +55 -0
  387. package/examples/schema-ui/example.json +5 -0
  388. package/examples/schema-ui/src/cms-ssr.mjs +276 -0
  389. package/examples/schema-ui/src/generated/db.schema.json +133 -0
  390. package/examples/schema-ui/src/generated/db.types.d.ts +46 -0
  391. package/examples/schema-ui/src/render-admin.mjs +175 -0
  392. package/examples/schema-ui/src/schema-ui-ssr-handler.mjs +149 -0
  393. package/examples/schema-ui/src/start-schema-ui-server.mjs +140 -0
  394. package/examples/standard-schema/README.md +55 -0
  395. package/examples/standard-schema/db/settings.schema.mjs +22 -0
  396. package/examples/standard-schema/db/users.schema.mjs +72 -0
  397. package/examples/standard-schema/example.json +5 -0
  398. package/package.json +108 -0
@@ -0,0 +1,552 @@
1
+ # Configuration
2
+
3
+ Most projects can skip `db.config.mjs` at first. Add config when defaults stop matching the project.
4
+
5
+ Use `defineConfig` for editor autocomplete and inline type checks:
6
+
7
+ ```js
8
+ // @ts-check
9
+ import { defineConfig } from '@async/db/config';
10
+
11
+ export default defineConfig({
12
+ stores: {
13
+ default: 'json',
14
+ },
15
+ mock: {
16
+ delay: [30, 100],
17
+ },
18
+ });
19
+ ```
20
+
21
+ See [db.config.example.mjs](../db.config.example.mjs) for a commented config with common values.
22
+
23
+ ## Config Map
24
+
25
+ | Need | Default | Configure |
26
+ | --- | --- | --- |
27
+ | Fixture folder | `./db` | `dbDir` |
28
+ | Custom source formats | Built-in readers | `sources.readers` |
29
+ | Nested resource names | Fixture basename | `resources.naming` or `resources.customizeResource` |
30
+ | Runtime store behavior | JSON files under `.db/state` | `stores.default` or `resources.<name>.store` |
31
+ | Index intent metadata | Off | `resources.<name>.indexes` |
32
+ | Generated output paths | `.db`, `.db/types/index.d.ts` | `outputs` |
33
+ | Importable generated types | Off | `outputs.committedTypes` |
34
+ | Importable schema manifest | Off | `outputs.schemaManifest` |
35
+ | Importable viewer manifest | Off | `outputs.viewerManifest` |
36
+ | Registered query operation refs | Off | `operations` |
37
+ | REST response formats | `.json`, `.html`, `.md` | `rest.formats` |
38
+ | App-facing data route base | `/db` | `server.dataPath` |
39
+ | Route exposure policy | Open | `server.expose` |
40
+ | Unknown fields | Warn | `schema.unknownFields` |
41
+ | Standard Schema-first output | Off | `schema.standardSchema` |
42
+ | Schema defaults | Create and safe hydration | `defaults` |
43
+ | Schema-only mock records | Off | `seed.generateFromSchema` |
44
+ | Local latency | `30-100ms` | `mock.delay` |
45
+ | Random local failures | Off | `mock.errors` |
46
+ | GraphQL endpoint | `/graphql`, enabled | `graphql` |
47
+ | Host, port, dev-tool route base, body limit | `127.0.0.1:7331`, `/__db`, 1 MB bodies | `server` |
48
+
49
+ ## Full Example
50
+
51
+ ```js
52
+ // @ts-check
53
+ import { defineConfig } from '@async/db/config';
54
+
55
+ export default defineConfig({
56
+ dbDir: './db',
57
+
58
+ outputs: {
59
+ stateDir: './.db',
60
+ types: './.db/types/index.d.ts',
61
+ committedTypes: './src/generated/db.types.d.ts',
62
+ schemaManifest: './src/generated/db.schema.json',
63
+ viewerManifest: './src/generated/db.viewer.json',
64
+ operationRegistry: './src/generated/db.operations.json',
65
+ operationRefs: './src/generated/db.operation-refs.json',
66
+ },
67
+
68
+ sources: {
69
+ writePolicy: 'preserve',
70
+ readers: [],
71
+ },
72
+
73
+ stores: {
74
+ default: 'json',
75
+ },
76
+
77
+ types: {
78
+ enabled: true,
79
+ useReadonly: false,
80
+ emitComments: true,
81
+ },
82
+
83
+ schema: {
84
+ standardSchema: false,
85
+ unknownFields: 'warn',
86
+ },
87
+
88
+ defaults: {
89
+ applyOnCreate: true,
90
+ applyOnSafeMigration: true,
91
+ },
92
+
93
+ seed: {
94
+ generateFromSchema: false,
95
+ generatedCount: 5,
96
+ },
97
+
98
+ server: {
99
+ apiBase: '/__db',
100
+ dataPath: '/db',
101
+ host: '127.0.0.1',
102
+ port: 7331,
103
+ maxBodyBytes: 1048576,
104
+ expose: {
105
+ rest: 'open',
106
+ graphql: 'open',
107
+ viewer: 'dev',
108
+ schema: 'dev',
109
+ manifest: 'dev',
110
+ },
111
+ viewerLinks: [
112
+ { label: 'App Data Viewer', href: 'http://127.0.0.1:5173/db' },
113
+ ],
114
+ },
115
+
116
+ operations: {
117
+ enabled: false,
118
+ sourceDir: './db/operations',
119
+ acceptRefs: 'both',
120
+ },
121
+
122
+ rest: {
123
+ enabled: true,
124
+ formats: {
125
+ default: 'json',
126
+ md({ resourceName, data }) {
127
+ return {
128
+ body: `# ${resourceName}\n\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\`\n`,
129
+ contentType: 'text/markdown; charset=utf-8',
130
+ };
131
+ },
132
+ // yaml: {
133
+ // mediaTypes: ['application/yaml', 'text/yaml'],
134
+ // contentType: 'application/yaml; charset=utf-8',
135
+ // render({ data }) {
136
+ // return stringifyYaml(data);
137
+ // },
138
+ // },
139
+ },
140
+ },
141
+
142
+ graphql: {
143
+ enabled: true,
144
+ path: '/graphql',
145
+ },
146
+
147
+ mock: {
148
+ delay: [30, 100],
149
+ errors: null,
150
+ },
151
+
152
+ });
153
+ ```
154
+
155
+ ## Fixture Folder
156
+
157
+ Use `dbDir` when fixtures live somewhere other than `./db`:
158
+
159
+ ```js
160
+ import { defineConfig } from '@async/db/config';
161
+
162
+ export default defineConfig({
163
+ dbDir: './db',
164
+ });
165
+ ```
166
+
167
+ Existing `sourceDir` configs still work; `dbDir` is the shorter fixture-folder name. If both are provided, `sourceDir` wins for backwards compatibility.
168
+
169
+ ## Source And Store Binding
170
+
171
+ Source fixtures and runtime persistence are separate concerns. By default, source fixtures stay unchanged and app writes go to the generated JSON store under `.db/state`.
172
+
173
+ Use `resources.<name>.store` to bind a resource to a different store:
174
+
175
+ ```js
176
+ import { defineConfig } from '@async/db/config';
177
+
178
+ export default defineConfig({
179
+ stores: {
180
+ default: 'json',
181
+ },
182
+ resources: {
183
+ users: { store: 'sourceFile' },
184
+ activityEvents: {
185
+ store: 'json',
186
+ indexes: [
187
+ { fields: ['observedAt'] },
188
+ { fields: ['domain', 'observedAt'] },
189
+ ],
190
+ },
191
+ },
192
+ });
193
+ ```
194
+
195
+ The `sourceFile` store is intentionally narrow. It is only for resources where supported writebacks should update plain `.json` source fixtures. JSONC and CSV sources remain source inputs and still hydrate runtime state.
196
+
197
+ `indexes` is metadata for store selection, generated tooling, and `doctor` scale warnings. The default JSON store does not build physical indexes.
198
+
199
+ Optional database stores keep the same fixture/schema workflow while moving
200
+ runtime persistence out of `.db/state`. They store whole resources as JSON
201
+ values in v1, so package API, REST, GraphQL, defaults, and source-hash refresh
202
+ behavior stay the same:
203
+
204
+ ```js
205
+ import { defineConfig } from '@async/db/config';
206
+ import { postgresStore } from '@async/db/postgres';
207
+ import { redisStore } from '@async/db/redis';
208
+
209
+ export default defineConfig({
210
+ resources: {
211
+ users: { store: 'postgres' },
212
+ sessions: { store: 'redis' },
213
+ },
214
+ stores: {
215
+ postgres: postgresStore({ client: pgPool }),
216
+ redis: redisStore({ client: redisClient, prefix: 'my-app:' }),
217
+ },
218
+ });
219
+ ```
220
+
221
+ The package does not install database clients for you. Pass a `pg` Pool/Client
222
+ or compatible object to `postgresStore({ client })`, and pass a Redis-like,
223
+ edge KV, Valkey, Dragonfly, or compatible object with `get(key)` and
224
+ `set(key, value)` to `kvStore()` or `redisStore()`.
225
+
226
+ ## Schema Strictness
227
+
228
+ Unknown fields in schema-backed data warn by default. Use strict checks when fixture drift should fail:
229
+
230
+ ```js
231
+ import { defineConfig } from '@async/db/config';
232
+
233
+ export default defineConfig({
234
+ schema: {
235
+ unknownFields: 'error',
236
+ },
237
+ });
238
+ ```
239
+
240
+ Keep the default `warn` while fixture shape is still changing.
241
+
242
+ ## Schema JavaScript Modules
243
+
244
+ `.schema.js` files are loaded as ESM. If the project root is not already `"type": "module"`, @async/db creates `db/package.json` with `"type": "module"` before loading schema files inside the fixture folder. Aggregate unbundle uses the same rule: it prefers generated `.schema.js` files under `db/`, then falls back to `.schema.mjs` when the marker is disabled or a custom output folder cannot be loaded as ESM.
245
+
246
+ Disable that marker when you manage fixture-folder package metadata yourself:
247
+
248
+ ```js
249
+ import { defineConfig } from '@async/db/config';
250
+
251
+ export default defineConfig({
252
+ schema: {
253
+ autoModulePackageJson: false,
254
+ },
255
+ });
256
+ ```
257
+
258
+ ## Standard Schema Output
259
+
260
+ @async/db detects Standard Schema validators by shape without installing a
261
+ validator dependency. Set `schema.standardSchema: true` when generated
262
+ executable schema files should prefer the validator-first authoring form for
263
+ resources that have a Standard Schema validator:
264
+
265
+ ```js
266
+ import { defineConfig } from '@async/db/config';
267
+
268
+ export default defineConfig({
269
+ schema: {
270
+ standardSchema: true,
271
+ },
272
+ });
273
+ ```
274
+
275
+ With that option, aggregate bundle/unbundle output can emit
276
+ `collection(UserSchema, { fields })` or `document(SettingsSchema, { fields })`
277
+ for Standard Schema-backed resources. Resources without a validator keep the
278
+ normal Async DB-first shape.
279
+
280
+ ## Schema Defaults
281
+
282
+ Schema defaults apply when creating collection records through the package API, REST, GraphQL, SQLite adapter, and generated Hono SQLite starter. Updates, patches, and document puts preserve omitted fields instead of backfilling defaults; include a field in the write body when you want to change it.
283
+
284
+ Safe runtime hydration also applies defaults to additive store migrations by default. Disable that separately when existing runtime records should remain untouched:
285
+
286
+ ```js
287
+ import { defineConfig } from '@async/db/config';
288
+
289
+ export default defineConfig({
290
+ defaults: {
291
+ applyOnCreate: true,
292
+ applyOnSafeMigration: false,
293
+ },
294
+ });
295
+ ```
296
+
297
+ ## Generated Schema Seed Data
298
+
299
+ Generate mock runtime records for schema-only resources with empty seed data:
300
+
301
+ ```js
302
+ import { defineConfig } from '@async/db/config';
303
+
304
+ export default defineConfig({
305
+ seed: {
306
+ generateFromSchema: true,
307
+ generatedCount: 5,
308
+ },
309
+ });
310
+ ```
311
+
312
+ Data files in `db/*.json`, `db/*.jsonc`, and `db/*.csv` remain the source of truth when present.
313
+
314
+ ## Mock Delay And Errors
315
+
316
+ @async/db delays local responses by `30-100ms` by default. Use `0` to disable delay, a number for fixed delay, or a tuple for a range.
317
+
318
+ ```js
319
+ import { defineConfig } from '@async/db/config';
320
+
321
+ export default defineConfig({
322
+ mock: {
323
+ delay: [50, 300],
324
+ errors: {
325
+ rate: 0.05,
326
+ status: 503,
327
+ message: 'Random local mock failure',
328
+ },
329
+ },
330
+ });
331
+ ```
332
+
333
+ Random errors stay off by default. Turn them on when testing retries and error UI.
334
+
335
+ ## Server Options
336
+
337
+ Use `server` for a different host, port, dev-tool route base, or JSON body limit:
338
+
339
+ ```js
340
+ import { defineConfig } from '@async/db/config';
341
+
342
+ export default defineConfig({
343
+ server: {
344
+ apiBase: '/__db',
345
+ dataPath: '/db',
346
+ host: '127.0.0.1',
347
+ port: 7331,
348
+ maxBodyBytes: 1048576,
349
+ },
350
+ });
351
+ ```
352
+
353
+ `server.apiBase` scopes the standalone viewer and internal development routes:
354
+ viewer, schema, batch, import, live events, and runtime log. REST
355
+ resources such as `/users` and the standalone GraphQL path stay unchanged unless
356
+ you configure those surfaces separately.
357
+
358
+ `server.dataPath` scopes the app-facing REST resource alias. It defaults to
359
+ `/db`, so `db/users.json` is available at `GET /db/users.json`. Set it to
360
+ `false` to disable the alias and use scoped REST under `/__db/rest` plus
361
+ standalone root REST routes.
362
+
363
+ ### Request Tracing
364
+
365
+ Request tracing is opt-in and safe for local debugging. It records handled DB
366
+ HTTP requests, phase timings, route/resource/operation metadata, slow status,
367
+ and hook short-circuit metadata when available. It records query keys only, not
368
+ query values, request bodies, response bodies, cookie headers, or authorization
369
+ headers.
370
+
371
+ ```js
372
+ import { defineConfig } from '@async/db/config';
373
+
374
+ export default defineConfig({
375
+ server: {
376
+ trace: {
377
+ enabled: true,
378
+ slowMs: 100,
379
+ console: true,
380
+ events: true,
381
+ header: 'x-async-db-request-id',
382
+ },
383
+ },
384
+ });
385
+ ```
386
+
387
+ Use `server.trace: true` to enable tracing with defaults:
388
+ `slowMs: 0`, `console: true`, `events: true`, and
389
+ `header: 'x-async-db-request-id'`. Set `server.trace: false` or omit it to keep
390
+ tracing disabled.
391
+
392
+ Trace events are emitted through the runtime log stream, so `GET /__db/log`
393
+ shows request traces alongside normal resource-change events. Console output is
394
+ compact:
395
+
396
+ ```txt
397
+ [async-db] GET /db/users 200 18ms route=rest resource=users op=list requestId=...
398
+ [async-db:slow] GET /__db/rest/users/u_1 401 122ms route=hono-rest resource=users op=get hook=beforeRequest shortCircuit=true requestId=...
399
+ ```
400
+
401
+ Explicit integration options such as `createDbRequestHandler(db, { trace })`,
402
+ `dbPlugin({ trace })`, `createDbHonoApp({ trace })`, and
403
+ `registerDbRoutes(app, db, { trace })` win over `db.config.mjs`
404
+ `server.trace`.
405
+
406
+ Use `server.expose` when a project wants production-like route hardening.
407
+ `operations.enabled: true` only enables registered operation execution; it does
408
+ not automatically lock down raw REST routes. To make registered operations the
409
+ only data API path, opt into operation-only exposure with
410
+ `server.expose.rest: 'registered-only'`:
411
+
412
+ ```js
413
+ import { defineConfig } from '@async/db/config';
414
+
415
+ export default defineConfig({
416
+ outputs: {
417
+ operationRegistry: './src/generated/db.operations.json',
418
+ operationRefs: './src/generated/db.operation-refs.json',
419
+ },
420
+ operations: {
421
+ enabled: true,
422
+ acceptRefs: 'ref',
423
+ },
424
+ server: {
425
+ expose: {
426
+ rest: 'registered-only',
427
+ graphql: false,
428
+ viewer: 'dev',
429
+ schema: 'dev',
430
+ manifest: 'dev',
431
+ },
432
+ },
433
+ });
434
+ ```
435
+
436
+ Exposure values are `open`, `registered-only`, `dev`, `disabled`, and `false`.
437
+ `dev` routes are available unless `NODE_ENV=production`. `registered-only` is
438
+ not a general hardening switch. For REST it specifically means raw REST resource
439
+ and batch routes are blocked, while `POST /__db/operations/:ref` can still
440
+ execute registered operation templates.
441
+
442
+ When REST exposure is `registered-only`, `async-db doctor` and the built-in
443
+ server require registered operations to be enabled and resolvable through
444
+ `operations.registry`, `operations.resolveRef`, `outputs.operationRegistry` /
445
+ `operations.outFile`, or operation files under `operations.sourceDir`. Missing,
446
+ invalid, or empty operation sources fail early with
447
+ `OPERATIONS_STRICT_MODE_WITHOUT_OPERATIONS`. For public operation-only APIs,
448
+ prefer `operations.acceptRefs: 'ref'`; doctor reports this as non-blocking
449
+ guidance.
450
+
451
+ ## Registered Queries
452
+
453
+ Registered queries are optional allowlisted REST or GraphQL request templates.
454
+ The config and CLI still use the `operations` name. Operation sources live under
455
+ `operations.sourceDir`, which defaults to `./db/operations`. When that folder
456
+ is inside the fixture folder, @async/db reserves it for operation templates and
457
+ does not load it as fixture data. Move it elsewhere by changing
458
+ `operations.sourceDir`.
459
+
460
+ ```txt
461
+ db/operations/get-user.jsonc
462
+ ```
463
+
464
+ ```json
465
+ {
466
+ "name": "GetUser",
467
+ "method": "GET",
468
+ "path": "/users/{id}.json",
469
+ "query": {
470
+ "select": "id,name"
471
+ }
472
+ }
473
+ ```
474
+
475
+ GraphQL templates use the same registry:
476
+
477
+ ```json
478
+ {
479
+ "name": "GetUser",
480
+ "query": "query GetUser($id: ID!) { user(id: $id) { id name } }",
481
+ "operationName": "GetUser",
482
+ "variables": {
483
+ "id": "{id}"
484
+ }
485
+ }
486
+ ```
487
+
488
+ ```bash
489
+ async-db operations build
490
+ ```
491
+
492
+ `outputs.operationRegistry` receives the full server registry with templates.
493
+ `outputs.operationRefs` receives client-safe refs with names and callable refs
494
+ only. The client-exposed surface is just `operations.<name>.name` and
495
+ `operations.<name>.ref`; paths, query templates, variables, request bodies, and
496
+ server registry contents stay out of that client file. Generated refs default
497
+ to `hashOperation(template)` unless the operation source provides an explicit
498
+ `ref`. `operations.acceptRefs` controls which
499
+ identifiers the server accepts by default: `'ref'`, `'name'`, or `'both'`. Use
500
+ `operations.validateRef` or `operations.resolveRef` only when an app-owned
501
+ runtime needs custom server-side policy or a custom registry lookup.
502
+ Manual inline registries can use operation objects or string REST templates,
503
+ for example `{ GetUser: '/users/{id}.json?select=id,name' }`.
504
+ Operation names and refs must be unique; the build fails
505
+ instead of generating client refs that could point at the wrong operation.
506
+ If `outputs.operationRegistry` is missing or invalid at runtime, registered operation
507
+ execution returns `OPERATION_REGISTRY_LOAD_FAILED`; rebuild the registry or fix
508
+ the configured path before treating operation misses as missing refs.
509
+
510
+ ## Production Doctor Checks
511
+
512
+ `async-db doctor --production` adds production-readiness findings for
513
+ JSON-backed resources. It keeps ordinary local prototype checks quiet by
514
+ default, then warns when production JSON resources do not have explicit schema
515
+ files and emits review guidance for keeping JSON-backed production resources
516
+ small, low-write, single-writer, and backed up.
517
+
518
+ Use strict production checks in CI when those warnings should fail:
519
+
520
+ ```bash
521
+ async-db check --strict --production
522
+ ```
523
+
524
+ For CI review, `async-db operations contract` prints a deterministic
525
+ client-exposed contract with `generatedAt` removed. Commit the approved refs or
526
+ contract file, then run:
527
+
528
+ ```bash
529
+ async-db operations contract --check
530
+ ```
531
+
532
+ `--check` compares against `outputs.operationRefs` by default, or against
533
+ `--out <file>` when provided, and fails when the exposed operation names or refs
534
+ change.
535
+
536
+ ## Runtime Forks
537
+
538
+ Runtime forks are package API state, not `db.config.mjs` fixture folders. Use `db.forks.create()`, `db.forks.open()`, `db.forks.ensure()`, branches, snapshots, migrations, and routing when an app needs tenants, previews, debug copies, or upgrade flows.
539
+
540
+ ```js
541
+ const tenant = await db.forks.ensure('tenant_acme', {
542
+ from: 'main',
543
+ metadata: { purpose: 'tenant' },
544
+ });
545
+
546
+ const draft = await tenant.branches.ensure('draft', {
547
+ from: 'main',
548
+ metadata: { purpose: 'draft' },
549
+ });
550
+ ```
551
+
552
+ The old fixture-folder `forks` and `templates` config surfaces were removed so `fork` has one meaning: an isolated logical database instance.