@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,55 @@
1
+ # Advanced Example
2
+
3
+ ## What This Teaches
4
+
5
+ Use this after the basics when you want to see several features working together: mixed-mode fixtures, `.schema.mjs`, defaults, nested objects, and committed generated types.
6
+
7
+ ## Files To Inspect
8
+
9
+ - [db/users.schema.mjs](./db/users.schema.mjs): schema helper API from `@async/db/schema`.
10
+ - [db/users.json](./db/users.json): data seed for the schema-backed `users` collection.
11
+ - [db/projects.schema.jsonc](./db/projects.schema.jsonc): nested object defaults.
12
+ - [src/generated/db.types.d.ts](./src/generated/db.types.d.ts): committed generated types.
13
+
14
+ ## Run It
15
+
16
+ From the repository root, use the repo-internal CLI path:
17
+
18
+ ```bash
19
+ npm run db -- sync --cwd ./examples/advanced
20
+ npm run db -- serve --cwd ./examples/advanced
21
+ ```
22
+
23
+ Open the viewer:
24
+
25
+ ```txt
26
+ http://127.0.0.1:7331/__db
27
+ ```
28
+
29
+ ## Expected Result
30
+
31
+ `sync` loads mixed data and schema sources, applies defaults in the selected runtime store, and writes committed generated types.
32
+
33
+ ## REST Request To Try
34
+
35
+ Leave `serve` running and run this from another terminal:
36
+
37
+ ```bash
38
+ curl 'http://127.0.0.1:7331/db/projects.json?select=id,name,status,metadata'
39
+ ```
40
+
41
+ ## Features To Notice
42
+
43
+ - [JavaScript schema sources](../../docs/fixtures-and-schemas.md#javascript-schema-sources)
44
+ - [Schema defaults](../../docs/configuration.md#schema-defaults)
45
+ - [Fixture-like `.json` REST routes](../../docs/server-and-viewer.md#fixture-like-json-routes)
46
+ - [Generated types](../../docs/generated-files.md#generated-types)
47
+
48
+ ## Cleanup
49
+
50
+ Generated `.db/` output is ignored by git and can be removed whenever you want fresh runtime state.
51
+
52
+ ## More Docs
53
+
54
+ - [Fixtures And Schemas](../../docs/fixtures-and-schemas.md)
55
+ - [Package API](../../docs/package-api.md)
@@ -0,0 +1,44 @@
1
+ {
2
+ "kind": "collection",
3
+ "idField": "id",
4
+ "fields": {
5
+ "id": {
6
+ "type": "string",
7
+ "required": true
8
+ },
9
+ "name": {
10
+ "type": "string",
11
+ "required": true
12
+ },
13
+ "ownerId": {
14
+ "type": "string",
15
+ "required": true
16
+ },
17
+ "status": {
18
+ "type": "enum",
19
+ "values": ["planned", "active", "paused", "done"],
20
+ "default": "planned"
21
+ },
22
+ "metadata": {
23
+ "type": "object",
24
+ "default": {},
25
+ "fields": {
26
+ "priority": {
27
+ "type": "string",
28
+ "default": "normal"
29
+ }
30
+ }
31
+ }
32
+ },
33
+ "seed": [
34
+ {
35
+ "id": "proj_1",
36
+ "name": "Local checkout",
37
+ "ownerId": "u_1",
38
+ "status": "active",
39
+ "metadata": {
40
+ "priority": "high"
41
+ }
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ // Singleton app settings with JSONC comments.
3
+ "theme": "dark",
4
+ "locale": "en-US",
5
+ "features": {
6
+ "billing": true,
7
+ "graphql": true,
8
+ },
9
+ }
@@ -0,0 +1,23 @@
1
+ [
2
+ {
3
+ "id": "u_1",
4
+ "name": "Ada Lovelace",
5
+ "email": "ada@example.com",
6
+ "role": "admin",
7
+ "profile": {
8
+ "title": "Mathematician",
9
+ "location": "London"
10
+ },
11
+ "twitterHandle": "@ada"
12
+ },
13
+ {
14
+ "id": "u_2",
15
+ "name": "Katherine Johnson",
16
+ "email": "katherine@example.com",
17
+ "role": "editor",
18
+ "profile": {
19
+ "title": "Research mathematician",
20
+ "location": "Virginia"
21
+ }
22
+ }
23
+ ]
@@ -0,0 +1,31 @@
1
+ import { collection, field } from '@async/db/schema';
2
+
3
+ export default collection({
4
+ description: 'Users who can sign into the local test app.',
5
+ idField: 'id',
6
+ fields: {
7
+ id: field.string({
8
+ required: true,
9
+ description: 'Stable user id.',
10
+ }),
11
+ name: field.string({
12
+ required: true,
13
+ description: 'Display name shown in the UI.',
14
+ }),
15
+ email: field.string({
16
+ required: true,
17
+ description: 'Unique email address.',
18
+ }),
19
+ role: field.enum(['admin', 'editor', 'user'], {
20
+ default: 'user',
21
+ description: 'Local authorization role.',
22
+ }),
23
+ twitterHandle: field.string({
24
+ description: 'Optional social handle used by local profile demos.',
25
+ }),
26
+ profile: field.object({
27
+ title: field.string({ default: 'Contributor' }),
28
+ location: field.string({ default: 'Remote' }),
29
+ }),
30
+ },
31
+ });
@@ -0,0 +1,18 @@
1
+ // @ts-check
2
+ import { defineConfig } from '@async/db/config';
3
+
4
+ export default defineConfig({
5
+ dbDir: './db',
6
+ outputs: {
7
+ stateDir: './.db',
8
+ types: './.db/types/index.d.ts',
9
+ committedTypes: './src/generated/db.types.d.ts',
10
+ },
11
+ types: {
12
+ enabled: true,
13
+ emitComments: true,
14
+ },
15
+ schema: {
16
+ unknownFields: 'warn',
17
+ },
18
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "Advanced Schema Mix",
3
+ "description": "Mixed data and schema sources, .schema.mjs helpers, defaults, nested objects, and committed generated types.",
4
+ "tags": ["schema-mjs", "mixed-mode", "defaults"]
5
+ }
@@ -0,0 +1,64 @@
1
+ /* eslint-disable */
2
+ // This file is generated by db. Do not edit by hand.
3
+
4
+ export type ProjectStatus =
5
+ | "planned"
6
+ | "active"
7
+ | "paused"
8
+ | "done";
9
+
10
+ export type UserRole = "admin" | "editor" | "user";
11
+
12
+ export type Project = {
13
+ id: string;
14
+ name: string;
15
+ ownerId: string;
16
+ status?: ProjectStatus;
17
+ metadata?: {
18
+ priority?: string;
19
+ };
20
+ };
21
+
22
+ export type Settings = {
23
+ features?: {
24
+ billing?: boolean;
25
+ graphql?: boolean;
26
+ };
27
+ locale?: string;
28
+ theme?: string;
29
+ };
30
+
31
+ /** Users who can sign into the local test app. */
32
+ export type User = {
33
+ /** Stable user id. */
34
+ id: string;
35
+ /** Display name shown in the UI. */
36
+ name: string;
37
+ /** Unique email address. */
38
+ email: string;
39
+ /** Local authorization role. */
40
+ role?: UserRole;
41
+ /** Optional social handle used by local profile demos. */
42
+ twitterHandle?: string;
43
+ profile?: {
44
+ title?: string;
45
+ location?: string;
46
+ };
47
+ };
48
+
49
+ export type DbCollections = {
50
+ projects: Project;
51
+ users: User;
52
+ };
53
+
54
+ export type DbDocuments = {
55
+ settings: Settings;
56
+ };
57
+
58
+ export type DbTypes = {
59
+ collections: DbCollections;
60
+ documents: DbDocuments;
61
+ };
62
+
63
+ export type DbCollectionName = keyof DbCollections;
64
+ export type DbDocumentName = keyof DbDocuments;
@@ -0,0 +1,95 @@
1
+ # Basic Example
2
+
3
+ ## What This Teaches
4
+
5
+ Start here when you want the smallest schema-backed db workflow. It demonstrates sync, committed generated types, the viewer, fixture-like `.json` REST reads, and creating a record.
6
+
7
+ ## Files To Inspect
8
+
9
+ - [db/users.schema.jsonc](./db/users.schema.jsonc): schema-backed collection with seed data.
10
+ - [db/settings.json](./db/settings.json): singleton document inferred from data.
11
+ - [db/operations/get-user.jsonc](./db/operations/get-user.jsonc): optional registered REST operation template.
12
+ - [src/generated/db.types.d.ts](./src/generated/db.types.d.ts): committed generated types.
13
+
14
+ ## Run It
15
+
16
+ From the repository root, use the repo-internal CLI path:
17
+
18
+ ```bash
19
+ npm run db -- sync --cwd ./examples/basic
20
+ npm run db -- operations build --cwd ./examples/basic
21
+ npm run db -- serve --cwd ./examples/basic
22
+ ```
23
+
24
+ Open the viewer:
25
+
26
+ ```txt
27
+ http://127.0.0.1:7331/__db
28
+ ```
29
+
30
+ ## Expected Result
31
+
32
+ `sync` writes generated schema, types, and runtime state under `examples/basic/.db/`, plus the committed type copy in `src/generated/`.
33
+
34
+ `operations build` writes a full server registry and client-safe refs under
35
+ `examples/basic/src/generated/`.
36
+
37
+ To review the browser-facing operation contract without volatile timestamps:
38
+
39
+ ```bash
40
+ npm run db -- operations contract --cwd ./examples/basic
41
+ npm run db -- operations contract --cwd ./examples/basic --check
42
+ ```
43
+
44
+ ## REST Request To Try
45
+
46
+ Leave `serve` running and run this from another terminal:
47
+
48
+ ```bash
49
+ curl http://127.0.0.1:7331/db/users.json
50
+ ```
51
+
52
+ The `.json` route is intentional: a source fixture such as `db/users.json`
53
+ maps naturally to `GET /db/users.json`, while the server still reads from the
54
+ synced runtime resource under `.db/state`.
55
+
56
+ Create a local runtime record:
57
+
58
+ ```bash
59
+ curl -X POST http://127.0.0.1:7331/db/users \
60
+ -H 'content-type: application/json' \
61
+ -d '{"id":"u_2","name":"Grace Hopper","email":"grace@example.com"}'
62
+ ```
63
+
64
+ The equivalent CLI smoke command is:
65
+
66
+ ```bash
67
+ npm run db -- create users '{"id":"u_2","name":"Grace Hopper","email":"grace@example.com"}' --cwd ./examples/basic
68
+ ```
69
+
70
+ ## Registered Operation To Try
71
+
72
+ Build operations, then use the generated ref from
73
+ `examples/basic/src/generated/db.operation-refs.json`:
74
+
75
+ ```bash
76
+ curl -X POST http://127.0.0.1:7331/__db/operations/REF \
77
+ -H 'content-type: application/json' \
78
+ -d '{"variables":{"id":"u_1"}}'
79
+ ```
80
+
81
+ ## Features To Notice
82
+
83
+ - [Fixture-like `.json` REST routes](../../docs/server-and-viewer.md#fixture-like-json-routes)
84
+ - [Schema-backed fixtures](../../docs/fixtures-and-schemas.md#schema-files)
85
+ - [Generated types](../../docs/generated-files.md#generated-types)
86
+ - [Registered REST operations](../../docs/server-and-viewer.md#registered-rest-operations)
87
+
88
+ ## Cleanup
89
+
90
+ Generated `.db/` output is ignored by git and can be removed whenever you want a fresh mirror.
91
+
92
+ ## More Docs
93
+
94
+ - [Getting Started](../../docs/getting-started.md)
95
+ - [Generated Files](../../docs/generated-files.md)
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "GetUser",
3
+ "method": "GET",
4
+ "path": "/users/{id}.json",
5
+ "query": {
6
+ "select": "id,name,email"
7
+ }
8
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "theme": "light",
3
+ "locale": "en-US",
4
+ "features": {
5
+ "billing": false
6
+ }
7
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ // Users who can sign into the local test app.
3
+ "kind": "collection",
4
+ "idField": "id",
5
+ "fields": {
6
+ "id": {
7
+ "type": "string",
8
+ "required": true,
9
+ "description": "Stable user id."
10
+ },
11
+ "name": {
12
+ "type": "string",
13
+ "required": true,
14
+ "description": "Display name shown in the UI."
15
+ },
16
+ "email": {
17
+ "type": "string",
18
+ "required": true,
19
+ "description": "Unique email address."
20
+ },
21
+ "role": {
22
+ "type": "enum",
23
+ "values": ["admin", "user"],
24
+ "default": "user",
25
+ "description": "Local authorization role."
26
+ }
27
+ },
28
+ "seed": [
29
+ {
30
+ "id": "u_1",
31
+ "name": "Ada Lovelace",
32
+ "email": "ada@example.com",
33
+ "role": "admin"
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,68 @@
1
+ // @ts-check
2
+ import { defineConfig } from '@async/db/config';
3
+
4
+ export default defineConfig({
5
+ dbDir: './db',
6
+ outputs: {
7
+ stateDir: './.db',
8
+ types: './.db/types/index.d.ts',
9
+ committedTypes: './src/generated/db.types.d.ts',
10
+ operationRegistry: './src/generated/db.operations.json',
11
+ operationRefs: './src/generated/db.operation-refs.json',
12
+ },
13
+ types: {
14
+ enabled: true,
15
+ emitComments: true,
16
+ },
17
+ schema: {
18
+ unknownFields: 'warn',
19
+ },
20
+ operations: {
21
+ enabled: false,
22
+ sourceDir: './db/operations',
23
+ },
24
+ rest: {
25
+ formats: {
26
+ yaml: {
27
+ mediaTypes: ['application/yaml', 'text/yaml'],
28
+ contentType: 'application/yaml; charset=utf-8',
29
+ render({ data }) {
30
+ return `${toYaml(data)}\n`;
31
+ },
32
+ },
33
+ },
34
+ },
35
+ });
36
+
37
+ function toYaml(value, indent = 0) {
38
+ const pad = ' '.repeat(indent);
39
+ if (Array.isArray(value)) {
40
+ return value.map((item) => {
41
+ if (item && typeof item === 'object') {
42
+ return `${pad}-\n${toYaml(item, indent + 2)}`;
43
+ }
44
+ return `${pad}- ${formatYamlScalar(item)}`;
45
+ }).join('\n');
46
+ }
47
+
48
+ if (value && typeof value === 'object') {
49
+ return Object.entries(value).map(([key, item]) => {
50
+ if (item && typeof item === 'object') {
51
+ return `${pad}${key}:\n${toYaml(item, indent + 2)}`;
52
+ }
53
+ return `${pad}${key}: ${formatYamlScalar(item)}`;
54
+ }).join('\n');
55
+ }
56
+
57
+ return `${pad}${formatYamlScalar(value)}`;
58
+ }
59
+
60
+ function formatYamlScalar(value) {
61
+ if (typeof value === 'string') {
62
+ return JSON.stringify(value);
63
+ }
64
+ if (value === null) {
65
+ return 'null';
66
+ }
67
+ return String(value);
68
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "Basic",
3
+ "description": "The smallest schema-backed workflow: sync fixtures, inspect the viewer, and create a record through REST or the CLI.",
4
+ "tags": ["quick-start", "schema", "rest"]
5
+ }
@@ -0,0 +1,39 @@
1
+ /* eslint-disable */
2
+ // This file is generated by db. Do not edit by hand.
3
+
4
+ export type UserRole = "admin" | "user";
5
+
6
+ export type Settings = {
7
+ features?: {
8
+ billing?: boolean;
9
+ };
10
+ locale?: string;
11
+ theme?: string;
12
+ };
13
+
14
+ export type User = {
15
+ /** Stable user id. */
16
+ id: string;
17
+ /** Display name shown in the UI. */
18
+ name: string;
19
+ /** Unique email address. */
20
+ email: string;
21
+ /** Local authorization role. */
22
+ role?: UserRole;
23
+ };
24
+
25
+ export type DbCollections = {
26
+ users: User;
27
+ };
28
+
29
+ export type DbDocuments = {
30
+ settings: Settings;
31
+ };
32
+
33
+ export type DbTypes = {
34
+ collections: DbCollections;
35
+ documents: DbDocuments;
36
+ };
37
+
38
+ export type DbCollectionName = keyof DbCollections;
39
+ export type DbDocumentName = keyof DbDocuments;
@@ -0,0 +1,21 @@
1
+ # CMS JSON Publish Example
2
+
3
+ This example shows how an app can build CMS behavior on top of generic `@async/db` primitives. The CMS helper is app code, not package API.
4
+
5
+ Run it from the repository root:
6
+
7
+ ```bash
8
+ npm run db -- sync --cwd ./examples/cms-json-publish
9
+ node ./examples/cms-json-publish/src/cms.mjs
10
+ ```
11
+
12
+ The script:
13
+
14
+ - creates a tenant fork
15
+ - creates `draft` and `published` branches
16
+ - saves draft content in `draft`
17
+ - filters public records in app code
18
+ - writes only published records into `published`
19
+ - serves public JSON from the `published` branch
20
+
21
+ `@async/db/json` stores the branch files; the app decides what `published` means.
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "id": "nav_home",
4
+ "label": "Home",
5
+ "slug": "home"
6
+ }
7
+ ]
@@ -0,0 +1,18 @@
1
+ [
2
+ {
3
+ "id": "home",
4
+ "slug": "home",
5
+ "title": "Home",
6
+ "status": "published",
7
+ "summary": "Public home page",
8
+ "bodyMarkdown": "# Home"
9
+ },
10
+ {
11
+ "id": "roadmap",
12
+ "slug": "roadmap",
13
+ "title": "Roadmap",
14
+ "status": "draft",
15
+ "summary": "Draft roadmap",
16
+ "bodyMarkdown": "# Roadmap"
17
+ }
18
+ ]
@@ -0,0 +1,5 @@
1
+ {
2
+ "title": "CMS JSON Publish",
3
+ "description": "App-owned CMS helper that uses branches to publish public JSON.",
4
+ "tags": ["cms", "forks", "branches", "json"]
5
+ }
@@ -0,0 +1,104 @@
1
+ import assert from 'node:assert/strict';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { openDb } from '@async/db';
4
+
5
+ export function createCms(db, { tenantId }) {
6
+ return {
7
+ async setup() {
8
+ const tenant = await db.forks.ensure(tenantId, {
9
+ from: 'main',
10
+ metadata: {
11
+ purpose: 'tenant',
12
+ app: 'cms-json-publish',
13
+ },
14
+ });
15
+ await tenant.branches.ensure('draft', { from: 'main', metadata: { purpose: 'draft' } });
16
+ await tenant.branches.ensure('published', { from: 'main', metadata: { purpose: 'published' } });
17
+ },
18
+
19
+ async saveDraft(pageId, changes) {
20
+ const tenant = await db.forks.open(tenantId);
21
+ const draft = await tenant.branches.open('draft');
22
+ return draft.collection('pages').patch(pageId, {
23
+ ...changes,
24
+ status: 'draft',
25
+ updatedAt: new Date().toISOString(),
26
+ });
27
+ },
28
+
29
+ async createPreview(previewId) {
30
+ const tenant = await db.forks.open(tenantId);
31
+ return tenant.branches.create(previewId, {
32
+ from: 'draft',
33
+ metadata: { purpose: 'preview' },
34
+ });
35
+ },
36
+
37
+ async publish({ label = 'publish' } = {}) {
38
+ const tenant = await db.forks.open(tenantId);
39
+ const draft = await tenant.branches.open('draft');
40
+ const published = await tenant.branches.open('published');
41
+ const snapshot = await draft.snapshots.create({
42
+ label,
43
+ resources: ['pages', 'navigation'],
44
+ });
45
+ const pages = await draft.collection('pages').all();
46
+ const publicPages = pages
47
+ .filter((page) => page.status === 'published')
48
+ .map(({ id, slug, title, status, summary, bodyMarkdown }) => ({
49
+ id,
50
+ slug,
51
+ title,
52
+ status,
53
+ summary,
54
+ bodyMarkdown,
55
+ }));
56
+
57
+ await published.collection('pages').replaceAll(publicPages);
58
+ await published.collection('navigation').replaceAll(await draft.collection('navigation').all());
59
+
60
+ return {
61
+ snapshot,
62
+ publicPages,
63
+ };
64
+ },
65
+
66
+ async listPublishedPages() {
67
+ const tenant = await db.forks.open(tenantId);
68
+ const published = await tenant.branches.open('published');
69
+ return published.collection('pages').all();
70
+ },
71
+ };
72
+ }
73
+
74
+ async function main() {
75
+ const db = await openDb({
76
+ cwd: new URL('../', import.meta.url).pathname,
77
+ });
78
+ const cms = createCms(db, { tenantId: 'tenant_acme' });
79
+
80
+ await cms.setup();
81
+ await cms.saveDraft('roadmap', {
82
+ title: 'Private roadmap',
83
+ });
84
+ await cms.createPreview('preview_homepage');
85
+ const { publicPages } = await cms.publish({ label: 'initial-public-json' });
86
+
87
+ assert.deepEqual(publicPages.map((page) => page.slug), ['home']);
88
+ assert.deepEqual(await cms.listPublishedPages(), [
89
+ {
90
+ id: 'home',
91
+ slug: 'home',
92
+ title: 'Home',
93
+ status: 'published',
94
+ summary: 'Public home page',
95
+ bodyMarkdown: '# Home',
96
+ },
97
+ ]);
98
+
99
+ await db.close();
100
+ }
101
+
102
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
103
+ await main();
104
+ }