ultimabase 0.0.0-stage → 0.1.1

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 (411) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +4 -2
  3. package/dist/access.d.ts +62 -0
  4. package/dist/access.d.ts.map +1 -0
  5. package/dist/access.js +258 -0
  6. package/dist/adapter-errors.d.ts +43 -0
  7. package/dist/adapter-errors.d.ts.map +1 -0
  8. package/dist/adapter-errors.js +72 -0
  9. package/dist/adapter-json.d.ts +20 -0
  10. package/dist/adapter-json.d.ts.map +1 -0
  11. package/dist/adapter-json.js +2 -0
  12. package/dist/adapter-migrations.d.ts +90 -0
  13. package/dist/adapter-migrations.d.ts.map +1 -0
  14. package/dist/adapter-migrations.js +1 -0
  15. package/dist/adapter.d.ts +333 -0
  16. package/dist/adapter.d.ts.map +1 -0
  17. package/dist/adapter.js +5 -0
  18. package/dist/aggregate.d.ts +31 -0
  19. package/dist/aggregate.d.ts.map +1 -0
  20. package/dist/aggregate.js +99 -0
  21. package/dist/app-internals.d.ts +10 -0
  22. package/dist/app-internals.d.ts.map +1 -0
  23. package/dist/app-internals.js +12 -0
  24. package/dist/app-options.d.ts +22 -0
  25. package/dist/app-options.d.ts.map +1 -0
  26. package/dist/app-options.js +3 -0
  27. package/dist/cascade.d.ts +47 -0
  28. package/dist/cascade.d.ts.map +1 -0
  29. package/dist/cascade.js +209 -0
  30. package/dist/cli-config.d.ts +6 -0
  31. package/dist/cli-config.d.ts.map +1 -0
  32. package/dist/cli-config.js +45 -0
  33. package/dist/cli-deploy.d.ts +14 -0
  34. package/dist/cli-deploy.d.ts.map +1 -0
  35. package/dist/cli-deploy.js +193 -0
  36. package/dist/cli-main.d.ts +15 -0
  37. package/dist/cli-main.d.ts.map +1 -0
  38. package/dist/cli-main.js +155 -0
  39. package/dist/cli-migrate.d.ts +20 -0
  40. package/dist/cli-migrate.d.ts.map +1 -0
  41. package/dist/cli-migrate.js +105 -0
  42. package/dist/cli.d.ts +3 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +4 -0
  45. package/dist/complete.d.ts +13 -0
  46. package/dist/complete.d.ts.map +1 -0
  47. package/dist/complete.js +60 -0
  48. package/dist/console-logger.d.ts +3 -0
  49. package/dist/console-logger.d.ts.map +1 -0
  50. package/dist/console-logger.js +62 -0
  51. package/dist/create-many.d.ts +7 -0
  52. package/dist/create-many.d.ts.map +1 -0
  53. package/dist/create-many.js +88 -0
  54. package/dist/decimal.d.ts +23 -0
  55. package/dist/decimal.d.ts.map +1 -0
  56. package/dist/decimal.js +50 -0
  57. package/dist/define-app.d.ts +59 -0
  58. package/dist/define-app.d.ts.map +1 -0
  59. package/dist/define-app.js +5 -0
  60. package/dist/define-enum.d.ts +6 -0
  61. package/dist/define-enum.d.ts.map +1 -0
  62. package/dist/define-enum.js +18 -0
  63. package/dist/define-function.d.ts +25 -0
  64. package/dist/define-function.d.ts.map +1 -0
  65. package/dist/define-function.js +111 -0
  66. package/dist/define-model.d.ts +48 -0
  67. package/dist/define-model.d.ts.map +1 -0
  68. package/dist/define-model.js +85 -0
  69. package/dist/definition.d.ts +179 -0
  70. package/dist/definition.d.ts.map +1 -0
  71. package/dist/definition.js +165 -0
  72. package/dist/delete-many.d.ts +13 -0
  73. package/dist/delete-many.d.ts.map +1 -0
  74. package/dist/delete-many.js +58 -0
  75. package/dist/engine.d.ts +16 -0
  76. package/dist/engine.d.ts.map +1 -0
  77. package/dist/engine.js +174 -0
  78. package/dist/errors.d.ts +50 -0
  79. package/dist/errors.d.ts.map +1 -0
  80. package/dist/errors.js +43 -0
  81. package/dist/exact.d.ts +20 -0
  82. package/dist/exact.d.ts.map +1 -0
  83. package/dist/exact.js +1 -0
  84. package/dist/feed.d.ts +6 -0
  85. package/dist/feed.d.ts.map +1 -0
  86. package/dist/feed.js +33 -0
  87. package/dist/field-codec.d.ts +11 -0
  88. package/dist/field-codec.d.ts.map +1 -0
  89. package/dist/field-codec.js +48 -0
  90. package/dist/field-rules.d.ts +57 -0
  91. package/dist/field-rules.d.ts.map +1 -0
  92. package/dist/field-rules.js +1 -0
  93. package/dist/field-type.d.ts +51 -0
  94. package/dist/field-type.d.ts.map +1 -0
  95. package/dist/field-type.js +106 -0
  96. package/dist/fields.d.ts +295 -0
  97. package/dist/fields.d.ts.map +1 -0
  98. package/dist/fields.js +1 -0
  99. package/dist/function.d.ts +126 -0
  100. package/dist/function.d.ts.map +1 -0
  101. package/dist/function.js +1 -0
  102. package/dist/functions.d.ts +18 -0
  103. package/dist/functions.d.ts.map +1 -0
  104. package/dist/functions.js +99 -0
  105. package/dist/group-by.d.ts +10 -0
  106. package/dist/group-by.d.ts.map +1 -0
  107. package/dist/group-by.js +145 -0
  108. package/dist/group-having.d.ts +8 -0
  109. package/dist/group-having.d.ts.map +1 -0
  110. package/dist/group-having.js +97 -0
  111. package/dist/hooks.d.ts +41 -0
  112. package/dist/hooks.d.ts.map +1 -0
  113. package/dist/hooks.js +149 -0
  114. package/dist/hosts.d.ts +3 -0
  115. package/dist/hosts.d.ts.map +1 -0
  116. package/dist/hosts.js +8 -0
  117. package/dist/identify.d.ts +15 -0
  118. package/dist/identify.d.ts.map +1 -0
  119. package/dist/identify.js +71 -0
  120. package/dist/index.d.ts +25 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +12 -0
  123. package/dist/internal.d.ts +28 -0
  124. package/dist/internal.d.ts.map +1 -0
  125. package/dist/internal.js +39 -0
  126. package/dist/lifecycle.d.ts +21 -0
  127. package/dist/lifecycle.d.ts.map +1 -0
  128. package/dist/lifecycle.js +149 -0
  129. package/dist/list-update.d.ts +12 -0
  130. package/dist/list-update.d.ts.map +1 -0
  131. package/dist/list-update.js +52 -0
  132. package/dist/live.d.ts +37 -0
  133. package/dist/live.d.ts.map +1 -0
  134. package/dist/live.js +139 -0
  135. package/dist/manifest.d.ts +11 -0
  136. package/dist/manifest.d.ts.map +1 -0
  137. package/dist/manifest.js +60 -0
  138. package/dist/memory-aggregate.d.ts +7 -0
  139. package/dist/memory-aggregate.d.ts.map +1 -0
  140. package/dist/memory-aggregate.js +107 -0
  141. package/dist/memory-conditions.d.ts +8 -0
  142. package/dist/memory-conditions.d.ts.map +1 -0
  143. package/dist/memory-conditions.js +82 -0
  144. package/dist/memory-draft.d.ts +34 -0
  145. package/dist/memory-draft.d.ts.map +1 -0
  146. package/dist/memory-draft.js +255 -0
  147. package/dist/memory-json.d.ts +6 -0
  148. package/dist/memory-json.d.ts.map +1 -0
  149. package/dist/memory-json.js +86 -0
  150. package/dist/memory-read.d.ts +45 -0
  151. package/dist/memory-read.d.ts.map +1 -0
  152. package/dist/memory-read.js +244 -0
  153. package/dist/memory-search.d.ts +16 -0
  154. package/dist/memory-search.d.ts.map +1 -0
  155. package/dist/memory-search.js +110 -0
  156. package/dist/memory-values.d.ts +23 -0
  157. package/dist/memory-values.d.ts.map +1 -0
  158. package/dist/memory-values.js +82 -0
  159. package/dist/memory.d.ts +4 -0
  160. package/dist/memory.d.ts.map +1 -0
  161. package/dist/memory.js +157 -0
  162. package/dist/migrate.d.ts +22 -0
  163. package/dist/migrate.d.ts.map +1 -0
  164. package/dist/migrate.js +131 -0
  165. package/dist/model.d.ts +239 -0
  166. package/dist/model.d.ts.map +1 -0
  167. package/dist/model.js +1 -0
  168. package/dist/nested-write.d.ts +64 -0
  169. package/dist/nested-write.d.ts.map +1 -0
  170. package/dist/nested-write.js +274 -0
  171. package/dist/number-update.d.ts +18 -0
  172. package/dist/number-update.d.ts.map +1 -0
  173. package/dist/number-update.js +96 -0
  174. package/dist/plugin-app.d.ts +48 -0
  175. package/dist/plugin-app.d.ts.map +1 -0
  176. package/dist/plugin-app.js +230 -0
  177. package/dist/plugin-code.d.ts +17 -0
  178. package/dist/plugin-code.d.ts.map +1 -0
  179. package/dist/plugin-code.js +125 -0
  180. package/dist/plugin-use.d.ts +22 -0
  181. package/dist/plugin-use.d.ts.map +1 -0
  182. package/dist/plugin-use.js +161 -0
  183. package/dist/plugin.d.ts +357 -0
  184. package/dist/plugin.d.ts.map +1 -0
  185. package/dist/plugin.js +17 -0
  186. package/dist/query-aggregate.d.ts +82 -0
  187. package/dist/query-aggregate.d.ts.map +1 -0
  188. package/dist/query-aggregate.js +1 -0
  189. package/dist/query-args.d.ts +41 -0
  190. package/dist/query-args.d.ts.map +1 -0
  191. package/dist/query-args.js +263 -0
  192. package/dist/query-bulk.d.ts +35 -0
  193. package/dist/query-bulk.d.ts.map +1 -0
  194. package/dist/query-bulk.js +1 -0
  195. package/dist/query-conditions.d.ts +9 -0
  196. package/dist/query-conditions.d.ts.map +1 -0
  197. package/dist/query-conditions.js +46 -0
  198. package/dist/query-context.d.ts +32 -0
  199. package/dist/query-context.d.ts.map +1 -0
  200. package/dist/query-context.js +55 -0
  201. package/dist/query-filter.d.ts +46 -0
  202. package/dist/query-filter.d.ts.map +1 -0
  203. package/dist/query-filter.js +1 -0
  204. package/dist/query-group.d.ts +82 -0
  205. package/dist/query-group.d.ts.map +1 -0
  206. package/dist/query-group.js +1 -0
  207. package/dist/query-json.d.ts +9 -0
  208. package/dist/query-json.d.ts.map +1 -0
  209. package/dist/query-json.js +66 -0
  210. package/dist/query-order.d.ts +15 -0
  211. package/dist/query-order.d.ts.map +1 -0
  212. package/dist/query-order.js +115 -0
  213. package/dist/query-project.d.ts +15 -0
  214. package/dist/query-project.d.ts.map +1 -0
  215. package/dist/query-project.js +45 -0
  216. package/dist/query-search.d.ts +24 -0
  217. package/dist/query-search.d.ts.map +1 -0
  218. package/dist/query-search.js +2 -0
  219. package/dist/query-values.d.ts +28 -0
  220. package/dist/query-values.d.ts.map +1 -0
  221. package/dist/query-values.js +91 -0
  222. package/dist/query-where.d.ts +46 -0
  223. package/dist/query-where.d.ts.map +1 -0
  224. package/dist/query-where.js +200 -0
  225. package/dist/query-write.d.ts +14 -0
  226. package/dist/query-write.d.ts.map +1 -0
  227. package/dist/query-write.js +260 -0
  228. package/dist/query.d.ts +254 -0
  229. package/dist/query.d.ts.map +1 -0
  230. package/dist/query.js +1 -0
  231. package/dist/record.d.ts +257 -0
  232. package/dist/record.d.ts.map +1 -0
  233. package/dist/record.js +1 -0
  234. package/dist/recorder.d.ts +32 -0
  235. package/dist/recorder.d.ts.map +1 -0
  236. package/dist/recorder.js +152 -0
  237. package/dist/relation-write.d.ts +41 -0
  238. package/dist/relation-write.d.ts.map +1 -0
  239. package/dist/relation-write.js +112 -0
  240. package/dist/relations.d.ts +42 -0
  241. package/dist/relations.d.ts.map +1 -0
  242. package/dist/relations.js +119 -0
  243. package/dist/rules.d.ts +97 -0
  244. package/dist/rules.d.ts.map +1 -0
  245. package/dist/rules.js +71 -0
  246. package/dist/running.d.ts +29 -0
  247. package/dist/running.d.ts.map +1 -0
  248. package/dist/running.js +39 -0
  249. package/dist/schema-indexes.d.ts +11 -0
  250. package/dist/schema-indexes.d.ts.map +1 -0
  251. package/dist/schema-indexes.js +59 -0
  252. package/dist/schema-virtuals.d.ts +19 -0
  253. package/dist/schema-virtuals.d.ts.map +1 -0
  254. package/dist/schema-virtuals.js +100 -0
  255. package/dist/schema.d.ts +35 -0
  256. package/dist/schema.d.ts.map +1 -0
  257. package/dist/schema.js +267 -0
  258. package/dist/scope.d.ts +46 -0
  259. package/dist/scope.d.ts.map +1 -0
  260. package/dist/scope.js +82 -0
  261. package/dist/scratch.d.ts +14 -0
  262. package/dist/scratch.d.ts.map +1 -0
  263. package/dist/scratch.js +10 -0
  264. package/dist/serve.d.ts +2 -0
  265. package/dist/serve.d.ts.map +1 -0
  266. package/dist/serve.js +4 -0
  267. package/dist/symbols.d.ts +10 -0
  268. package/dist/symbols.d.ts.map +1 -0
  269. package/dist/symbols.js +1 -0
  270. package/dist/transaction.d.ts +28 -0
  271. package/dist/transaction.d.ts.map +1 -0
  272. package/dist/transaction.js +156 -0
  273. package/dist/types.d.ts +58 -0
  274. package/dist/types.d.ts.map +1 -0
  275. package/dist/types.js +1 -0
  276. package/dist/update-many.d.ts +7 -0
  277. package/dist/update-many.d.ts.map +1 -0
  278. package/dist/update-many.js +182 -0
  279. package/dist/uuid.d.ts +7 -0
  280. package/dist/uuid.d.ts.map +1 -0
  281. package/dist/uuid.js +48 -0
  282. package/dist/validation.d.ts +24 -0
  283. package/dist/validation.d.ts.map +1 -0
  284. package/dist/validation.js +72 -0
  285. package/dist/virtual-read.d.ts +9 -0
  286. package/dist/virtual-read.d.ts.map +1 -0
  287. package/dist/virtual-read.js +145 -0
  288. package/dist/virtual.d.ts +142 -0
  289. package/dist/virtual.d.ts.map +1 -0
  290. package/dist/virtual.js +1 -0
  291. package/dist/write-context.d.ts +46 -0
  292. package/dist/write-context.d.ts.map +1 -0
  293. package/dist/write-context.js +102 -0
  294. package/dist/write-data.d.ts +26 -0
  295. package/dist/write-data.d.ts.map +1 -0
  296. package/dist/write-data.js +144 -0
  297. package/dist/write-plan.d.ts +107 -0
  298. package/dist/write-plan.d.ts.map +1 -0
  299. package/dist/write-plan.js +170 -0
  300. package/dist/write-target.d.ts +17 -0
  301. package/dist/write-target.d.ts.map +1 -0
  302. package/dist/write-target.js +59 -0
  303. package/dist/writes.d.ts +23 -0
  304. package/dist/writes.d.ts.map +1 -0
  305. package/dist/writes.js +246 -0
  306. package/dist/writing.d.ts +10 -0
  307. package/dist/writing.d.ts.map +1 -0
  308. package/dist/writing.js +66 -0
  309. package/package.json +42 -3
  310. package/src/access.ts +329 -0
  311. package/src/adapter-errors.ts +89 -0
  312. package/src/adapter-json.ts +21 -0
  313. package/src/adapter-migrations.ts +98 -0
  314. package/src/adapter.ts +363 -0
  315. package/src/aggregate.ts +136 -0
  316. package/src/app-internals.ts +26 -0
  317. package/src/app-options.ts +24 -0
  318. package/src/cascade.ts +297 -0
  319. package/src/cli-config.ts +45 -0
  320. package/src/cli-deploy.ts +235 -0
  321. package/src/cli-main.ts +166 -0
  322. package/src/cli-migrate.ts +143 -0
  323. package/src/cli.ts +5 -0
  324. package/src/complete.ts +73 -0
  325. package/src/console-logger.ts +87 -0
  326. package/src/create-many.ts +126 -0
  327. package/src/decimal.ts +74 -0
  328. package/src/define-app.ts +108 -0
  329. package/src/define-enum.ts +26 -0
  330. package/src/define-function.ts +188 -0
  331. package/src/define-model.ts +220 -0
  332. package/src/definition.ts +352 -0
  333. package/src/delete-many.ts +76 -0
  334. package/src/engine.ts +281 -0
  335. package/src/errors.ts +97 -0
  336. package/src/exact.ts +49 -0
  337. package/src/feed.ts +39 -0
  338. package/src/field-codec.ts +72 -0
  339. package/src/field-rules.ts +77 -0
  340. package/src/field-type.ts +219 -0
  341. package/src/fields.ts +383 -0
  342. package/src/function.ts +143 -0
  343. package/src/functions.ts +154 -0
  344. package/src/group-by.ts +186 -0
  345. package/src/group-having.ts +143 -0
  346. package/src/hooks.ts +215 -0
  347. package/src/hosts.ts +11 -0
  348. package/src/identify.ts +95 -0
  349. package/src/index.ts +125 -0
  350. package/src/internal.ts +68 -0
  351. package/src/lifecycle.ts +214 -0
  352. package/src/list-update.ts +71 -0
  353. package/src/live.ts +199 -0
  354. package/src/manifest.ts +71 -0
  355. package/src/memory-aggregate.ts +162 -0
  356. package/src/memory-conditions.ts +88 -0
  357. package/src/memory-draft.ts +319 -0
  358. package/src/memory-json.ts +91 -0
  359. package/src/memory-read.ts +311 -0
  360. package/src/memory-search.ts +149 -0
  361. package/src/memory-values.ts +106 -0
  362. package/src/memory.ts +173 -0
  363. package/src/migrate.ts +152 -0
  364. package/src/model.ts +312 -0
  365. package/src/nested-write.ts +390 -0
  366. package/src/number-update.ts +142 -0
  367. package/src/plugin-app.ts +308 -0
  368. package/src/plugin-code.ts +158 -0
  369. package/src/plugin-use.ts +217 -0
  370. package/src/plugin.ts +400 -0
  371. package/src/query-aggregate.ts +96 -0
  372. package/src/query-args.ts +375 -0
  373. package/src/query-bulk.ts +53 -0
  374. package/src/query-conditions.ts +53 -0
  375. package/src/query-context.ts +104 -0
  376. package/src/query-filter.ts +54 -0
  377. package/src/query-group.ts +137 -0
  378. package/src/query-json.ts +90 -0
  379. package/src/query-order.ts +158 -0
  380. package/src/query-project.ts +73 -0
  381. package/src/query-search.ts +31 -0
  382. package/src/query-values.ts +131 -0
  383. package/src/query-where.ts +318 -0
  384. package/src/query-write.ts +360 -0
  385. package/src/query.ts +400 -0
  386. package/src/record.ts +379 -0
  387. package/src/recorder.ts +212 -0
  388. package/src/relation-write.ts +176 -0
  389. package/src/relations.ts +165 -0
  390. package/src/rules.ts +188 -0
  391. package/src/running.ts +62 -0
  392. package/src/schema-indexes.ts +88 -0
  393. package/src/schema-virtuals.ts +134 -0
  394. package/src/schema.ts +367 -0
  395. package/src/scope.ts +123 -0
  396. package/src/scratch.ts +28 -0
  397. package/src/serve.ts +5 -0
  398. package/src/symbols.ts +11 -0
  399. package/src/transaction.ts +211 -0
  400. package/src/types.ts +79 -0
  401. package/src/update-many.ts +268 -0
  402. package/src/uuid.ts +51 -0
  403. package/src/validation.ts +107 -0
  404. package/src/virtual-read.ts +198 -0
  405. package/src/virtual.ts +187 -0
  406. package/src/write-context.ts +170 -0
  407. package/src/write-data.ts +188 -0
  408. package/src/write-plan.ts +273 -0
  409. package/src/write-target.ts +92 -0
  410. package/src/writes.ts +361 -0
  411. package/src/writing.ts +93 -0
package/src/index.ts ADDED
@@ -0,0 +1,125 @@
1
+ // The kernel's public surface (D-01).
2
+ export type {
3
+ Adapter,
4
+ Aggregate,
5
+ AggregateRead,
6
+ Arithmetic,
7
+ Change,
8
+ Changed,
9
+ Check,
10
+ Condition,
11
+ CountRead,
12
+ Feed,
13
+ Filter,
14
+ GroupKey,
15
+ ListUpdate,
16
+ Migration,
17
+ Migrations,
18
+ Nested,
19
+ Order,
20
+ Read,
21
+ Row,
22
+ Run,
23
+ ScalarType,
24
+ Schema,
25
+ SchemaField,
26
+ SchemaModel,
27
+ Sort,
28
+ Statement,
29
+ Stored,
30
+ Transaction,
31
+ Write,
32
+ } from './adapter.ts'
33
+ export {
34
+ CheckFailed,
35
+ feedFields,
36
+ feedIds,
37
+ MigrationFailed,
38
+ OutOfRange,
39
+ RelationViolation,
40
+ UniqueViolation,
41
+ } from './adapter.ts'
42
+ export type { Logger, MasterKey } from './app-options.ts'
43
+ export { defineApp } from './define-app.ts'
44
+ export { defineEnum } from './define-enum.ts'
45
+ export type {
46
+ FieldShapes,
47
+ ModelFields,
48
+ ModelIndexes,
49
+ ModelOf,
50
+ } from './define-model.ts'
51
+ export { defineModel } from './define-model.ts'
52
+ export type { ErrorCode, Issue } from './errors.ts'
53
+ export { InvalidQuery, PublicError, Refused } from './errors.ts'
54
+ export type {
55
+ DecimalOptions,
56
+ Enum,
57
+ Field,
58
+ FieldBuilders,
59
+ JsonOptions,
60
+ JsonValue,
61
+ ListOptions,
62
+ Many,
63
+ ManyOptions,
64
+ One,
65
+ ScalarOptions,
66
+ SingleOptions,
67
+ StringOptions,
68
+ } from './fields.ts'
69
+ export { defineFunction, defineType } from './define-function.ts'
70
+ export type {
71
+ FieldType,
72
+ FieldTypeDefinition,
73
+ FieldTypeOptions,
74
+ } from './field-type.ts'
75
+ export { defineFieldType } from './field-type.ts'
76
+ export { isLocalHost } from './hosts.ts'
77
+ export type {
78
+ Client,
79
+ CookieOptions,
80
+ FunctionPlugin,
81
+ FunctionShape,
82
+ Nullable,
83
+ ObjectType,
84
+ OutputSpec,
85
+ ServerFunction,
86
+ } from './function.ts'
87
+ export { memory } from './memory.ts'
88
+ export type { App, FindOperation, IndexShape, Model } from './model.ts'
89
+ export type {
90
+ ExposedFunction,
91
+ ExposedModel,
92
+ ExposedOutput,
93
+ ExposedVirtual,
94
+ ExposedType,
95
+ ModelQueries,
96
+ ModelUse,
97
+ OutputForm,
98
+ PluginOf,
99
+ PluginTypes,
100
+ UseOf,
101
+ } from './plugin.ts'
102
+ export type { Payload, Queries } from './query.ts'
103
+ export { definePlugin } from './plugin.ts'
104
+ export type {
105
+ Caller,
106
+ CallerRule,
107
+ Identity,
108
+ Register,
109
+ UserCallerKeys,
110
+ UserOf,
111
+ } from './rules.ts'
112
+ export { allOf, allow, anyOf, isMaster, master } from './rules.ts'
113
+ export { transaction } from './transaction.ts'
114
+ export type {
115
+ ArgsOf,
116
+ CreateDataOf,
117
+ IncludeOf,
118
+ InputOf,
119
+ OrderByOf,
120
+ OutputOf,
121
+ RecordOf,
122
+ SelectOf,
123
+ UpdateDataOf,
124
+ WhereOf,
125
+ } from './types.ts'
@@ -0,0 +1,68 @@
1
+ // What official packages read from an application (D-130), kept off the
2
+ // documented surface: new runs of it on another database, quieter, the
3
+ // running plugins' APIs, what raw SQL and tests on the declared database
4
+ // need (D-137), and what live reads need (D-154).
5
+ import type { Adapter } from './adapter.ts'
6
+ import { internalsOf } from './app-internals.ts'
7
+ import type { Logger } from './app-options.ts'
8
+ import { consoleLogger } from './console-logger.ts'
9
+ import type { Lifecycle } from './lifecycle.ts'
10
+ import { lifecycle } from './lifecycle.ts'
11
+ import { current } from './running.ts'
12
+
13
+ export type { Lifecycle }
14
+ export type { Scratch } from './scratch.ts'
15
+ export { scratchable, scratchOf } from './scratch.ts'
16
+ export { isRow } from './field-codec.ts'
17
+ export { joining } from './transaction.ts'
18
+ export { issueOf } from './write-data.ts'
19
+ export { decimalPattern } from './decimal.ts'
20
+ export type { Recorded } from './recorder.ts'
21
+ export { recording } from './recorder.ts'
22
+ export type { LivePlan } from './live.ts'
23
+ export {
24
+ inMemory,
25
+ liveSchema,
26
+ livePlan,
27
+ matches,
28
+ servedRows,
29
+ sortKeys,
30
+ storedRows,
31
+ } from './live.ts'
32
+ export { compareKeys } from './memory-values.ts'
33
+
34
+ /** `logger` without its info lines. */
35
+ function quieted(logger: Logger): Logger {
36
+ return {
37
+ info: () => undefined,
38
+ warn: logger.warn.bind(logger),
39
+ error: logger.error.bind(logger),
40
+ child: (bindings) => quieted(logger.child(bindings)),
41
+ }
42
+ }
43
+
44
+ /** The application's database, and new runs of it on another (D-130). */
45
+ export type QuietRuns = {
46
+ readonly declared: Adapter
47
+ /** A run on `database`, without info lines. */
48
+ readonly on: (database: Adapter) => Lifecycle
49
+ }
50
+
51
+ /**
52
+ * Runs of the application `defineApp` returned as `app`, or `undefined` for
53
+ * another value.
54
+ */
55
+ export function quietRuns(app: unknown): QuietRuns | undefined {
56
+ const options = internalsOf(app)?.options
57
+ if (options === undefined) return undefined
58
+ const logger = quieted(options.logger ?? consoleLogger())
59
+ return {
60
+ declared: options.database,
61
+ on: (database) => lifecycle({ ...options, database, logger }),
62
+ }
63
+ }
64
+
65
+ /** The running application's plugin API named `name`, if any. */
66
+ export function runningApi(name: string): unknown {
67
+ return current()?.apis.get(name)
68
+ }
@@ -0,0 +1,214 @@
1
+ // `start` and `stop` (D-59, D-91): the database, the plugins' APIs, their
2
+ // `start` and `stop`, the operations still running, and `SIGTERM`.
3
+ import type { Adapter, Schema } from './adapter.ts'
4
+ import type { Logger, MasterKey } from './app-options.ts'
5
+ import type { PluginCaller } from './complete.ts'
6
+ import { completer } from './complete.ts'
7
+ import { consoleLogger } from './console-logger.ts'
8
+ import { feedOf } from './feed.ts'
9
+ import type { PluginIdentify } from './identify.ts'
10
+ import { identifier } from './identify.ts'
11
+ import { checkVersions } from './manifest.ts'
12
+ import { checked, synced } from './migrate.ts'
13
+ import type { Installed } from './plugin-app.ts'
14
+ import {
15
+ buildApis,
16
+ installed,
17
+ pluginCallers,
18
+ pluginIdentifiers,
19
+ withContexts,
20
+ } from './plugin-app.ts'
21
+ import type { Running } from './running.ts'
22
+ import { register, unregister, Work } from './running.ts'
23
+ import { resolve } from './schema.ts'
24
+
25
+ export type Lifecycle = {
26
+ readonly start: () => Promise<void>
27
+ readonly stop: () => Promise<void>
28
+ }
29
+
30
+ type Started = {
31
+ readonly app: Running
32
+ readonly plugins: readonly Installed[]
33
+ readonly onSigterm: () => void
34
+ }
35
+
36
+ /** Stops `plugins` in reverse order, each even when another fails. */
37
+ async function stopped(plugins: readonly Installed[]): Promise<unknown[]> {
38
+ const errors: unknown[] = []
39
+ for (const { code, context } of plugins.toReversed()) {
40
+ if (code.stop === undefined) continue
41
+ try {
42
+ await Reflect.apply(code.stop, undefined, [context])
43
+ } catch (error) {
44
+ context.logger.error({ err: error }, 'The plugin failed to stop.')
45
+ errors.push(error)
46
+ }
47
+ }
48
+ return errors
49
+ }
50
+
51
+ export type LifecycleOptions = {
52
+ readonly database: Adapter
53
+ readonly plugins?: readonly unknown[]
54
+ /** The application's `defineFunction` values (D-27). */
55
+ readonly functions?: readonly unknown[]
56
+ readonly models: readonly unknown[]
57
+ readonly logger?: Logger
58
+ readonly masterKey?: MasterKey
59
+ }
60
+
61
+ /** Once stdout and stderr have written what they were given. */
62
+ const written = () =>
63
+ Promise.all(
64
+ [process.stdout, process.stderr].map(
65
+ (stream) => new Promise((done) => stream.write('', done)),
66
+ ),
67
+ )
68
+
69
+ /** The application's schema, or a message on what is wrong with it. */
70
+ export function schemaOf(options: LifecycleOptions): Schema {
71
+ const { plugins } = installed(options.plugins ?? [])
72
+ return resolve(
73
+ options.models,
74
+ plugins.map((plugin) => plugin.code),
75
+ ).schema
76
+ }
77
+
78
+ /** The kernel's logger: the application's, or JSON lines. */
79
+ export const kernelLogger = (options: LifecycleOptions): Logger =>
80
+ (options.logger ?? consoleLogger()).child({ name: 'ultimabase' })
81
+
82
+ /** Syncs a development database, or checks a production one (D-105). */
83
+ async function follow(
84
+ database: Adapter,
85
+ schema: Schema,
86
+ logger: Logger,
87
+ ): Promise<void> {
88
+ try {
89
+ await (process.env['NODE_ENV'] === 'production'
90
+ ? checked(database, schema, logger)
91
+ : synced(database, schema, logger, false))
92
+ } catch (error) {
93
+ await database.stop()
94
+ throw error
95
+ }
96
+ }
97
+
98
+ export function lifecycle(options: LifecycleOptions): Lifecycle {
99
+ const { database, models } = options
100
+ let started: Started | undefined
101
+ let stopping: Promise<void> | undefined
102
+ let starting = false
103
+
104
+ const shutDown = async ({ app, plugins, onSigterm }: Started) => {
105
+ process.off('SIGTERM', onSigterm)
106
+ const errors = await stopped(plugins)
107
+ // A plugin's stop may still query; the database closes last.
108
+ await app.work.settled()
109
+ unregister(app)
110
+ started = undefined
111
+ await database.stop()
112
+ app.logger.info('Application stopped.')
113
+ if (errors.length > 0) throw errors[0]
114
+ }
115
+
116
+ const stop = async (): Promise<void> => {
117
+ if (stopping !== undefined) return stopping
118
+ if (started === undefined) return
119
+ stopping = shutDown(started).finally(() => {
120
+ stopping = undefined
121
+ })
122
+ return stopping
123
+ }
124
+
125
+ const start = async (): Promise<void> => {
126
+ if (started !== undefined || starting) {
127
+ throw new Error('The application is running.')
128
+ }
129
+ // Set before the first await: a second start meanwhile is refused.
130
+ starting = true
131
+ try {
132
+ await launch()
133
+ } finally {
134
+ starting = false
135
+ }
136
+ }
137
+
138
+ const launch = async (): Promise<void> => {
139
+ const { plugins: records, apiOrder } = installed(options.plugins ?? [])
140
+ const resolved = resolve(
141
+ models,
142
+ records.map((plugin) => plugin.code),
143
+ )
144
+ const base = options.logger ?? consoleLogger()
145
+ const logger = base.child({ name: 'ultimabase' })
146
+ checkVersions(records, logger)
147
+ // Plugins identify with their contexts, which hold identify.
148
+ const identifiers: PluginIdentify[] = []
149
+ const callers: PluginCaller[] = []
150
+ const complete = completer(callers)
151
+ const identify = identifier(
152
+ options.masterKey,
153
+ logger,
154
+ identifiers,
155
+ complete,
156
+ )
157
+ const { plugins, functions } = withContexts(
158
+ apiOrder,
159
+ base,
160
+ identify,
161
+ resolved,
162
+ options.functions ?? [],
163
+ )
164
+ identifiers.push(...pluginIdentifiers(records, plugins))
165
+ callers.push(...pluginCallers(records, plugins))
166
+ await database.start(resolved.schema, logger, feedOf(records, plugins))
167
+ const apis = new Map<string, unknown>()
168
+ const app: Running = {
169
+ resolved,
170
+ adapter: database,
171
+ logger,
172
+ apis,
173
+ functions: functions.definitions,
174
+ work: new Work(),
175
+ complete,
176
+ }
177
+ const ran: Installed[] = []
178
+ try {
179
+ await follow(database, resolved.schema, logger)
180
+ register(app)
181
+ // An API may read the APIs it needs as it is built (D-89).
182
+ buildApis(plugins, apis)
183
+ for (const plugin of plugins) {
184
+ const { code, context } = plugin
185
+ if (code.start !== undefined) {
186
+ await Reflect.apply(code.start, undefined, [context])
187
+ }
188
+ ran.push(plugin)
189
+ }
190
+ } catch (error) {
191
+ await stopped(ran)
192
+ unregister(app)
193
+ await database.stop()
194
+ throw error
195
+ }
196
+ const onSigterm = () => {
197
+ void stop()
198
+ .catch((error: unknown) => {
199
+ logger.error({ err: error }, 'The application stopped with an error.')
200
+ })
201
+ // The last lines first: a pipe may write them later.
202
+ .then(written)
203
+ .finally(() => {
204
+ // Its listener is gone: the signal now ends the process.
205
+ process.kill(process.pid, 'SIGTERM')
206
+ })
207
+ }
208
+ process.once('SIGTERM', onSigterm)
209
+ started = { app, plugins, onSigterm }
210
+ logger.info('Application started.')
211
+ }
212
+
213
+ return { start, stop }
214
+ }
@@ -0,0 +1,71 @@
1
+ // List updates (D-149): `{ set }`, `{ push }`, `{ pushUnique }` or
2
+ // `{ remove }` on a list field, with an element or a list of them, computed
3
+ // on the row as the write finds it, as a number update is (D-132).
4
+ import type { ListUpdate } from './adapter.ts'
5
+ import { InvalidQuery } from './errors.ts'
6
+ import { isObject } from './query-where.ts'
7
+ import type { ModelInfo } from './schema.ts'
8
+ import type { Draft } from './write-data.ts'
9
+ import { invalid, issueOf } from './write-data.ts'
10
+
11
+ const operations = ['set', 'push', 'pushUnique', 'remove'] as const
12
+ type Operation = (typeof operations)[number]
13
+
14
+ const isOperation = (key: unknown): key is Operation =>
15
+ operations.some((operation) => operation === key)
16
+
17
+ /**
18
+ * Takes the operations out of an update's draft: `{ set }` becomes its
19
+ * list, an operation by `undefined` leaves its field as it is (D-84), and
20
+ * each other one comes back to be computed on the row.
21
+ */
22
+ export function listUpdates(
23
+ model: ModelInfo,
24
+ draft: Draft,
25
+ at: readonly (string | number)[] = [],
26
+ ): Map<string, ListUpdate> {
27
+ const lists = new Map<string, ListUpdate>()
28
+ for (const [name, value] of Object.entries(draft)) {
29
+ const field = model.fields.get(name)
30
+ // A field type's value is its own, as for numbers (D-132).
31
+ const plain = field?.kind === 'scalar' && field.list && !field.codec
32
+ if (!plain || !isObject(value)) continue
33
+ const keys = Object.keys(value)
34
+ const used = operations.filter((key) => value[key] !== undefined)
35
+ if (keys.length === 0 || used.length > 1 || !keys.every(isOperation)) {
36
+ const path = ['data', ...at, name].join('.')
37
+ throw new InvalidQuery(
38
+ path,
39
+ `${path} takes a list or one of ${operations.join(', ')}.`,
40
+ )
41
+ }
42
+ delete draft[name]
43
+ const [operation] = used
44
+ if (operation === undefined) continue
45
+ const given = value[operation]
46
+ const elements: readonly unknown[] = Array.isArray(given) ? given : [given]
47
+ const issue = issueOf(elements, field)
48
+ if (issue !== undefined) {
49
+ throw invalid([{ path: [...at, name], message: issue }])
50
+ }
51
+ if (operation === 'set') draft[name] = elements
52
+ else lists.set(name, { operation, elements })
53
+ }
54
+ return lists
55
+ }
56
+
57
+ /** A list update's result on `current`, the elements in their order. */
58
+ export function listed(
59
+ current: unknown,
60
+ { operation, elements }: ListUpdate,
61
+ ): unknown[] {
62
+ const from: readonly unknown[] = Array.isArray(current) ? current : []
63
+ if (operation === 'push') return [...from, ...elements]
64
+ if (operation === 'remove') {
65
+ return from.filter((item) => !elements.includes(item))
66
+ }
67
+ const added = elements.filter(
68
+ (item, index) => !from.includes(item) && elements.indexOf(item) === index,
69
+ )
70
+ return [...from, ...added]
71
+ }
package/src/live.ts ADDED
@@ -0,0 +1,199 @@
1
+ // What the realtime plugin asks the kernel (D-154): a live read's effective
2
+ // filter and order, planned once for its caller, and, on a stored row, that
3
+ // filter and the row's sort keys, tested as `memory()` reads.
4
+ import { accessFor, and } from './access.ts'
5
+ import type { Filter, Nested, Order, Read, Row, Schema } from './adapter.ts'
6
+ import { rootFind } from './engine.ts'
7
+ import { decoded, isRow } from './field-codec.ts'
8
+ import { Reader } from './memory-read.ts'
9
+ import { compareKeys, sortable } from './memory-values.ts'
10
+ import { isFilters } from './memory-conditions.ts'
11
+ import { plan, uniqueWhere } from './query-args.ts'
12
+ import { modelOf } from './query-where.ts'
13
+ import { isObject } from './query-values.ts'
14
+ import type { Caller } from './rules.ts'
15
+ import type { Running } from './running.ts'
16
+ import { current } from './running.ts'
17
+ import { QueryScope, planned } from './scope.ts'
18
+
19
+ /**
20
+ * The rows a live read follows, and their order, ending with `id`; `filter`
21
+ * is the read's own part of `where`, `rights` the part the caller's read
22
+ * rules and `beforeFind` add, and
23
+ * `include`, `count` and `fields` what its selection reads, as the adapter
24
+ * receives them.
25
+ */
26
+ export type LivePlan = Pick<Nested, 'include' | 'count' | 'fields'> & {
27
+ readonly where: Filter | undefined
28
+ readonly filter: Filter | undefined
29
+ readonly rights: Filter | undefined
30
+ readonly orderBy: readonly Order[]
31
+ }
32
+
33
+ function started(): Running {
34
+ const app = current()
35
+ if (app === undefined) throw new Error('No application is running.')
36
+ return app
37
+ }
38
+
39
+ const shapeKeys = ['select', 'include', 'omit']
40
+ const liveKeys = new Set(['where', 'orderBy', ...shapeKeys])
41
+ const rowKeys = new Set(shapeKeys)
42
+
43
+ /**
44
+ * `args` as `caller` reads `model`: its read rules and every `beforeFind`
45
+ * included. A live row's `where` names one row, as `findUnique`'s.
46
+ */
47
+ export async function livePlan(
48
+ model: string,
49
+ args: unknown,
50
+ caller: Caller,
51
+ row = false,
52
+ ): Promise<LivePlan> {
53
+ const app = started()
54
+ const { models } = app.resolved
55
+ const info = modelOf(models, model)
56
+ const access = accessFor(models, caller, app.logger)
57
+ const scope = new QueryScope(models, caller, access)
58
+ const { where: unique, ...shape } = isObject(args) ? args : {}
59
+ return app.work.run(async () =>
60
+ planned(scope, () => {
61
+ const { read } = row
62
+ ? plan(models, info, shape, '', 'many', rowKeys, scope)
63
+ : plan(models, info, args, '', 'many', liveKeys, scope)
64
+ const rights = scope.readable(model)
65
+ const where = row
66
+ ? uniqueWhere(models, info, unique, 'where', scope)
67
+ : read.where
68
+ const { include, count, fields } = read
69
+ return {
70
+ ...(include && { include }),
71
+ ...(count && { count }),
72
+ ...(fields && { fields }),
73
+ where: and(where, rights),
74
+ filter: where,
75
+ rights,
76
+ orderBy: read.orderBy ?? [{ field: 'id', direction: 'asc' }],
77
+ }
78
+ }),
79
+ )
80
+ }
81
+
82
+ /** The stored rows `read` finds, as Master, plugin fields undecoded. */
83
+ export async function storedRows(
84
+ model: string,
85
+ read: Nested,
86
+ ): Promise<readonly Row[]> {
87
+ const app = started()
88
+ return app.work.run(async () => app.adapter.find({ ...read, model }))
89
+ }
90
+
91
+ /** The running application's schema, its plugins' models included. */
92
+ export function liveSchema(): Schema {
93
+ return started().resolved.schema
94
+ }
95
+
96
+ /** Whether `filter` reads `model`'s row alone, so `matches` can test it. */
97
+ export function inMemory(model: string, filter: Filter | undefined): boolean {
98
+ const fields = modelOf(started().resolved.models, model).fields
99
+ return Object.entries(filter ?? {}).every(([key, value]) => {
100
+ if (value === undefined) return true
101
+ if (isFilters(value)) return value.every((part) => inMemory(model, part))
102
+ // A search ranks as each database does (D-148).
103
+ if (value.search !== undefined || value.removedBy !== undefined) {
104
+ return false
105
+ }
106
+ const field = fields.get(key)
107
+ return field === undefined || field.kind === 'scalar'
108
+ })
109
+ }
110
+
111
+ const readers = new WeakMap<Running, Reader>()
112
+
113
+ function readerOf(app: Running): Reader {
114
+ const known = readers.get(app)
115
+ if (known !== undefined) return known
116
+ const fields = new Map(
117
+ app.resolved.schema.models.map((model) => [
118
+ model.name,
119
+ new Map(model.fields.map((field) => [field.name, field])),
120
+ ]),
121
+ )
122
+ const reader = new Reader({ tables: new Map(), joins: new Map() }, fields)
123
+ readers.set(app, reader)
124
+ return reader
125
+ }
126
+
127
+ /** Whether the stored `row` of `model` passes `filter`, which `inMemory` takes. */
128
+ export function matches(
129
+ model: string,
130
+ row: Row,
131
+ filter: Filter | undefined,
132
+ ): boolean {
133
+ return readerOf(started()).matches(model, row, filter) === true
134
+ }
135
+
136
+ /** Whether rows alone answer `read`: one level, unpaged, read in memory. */
137
+ const servable = (read: Read): boolean =>
138
+ read.include === undefined &&
139
+ read.count === undefined &&
140
+ read.distinct === undefined &&
141
+ read.cursor === undefined &&
142
+ read.skip === undefined &&
143
+ read.take === undefined &&
144
+ (read.orderBy ?? []).every(
145
+ (order) => (order.through ?? order.count ?? order.relevance) === undefined,
146
+ ) &&
147
+ inMemory(read.model, read.where)
148
+
149
+ /**
150
+ * The stored `rows` that pass `read`, in its order; the find that asked for
151
+ * them keeps the fields its shape selects.
152
+ */
153
+ function served(read: Read, rows: Iterable<Row>): Row[] {
154
+ const { model, orderBy = [] } = read
155
+ const kept = [...rows].filter((row) => matches(model, row, read.where))
156
+ const keys = new Map(kept.map((row) => [row, sortKeys(model, row, orderBy)]))
157
+ const key = (row: Row): unknown[] => keys.get(row) ?? []
158
+ kept.sort((a, b) => compareKeys(key(a), key(b), orderBy))
159
+ return kept
160
+ }
161
+
162
+ /**
163
+ * `findMany(args)` on `model` as `caller`, its rows taken from the stored
164
+ * `rows` when they alone answer it, else from the database. `rows` holds
165
+ * every row its `where` finds.
166
+ */
167
+ export async function servedRows(
168
+ model: string,
169
+ args: unknown,
170
+ caller: Caller,
171
+ rows: ReadonlyMap<string, Row>,
172
+ ): Promise<readonly Row[]> {
173
+ const { models } = started().resolved
174
+ const found = await rootFind(
175
+ model,
176
+ args,
177
+ { as: caller },
178
+ async (store, read) =>
179
+ servable(read)
180
+ ? decoded(models, read, served(read, rows.values()))
181
+ : store.find(read),
182
+ )
183
+ return Array.isArray(found) ? found.filter(isRow) : []
184
+ }
185
+
186
+ /** The sort keys of the stored `row`, for an order on its own fields. */
187
+ export function sortKeys(
188
+ model: string,
189
+ row: Row,
190
+ orderBy: readonly Order[],
191
+ ): unknown[] {
192
+ const reader = readerOf(started())
193
+ return orderBy.map((order) => {
194
+ if (order.through ?? order.count ?? order.relevance) {
195
+ throw new Error(`The order by ${order.field} reads another row.`)
196
+ }
197
+ return sortable(row[order.field] ?? null, reader.field(model, order.field))
198
+ })
199
+ }